Add peer CRT digest to session tickets
This commit changes the format of session tickets to include
the digest of the peer's CRT if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
is disabled.
This commit does not yet remove the peer CRT itself.
diff --git a/library/ssl_ticket.c b/library/ssl_ticket.c
index 2ad5436..ef9f7e1 100644
--- a/library/ssl_ticket.c
+++ b/library/ssl_ticket.c
@@ -187,9 +187,11 @@
/*
* Serialize a session in the following format:
- * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
- * n . n+2 peer_cert length = m (0 if no certificate)
- * n+3 . n+2+m peer cert ASN.1
+ * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
+ * n . n+2 peer_cert length = m (0 if no certificate)
+ * n+3 . n+2+m peer cert ASN.1
+ * n+3+m . n+3+m length of peer certificate digest = k (0 if n digest)
+ * n+4+m . n+4+k peer certificate digest (digest type encoded in session)
*/
static int ssl_save_session( const mbedtls_ssl_session *session,
unsigned char *buf, size_t buf_len,
@@ -199,6 +201,9 @@
size_t left = buf_len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
size_t cert_len;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_digest_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( left < sizeof( mbedtls_ssl_session ) )
@@ -223,11 +228,32 @@
*p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len ) & 0xFF );
+ left -= 3;
if( session->peer_cert != NULL )
memcpy( p, session->peer_cert->raw.p, cert_len );
p += cert_len;
+ left -= cert_len;
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( session->peer_cert_digest != NULL )
+ cert_digest_len = 0;
+ else
+ cert_digest_len = session->peer_cert_digest_len;
+
+ if( left < 1 + cert_digest_len )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ *p++ = (unsigned char) cert_digest_len;
+ left--;
+
+ if( session->peer_cert_digest != NULL )
+ memcpy( p, session->peer_cert_digest, cert_digest_len );
+
+ p += cert_digest_len;
+ left -= cert_digest_len;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
*olen = p - buf;
@@ -245,6 +271,9 @@
const unsigned char * const end = buf + len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
size_t cert_len;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_digest_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
@@ -257,6 +286,9 @@
* and potentially harmful. Zeroize them for safety. */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
session->peer_cert = NULL;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
session->ticket = NULL;
@@ -295,6 +327,30 @@
p += cert_len;
}
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* Deserialize CRT digest from the end of the ticket. */
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ cert_digest_len = (size_t) p[0];
+ p++;
+
+ if( cert_digest_len != 0 )
+ {
+ if( cert_digest_len > (size_t)( end - p ) ||
+ cert_digest_len != session->peer_cert_digest_len )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ session->peer_cert_digest = mbedtls_calloc( 1, cert_digest_len );
+ if( session->peer_cert_digest == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( session->peer_cert_digest, p, cert_digest_len );
+ p += cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( p != end )