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:
parent
8a55ce4954
commit
f1050fd79a
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
})
|
})
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user