Make a copy of peer's raw public key after verifying its CRT chain

This commit modifies `mbedtls_ssl_parse_certificate()` to store a
copy of the peer's public key after parsing and verifying the peer's
CRT chain.

So far, this leads to heavy memory duplication: We have the CRT chain
in the I/O buffer, then parse (and, thereby, copy) it to a
`mbedtls_x509_crt` structure, and then make another copy of the
peer's public key, plus the overhead from the MPI and ECP structures.

This inefficiency will soon go away to a significant extend, because:
- Another PR adds functionality to parse CRTs without taking
  ownership of the input buffers. Applying this here will allow
  parsing and verifying the peer's chain without making an additional
  raw copy. The overhead reduces to the size of `mbedtls_x509_crt`,
  the public key, and the DN structures referenced in the CRT.
- Once copyless parsing is in place and the removal of the peer CRT
  is fully implemented, we can extract the public key bounds from
  the parsed certificate and then free the entire chain before
  parsing the public key again. This means that we never store
  the parsed public key twice at the same time.
This commit is contained in:
Hanno Becker 2019-02-06 16:19:04 +00:00
parent 3bf8cdf2f8
commit cf291d63dd

View File

@ -6698,6 +6698,24 @@ crt_verify:
MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* Make a copy of the peer's raw public key. */
mbedtls_pk_init( &ssl->handshake->peer_pubkey );
{
unsigned char *p, *end;
p = chain->pk_raw.p;
end = p + chain->pk_raw.len;
ret = mbedtls_pk_parse_subpubkey( &p, end,
&ssl->handshake->peer_pubkey );
if( ret != 0 )
{
/* We should have parsed the public key before. */
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto exit;
}
}
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ssl->session_negotiate->peer_cert = chain;
chain = NULL;