Preserve the peer signature algorithm across resumes.

So we can report it cleanly out of DevTools, it should behave like
SSL_get_curve_id and be reported on resumption too.

BUG=chromium:658905

Change-Id: I0402e540a1e722e09eaebadf7fb4785d8880c389
Reviewed-on: https://boringssl-review.googlesource.com/12694
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2016-12-13 20:05:36 -05:00 committed by CQ bot account: commit-bot@chromium.org
parent 8a55ce4954
commit f1050fd79a
9 changed files with 49 additions and 9 deletions

View File

@ -3669,6 +3669,10 @@ struct ssl_session_st {
* if not applicable or unknown. */ * if not applicable or unknown. */
uint16_t group_id; uint16_t group_id;
/* peer_signature_algorithm is the signature algorithm used to authenticate
* the peer, or zero if not applicable or unknown. */
uint16_t peer_signature_algorithm;
/* master_key, in TLS 1.2 and below, is the master secret associated with the /* master_key, in TLS 1.2 and below, is the master secret associated with the
* session. In TLS 1.3 and up, it is the resumption secret. */ * session. In TLS 1.3 and up, it is the resumption secret. */
int master_key_length; int master_key_length;

View File

@ -1287,7 +1287,7 @@ static int ssl3_get_server_key_exchange(SSL_HANDSHAKE *hs) {
if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) { if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) {
goto f_err; goto f_err;
} }
ssl->s3->tmp.peer_signature_algorithm = signature_algorithm; ssl->s3->new_session->peer_signature_algorithm = signature_algorithm;
} else if (hs->peer_pubkey->type == EVP_PKEY_RSA) { } else if (hs->peer_pubkey->type == EVP_PKEY_RSA) {
signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1; signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
} else if (hs->peer_pubkey->type == EVP_PKEY_EC) { } else if (hs->peer_pubkey->type == EVP_PKEY_EC) {

View File

@ -1826,7 +1826,7 @@ static int ssl3_get_cert_verify(SSL_HANDSHAKE *hs) {
if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) { if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) {
goto f_err; goto f_err;
} }
ssl->s3->tmp.peer_signature_algorithm = signature_algorithm; ssl->s3->new_session->peer_signature_algorithm = signature_algorithm;
} else if (hs->peer_pubkey->type == EVP_PKEY_RSA) { } else if (hs->peer_pubkey->type == EVP_PKEY_RSA) {
signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1; signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
} else if (hs->peer_pubkey->type == EVP_PKEY_EC) { } else if (hs->peer_pubkey->type == EVP_PKEY_EC) {

View File

@ -1531,10 +1531,6 @@ typedef struct ssl3_state_st {
* messages, but it doesn't matter if the session that's being resumed * messages, but it doesn't matter if the session that's being resumed
* didn't use it to create the master secret initially. */ * didn't use it to create the master secret initially. */
char extended_master_secret; char extended_master_secret;
/* peer_signature_algorithm is the signature algorithm used to authenticate
* the peer, or zero if not applicable. */
uint16_t peer_signature_algorithm;
} tmp; } tmp;
/* new_session is the new mutable session being established by the current /* new_session is the new mutable session being established by the current

View File

@ -126,6 +126,7 @@
* certChain [19] SEQUENCE OF Certificate OPTIONAL, * certChain [19] SEQUENCE OF Certificate OPTIONAL,
* ticketAgeAdd [21] OCTET STRING OPTIONAL, * ticketAgeAdd [21] OCTET STRING OPTIONAL,
* isServer [22] BOOLEAN DEFAULT TRUE, * isServer [22] BOOLEAN DEFAULT TRUE,
* peerSignatureAlgorithm [23] INTEGER OPTIONAL,
* } * }
* *
* Note: historically this serialization has included other optional * Note: historically this serialization has included other optional
@ -176,6 +177,8 @@ static const int kTicketAgeAddTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21;
static const int kIsServerTag = static const int kIsServerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22;
static const int kPeerSignatureAlgorithmTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23;
static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data, static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len, int for_ticket) { size_t *out_len, int for_ticket) {
@ -381,6 +384,13 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
} }
} }
if (in->peer_signature_algorithm != 0 &&
(!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) ||
!CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CBB_finish(&cbb, out_data, out_len)) { if (!CBB_finish(&cbb, out_data, out_len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err; goto err;
@ -531,6 +541,19 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
return 1; return 1;
} }
static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag,
uint16_t default_value) {
uint64_t value;
if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
(uint64_t)default_value) ||
value > 0xffff) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
*out = (uint16_t)value;
return 1;
}
static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) { static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
SSL_SESSION *ret = SSL_SESSION_new(); SSL_SESSION *ret = SSL_SESSION_new();
if (ret == NULL) { if (ret == NULL) {
@ -748,7 +771,9 @@ static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
ret->is_server = is_server; ret->is_server = is_server;
if (CBS_len(&session) != 0) { if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm,
kPeerSignatureAlgorithmTag, 0) ||
CBS_len(&session) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err; goto err;
} }

View File

@ -2843,7 +2843,14 @@ uint64_t SSL_get_write_sequence(const SSL *ssl) {
} }
uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) {
return ssl->s3->tmp.peer_signature_algorithm; /* TODO(davidben): This checks the wrong session if there is a renegotiation
* in progress. */
SSL_SESSION *session = SSL_get_session(ssl);
if (session == NULL) {
return 0;
}
return session->peer_signature_algorithm;
} }
size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) { size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) {

View File

@ -255,6 +255,8 @@ SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) {
} }
} }
new_session->peer_signature_algorithm = session->peer_signature_algorithm;
new_session->timeout = session->timeout; new_session->timeout = session->timeout;
new_session->time = session->time; new_session->time = session->time;

View File

@ -6546,6 +6546,9 @@ func addSignatureAlgorithmTests() {
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)), "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
"-enable-all-curves", "-enable-all-curves",
}, },
// Resume the session to assert the peer signature
// algorithm is reported on both handshakes.
resumeSession: !shouldVerifyFail,
shouldFail: shouldVerifyFail, shouldFail: shouldVerifyFail,
expectedError: verifyError, expectedError: verifyError,
}) })
@ -6592,6 +6595,9 @@ func addSignatureAlgorithmTests() {
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)), "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
"-enable-all-curves", "-enable-all-curves",
}, },
// Resume the session to assert the peer signature
// algorithm is reported on both handshakes.
resumeSession: !shouldVerifyFail,
shouldFail: shouldVerifyFail, shouldFail: shouldVerifyFail,
expectedError: verifyError, expectedError: verifyError,
}) })

View File

@ -358,7 +358,7 @@ int tls13_process_certificate_verify(SSL *ssl) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, al); ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
goto err; goto err;
} }
ssl->s3->tmp.peer_signature_algorithm = signature_algorithm; ssl->s3->new_session->peer_signature_algorithm = signature_algorithm;
if (!tls13_get_cert_verify_signature_input( if (!tls13_get_cert_verify_signature_input(
ssl, &msg, &msg_len, ssl, &msg, &msg_len,