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. */
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
* session. In TLS 1.3 and up, it is the resumption secret. */
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)) {
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) {
signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
} 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)) {
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) {
signature_algorithm = SSL_SIGN_RSA_PKCS1_MD5_SHA1;
} 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
* didn't use it to create the master secret initially. */
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;
/* new_session is the new mutable session being established by the current

View File

@ -126,6 +126,7 @@
* certChain [19] SEQUENCE OF Certificate OPTIONAL,
* ticketAgeAdd [21] OCTET STRING OPTIONAL,
* isServer [22] BOOLEAN DEFAULT TRUE,
* peerSignatureAlgorithm [23] INTEGER 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;
static const int kIsServerTag =
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,
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)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@ -531,6 +541,19 @@ static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
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) {
SSL_SESSION *ret = SSL_SESSION_new();
if (ret == NULL) {
@ -748,7 +771,9 @@ static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
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);
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) {
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) {

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->time = session->time;

View File

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

View File

@ -358,7 +358,7 @@ int tls13_process_certificate_verify(SSL *ssl) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
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(
ssl, &msg, &msg_len,