(self, hostkey: bytes, hostkey_type: str, ptr: int)
| 151 | return hostkey |
| 152 | |
| 153 | def __parse_ca_key(self, hostkey: bytes, hostkey_type: str, ptr: int) -> Tuple[str, int]: |
| 154 | ca_key_type = '' |
| 155 | ca_key_n_len = 0 |
| 156 | |
| 157 | # If this is a certificate, continue parsing to extract the CA type and key length. Even though a hostkey type might be 'ssh-ed25519-cert-v01@openssh.com', its CA may still be RSA. |
| 158 | # if hostkey_type.startswith('ssh-rsa-cert-v0') or hostkey_type.startswith('ssh-ed25519-cert-v0'): |
| 159 | self.out.d("Parsing CA for hostkey type [%s]..." % hostkey_type) |
| 160 | |
| 161 | # Skip over the serial number. |
| 162 | ptr += 8 |
| 163 | |
| 164 | # Get the certificate type. |
| 165 | cert_type = int(binascii.hexlify(hostkey[ptr:ptr + 4]), 16) |
| 166 | ptr += 4 |
| 167 | |
| 168 | # Only SSH2_CERT_TYPE_HOST (2) makes sense in this context. |
| 169 | if cert_type == 2: |
| 170 | |
| 171 | # Skip the key ID (this is the serial number of the |
| 172 | # certificate). |
| 173 | key_id, key_id_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 174 | |
| 175 | # The principles, which are... I don't know what. |
| 176 | principles, principles_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 177 | |
| 178 | # Skip over the timestamp that this certificate is valid after. |
| 179 | ptr += 8 |
| 180 | |
| 181 | # Skip over the timestamp that this certificate is valid before. |
| 182 | ptr += 8 |
| 183 | |
| 184 | # TODO: validate the principles, and time range. |
| 185 | |
| 186 | # The critical options. |
| 187 | critical_options, critical_options_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 188 | |
| 189 | # Certificate extensions. |
| 190 | extensions, extensions_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 191 | |
| 192 | # Another nonce. |
| 193 | nonce, nonce_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 194 | |
| 195 | # Finally, we get to the CA key. |
| 196 | ca_key, ca_key_len, ptr = KexDH.__get_bytes(hostkey, ptr) # pylint: disable=unused-variable |
| 197 | |
| 198 | # Last in the host key blob is the CA signature. It isn't |
| 199 | # interesting to us, so we won't bother parsing any further. |
| 200 | # The CA key has the modulus, however... |
| 201 | ptr = 0 |
| 202 | |
| 203 | # 'ssh-rsa', 'rsa-sha2-256', etc. |
| 204 | ca_key_type_bytes, ca_key_type_len, ptr = KexDH.__get_bytes(ca_key, ptr) # pylint: disable=unused-variable |
| 205 | ca_key_type = ca_key_type_bytes.decode('ascii') |
| 206 | self.out.d("Found CA type: [%s]" % ca_key_type) |
| 207 | |
| 208 | # ED25519 CA's don't explicitly include the modulus size in the public key, since its fixed at 32 in all cases. |
| 209 | if ca_key_type == 'ssh-ed25519': |
| 210 | ca_key_n_len = 32 |
no test coverage detected