Push the difference in chain semantics to the edge. OpenSSL includes a leaf certificate in a certificate chain when it's a client, but doesn't when it's a server. This is also reflected in the serialisation of sessions. This change makes the internal semantics consistent: the leaf is always included in the chain in memory, and never duplicated when serialised. To maintain the same API, SSL_get_peer_cert_chain will construct a copy of the chain without the leaf if needed. Since the serialised format of a client session has changed, an |is_server| boolean is added to the ASN.1 that defaults to true. Thus any old client sessions will be parsed as server sessions and (silently) discarded by a client. Change-Id: Ibcf72bc8a130cedb423bc0fd3417868e0af3ca3e Reviewed-on: https://boringssl-review.googlesource.com/12704 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: Adam Langley <agl@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index d4b17c9..041895c 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -3698,6 +3698,13 @@ * |peer|, but when a server it does not. */ STACK_OF(X509) *x509_chain; + /* x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that + * omits the leaf certificate. This exists because OpenSSL, historically, + * didn't include the leaf certificate in the chain for a server, but did for + * a client. The |x509_chain| always includes it and, if an API call requires + * a chain without, it is stored here. */ + STACK_OF(X509) *x509_chain_without_leaf; + /* verify_result is the result of certificate verification in the case of * non-fatal certificate errors. */ long verify_result; @@ -3756,6 +3763,9 @@ /* ticket_age_add_valid is non-zero if |ticket_age_add| is valid. */ unsigned ticket_age_add_valid:1; + + /* is_server is true if this session was created by a server. */ + unsigned is_server:1; }; /* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with