Fix a number of sigalg scope issues.
peer_sigalgs should live on SSL_HANDSHAKE. This both releases a little bit of memory after the handshake is over and also avoids the bug where the sigalgs get dropped if SSL_set_SSL_CTX is called at a bad time. See also upstream's 14e14bf6964965d02ce89805d9de867f000095aa. This only affects consumers using the old SNI callback and not select_certificate_cb. Add a test that the SNI callback works as expected. In doing so, add an SSL_CTX version of the signing preferences API. This is a property of the cert/key pair (really just the key) and should be tied to that. This makes it a bit easier to have the regression test work with TLS 1.2 too. I thought we'd fixed this already, but apparently not... :-/ BUG=95 Change-Id: I75b02fad4059e6aa46c3b05183a07d72880711b3 Reviewed-on: https://boringssl-review.googlesource.com/10445 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
7bee853d18
commit
0fc37ef082
@ -921,13 +921,21 @@ OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx,
|
||||
* before TLS 1.2. */
|
||||
#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01
|
||||
|
||||
/* SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the
|
||||
* preference list when signing with |ctx|'s private key. It returns one on
|
||||
* success and zero on error. |prefs| should not include the internal-only value
|
||||
* |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. */
|
||||
OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx,
|
||||
const uint16_t *prefs,
|
||||
size_t num_prefs);
|
||||
|
||||
/* SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the
|
||||
* preference list when signing with |ssl|'s private key. It returns one on
|
||||
* success and zero on error. |prefs| should not include the internal-only value
|
||||
* |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. */
|
||||
OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl,
|
||||
const uint16_t *prefs,
|
||||
size_t prefs_len);
|
||||
size_t num_prefs);
|
||||
|
||||
|
||||
/* Certificate and private key convenience functions. */
|
||||
|
@ -1194,13 +1194,12 @@ static int ssl3_send_certificate_request(SSL *ssl) {
|
||||
|
||||
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
|
||||
const uint16_t *sigalgs;
|
||||
size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < sigalgs_len; i++) {
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
|
||||
goto err;
|
||||
}
|
||||
|
@ -907,6 +907,13 @@ struct ssl_handshake_st {
|
||||
uint8_t *public_key;
|
||||
size_t public_key_len;
|
||||
|
||||
/* peer_sigalgs are the signature algorithms that the peer supports. These are
|
||||
* taken from the contents of the signature algorithms extension for a server
|
||||
* or from the CertificateRequest for a client. */
|
||||
uint16_t *peer_sigalgs;
|
||||
/* num_peer_sigalgs is the number of entries in |peer_sigalgs|. */
|
||||
size_t num_peer_sigalgs;
|
||||
|
||||
uint8_t session_tickets_sent;
|
||||
} /* SSL_HANDSHAKE */;
|
||||
|
||||
@ -1030,17 +1037,10 @@ typedef struct cert_st {
|
||||
DH *dh_tmp;
|
||||
DH *(*dh_tmp_cb)(SSL *ssl, int is_export, int keysize);
|
||||
|
||||
/* peer_sigalgs are the algorithm/hash pairs that the peer supports. These
|
||||
* are taken from the contents of signature algorithms extension for a server
|
||||
* or from the CertificateRequest for a client. */
|
||||
uint16_t *peer_sigalgs;
|
||||
/* peer_sigalgslen is the number of entries in |peer_sigalgs|. */
|
||||
size_t peer_sigalgslen;
|
||||
|
||||
/* sigalgs, if non-NULL, is the set of digests supported by |privatekey| in
|
||||
* decreasing order of preference. */
|
||||
/* sigalgs, if non-NULL, is the set of signature algorithms supported by
|
||||
* |privatekey| in decreasing order of preference. */
|
||||
uint16_t *sigalgs;
|
||||
size_t sigalgs_len;
|
||||
size_t num_sigalgs;
|
||||
|
||||
/* Certificate setup callback: if set is called whenever a
|
||||
* certificate may be required (client or server). the callback
|
||||
|
@ -165,6 +165,7 @@ void ssl_handshake_free(SSL_HANDSHAKE *hs) {
|
||||
ssl_handshake_clear_groups(hs);
|
||||
OPENSSL_free(hs->key_share_bytes);
|
||||
OPENSSL_free(hs->public_key);
|
||||
OPENSSL_free(hs->peer_sigalgs);
|
||||
OPENSSL_free(hs);
|
||||
}
|
||||
|
||||
|
@ -158,18 +158,6 @@ CERT *ssl_cert_dup(CERT *cert) {
|
||||
}
|
||||
memset(ret, 0, sizeof(CERT));
|
||||
|
||||
ret->mask_k = cert->mask_k;
|
||||
ret->mask_a = cert->mask_a;
|
||||
|
||||
if (cert->dh_tmp != NULL) {
|
||||
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
|
||||
if (ret->dh_tmp == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ret->dh_tmp_cb = cert->dh_tmp_cb;
|
||||
|
||||
if (cert->x509 != NULL) {
|
||||
X509_up_ref(cert->x509);
|
||||
ret->x509 = cert->x509;
|
||||
@ -190,6 +178,27 @@ CERT *ssl_cert_dup(CERT *cert) {
|
||||
|
||||
ret->key_method = cert->key_method;
|
||||
|
||||
ret->mask_k = cert->mask_k;
|
||||
ret->mask_a = cert->mask_a;
|
||||
|
||||
if (cert->dh_tmp != NULL) {
|
||||
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
|
||||
if (ret->dh_tmp == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ret->dh_tmp_cb = cert->dh_tmp_cb;
|
||||
|
||||
if (cert->sigalgs != NULL) {
|
||||
ret->sigalgs =
|
||||
BUF_memdup(cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0]));
|
||||
if (ret->sigalgs == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ret->num_sigalgs = cert->num_sigalgs;
|
||||
|
||||
ret->cert_cb = cert->cert_cb;
|
||||
ret->cert_cb_arg = cert->cert_cb_arg;
|
||||
|
||||
@ -228,7 +237,6 @@ void ssl_cert_free(CERT *c) {
|
||||
DH_free(c->dh_tmp);
|
||||
|
||||
ssl_cert_clear_certs(c);
|
||||
OPENSSL_free(c->peer_sigalgs);
|
||||
OPENSSL_free(c->sigalgs);
|
||||
X509_STORE_free(c->verify_store);
|
||||
|
||||
|
@ -336,19 +336,30 @@ void SSL_CTX_set_private_key_method(SSL_CTX *ctx,
|
||||
ctx->cert->key_method = key_method;
|
||||
}
|
||||
|
||||
int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
|
||||
size_t prefs_len) {
|
||||
ssl->cert->sigalgs_len = 0;
|
||||
ssl->cert->sigalgs = BUF_memdup(prefs, prefs_len * sizeof(prefs[0]));
|
||||
if (ssl->cert->sigalgs == NULL) {
|
||||
static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
|
||||
size_t num_prefs) {
|
||||
cert->num_sigalgs = 0;
|
||||
cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
|
||||
if (cert->sigalgs == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
ssl->cert->sigalgs_len = prefs_len;
|
||||
cert->num_sigalgs = num_prefs;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs,
|
||||
size_t num_prefs) {
|
||||
return set_signing_algorithm_prefs(ctx->cert, prefs, num_prefs);
|
||||
}
|
||||
|
||||
|
||||
int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs,
|
||||
size_t num_prefs) {
|
||||
return set_signing_algorithm_prefs(ssl->cert, prefs, num_prefs);
|
||||
}
|
||||
|
||||
OPENSSL_COMPILE_ASSERT(sizeof(int) >= 2 * sizeof(uint16_t),
|
||||
digest_list_conversion_cannot_overflow);
|
||||
|
||||
@ -356,7 +367,7 @@ int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
|
||||
size_t num_digests) {
|
||||
OPENSSL_free(ssl->cert->sigalgs);
|
||||
|
||||
ssl->cert->sigalgs_len = 0;
|
||||
ssl->cert->num_sigalgs = 0;
|
||||
ssl->cert->sigalgs = OPENSSL_malloc(sizeof(uint16_t) * 2 * num_digests);
|
||||
if (ssl->cert->sigalgs == NULL) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
|
||||
@ -369,27 +380,27 @@ int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
|
||||
for (size_t i = 0; i < num_digests; i++) {
|
||||
switch (digest_nids[i]) {
|
||||
case NID_sha1:
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA1;
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] = SSL_SIGN_ECDSA_SHA1;
|
||||
ssl->cert->sigalgs_len += 2;
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA1;
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] = SSL_SIGN_ECDSA_SHA1;
|
||||
ssl->cert->num_sigalgs += 2;
|
||||
break;
|
||||
case NID_sha256:
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA256;
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA256;
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
|
||||
SSL_SIGN_ECDSA_SECP256R1_SHA256;
|
||||
ssl->cert->sigalgs_len += 2;
|
||||
ssl->cert->num_sigalgs += 2;
|
||||
break;
|
||||
case NID_sha384:
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA384;
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA384;
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
|
||||
SSL_SIGN_ECDSA_SECP384R1_SHA384;
|
||||
ssl->cert->sigalgs_len += 2;
|
||||
ssl->cert->num_sigalgs += 2;
|
||||
break;
|
||||
case NID_sha512:
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len] = SSL_SIGN_RSA_PKCS1_SHA512;
|
||||
ssl->cert->sigalgs[ssl->cert->sigalgs_len + 1] =
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs] = SSL_SIGN_RSA_PKCS1_SHA512;
|
||||
ssl->cert->sigalgs[ssl->cert->num_sigalgs + 1] =
|
||||
SSL_SIGN_ECDSA_SECP521R1_SHA512;
|
||||
ssl->cert->sigalgs_len += 2;
|
||||
ssl->cert->num_sigalgs += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
104
ssl/ssl_test.cc
104
ssl/ssl_test.cc
@ -1106,6 +1106,36 @@ static ScopedEVP_PKEY GetTestKey() {
|
||||
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
static ScopedX509 GetECDSATestCertificate() {
|
||||
static const char kCertPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
|
||||
"QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
|
||||
"dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
|
||||
"BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
|
||||
"dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
|
||||
"v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
|
||||
"HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
|
||||
"HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
|
||||
"BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
|
||||
"BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
|
||||
return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
static ScopedEVP_PKEY GetECDSATestKey() {
|
||||
static const char kKeyPEM[] =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
|
||||
"TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
|
||||
"Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
|
||||
"-----END PRIVATE KEY-----\n";
|
||||
ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
|
||||
return ScopedEVP_PKEY(
|
||||
PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
|
||||
}
|
||||
|
||||
static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
|
||||
SSL_CTX *client_ctx, SSL_CTX *server_ctx,
|
||||
SSL_SESSION *session) {
|
||||
@ -1906,6 +1936,77 @@ static bool TestSessionTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
|
||||
SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
|
||||
SSL_set_SSL_CTX(ssl, ctx);
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
static bool TestSNICallback() {
|
||||
ScopedX509 cert = GetTestCertificate();
|
||||
ScopedEVP_PKEY key = GetTestKey();
|
||||
ScopedX509 cert2 = GetECDSATestCertificate();
|
||||
ScopedEVP_PKEY key2 = GetECDSATestKey();
|
||||
if (!cert || !key || !cert2 || !key2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// At each version, test that switching the |SSL_CTX| at the SNI callback
|
||||
// behaves correctly.
|
||||
for (uint16_t version : kVersions) {
|
||||
if (version == SSL3_VERSION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
|
||||
|
||||
ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
|
||||
ScopedSSL_CTX server_ctx2(SSL_CTX_new(TLS_method()));
|
||||
ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
|
||||
if (!server_ctx || !server_ctx2 || !client_ctx ||
|
||||
!SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
|
||||
!SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
|
||||
!SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
|
||||
!SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
|
||||
// Historically signing preferences would be lost in some cases with the
|
||||
// SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
|
||||
// this doesn't happen when |version| is TLS 1.2, configure the private
|
||||
// key to only sign SHA-256.
|
||||
!SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
|
||||
&kECDSAWithSHA256, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL_CTX_set_min_version(client_ctx.get(), version);
|
||||
SSL_CTX_set_max_version(client_ctx.get(), version);
|
||||
SSL_CTX_set_min_version(server_ctx.get(), version);
|
||||
SSL_CTX_set_max_version(server_ctx.get(), version);
|
||||
SSL_CTX_set_min_version(server_ctx2.get(), version);
|
||||
SSL_CTX_set_max_version(server_ctx2.get(), version);
|
||||
|
||||
SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
|
||||
SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
|
||||
|
||||
ScopedSSL client, server;
|
||||
if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
|
||||
server_ctx.get(), nullptr)) {
|
||||
fprintf(stderr, "Handshake failed at version %04x.\n", version);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The client should have received |cert2|.
|
||||
ScopedX509 peer(SSL_get_peer_certificate(client.get()));
|
||||
if (!peer ||
|
||||
X509_cmp(peer.get(), cert2.get()) != 0) {
|
||||
fprintf(stderr, "Incorrect certificate received at version %04x.\n",
|
||||
version);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
CRYPTO_library_init();
|
||||
|
||||
@ -1939,7 +2040,8 @@ int main() {
|
||||
!TestRetainOnlySHA256OfCerts() ||
|
||||
!TestClientHello() ||
|
||||
!TestSessionIDContext() ||
|
||||
!TestSessionTimeout()) {
|
||||
!TestSessionTimeout() ||
|
||||
!TestSNICallback()) {
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
65
ssl/t1_lib.c
65
ssl/t1_lib.c
@ -594,16 +594,15 @@ int tls12_check_peer_sigalg(SSL *ssl, int *out_alert, uint16_t sigalg) {
|
||||
* settings. */
|
||||
void ssl_set_client_disabled(SSL *ssl) {
|
||||
CERT *c = ssl->cert;
|
||||
const uint16_t *sigalgs;
|
||||
size_t i, sigalgslen;
|
||||
int have_rsa = 0, have_ecdsa = 0;
|
||||
c->mask_a = 0;
|
||||
c->mask_k = 0;
|
||||
|
||||
/* Now go through all signature algorithms seeing if we support any for RSA,
|
||||
* DSA, ECDSA. Do this for all versions not just TLS 1.2. */
|
||||
sigalgslen = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
for (i = 0; i < sigalgslen; i++) {
|
||||
const uint16_t *sigalgs;
|
||||
size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
switch (sigalgs[i]) {
|
||||
case SSL_SIGN_RSA_PSS_SHA512:
|
||||
case SSL_SIGN_RSA_PSS_SHA384:
|
||||
@ -1130,19 +1129,18 @@ static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const uint16_t *sigalgs_data;
|
||||
const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);
|
||||
const uint16_t *sigalgs;
|
||||
const size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
|
||||
CBB contents, sigalgs;
|
||||
CBB contents, sigalgs_cbb;
|
||||
if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
|
||||
!CBB_add_u16_length_prefixed(out, &contents) ||
|
||||
!CBB_add_u16_length_prefixed(&contents, &sigalgs)) {
|
||||
!CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < sigalgs_len; i++) {
|
||||
if (!CBB_add_u16(&sigalgs, sigalgs_data[i])) {
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1156,9 +1154,9 @@ static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
|
||||
|
||||
static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
|
||||
CBS *contents) {
|
||||
OPENSSL_free(ssl->cert->peer_sigalgs);
|
||||
ssl->cert->peer_sigalgs = NULL;
|
||||
ssl->cert->peer_sigalgslen = 0;
|
||||
OPENSSL_free(ssl->s3->hs->peer_sigalgs);
|
||||
ssl->s3->hs->peer_sigalgs = NULL;
|
||||
ssl->s3->hs->num_peer_sigalgs = 0;
|
||||
|
||||
if (contents == NULL) {
|
||||
return 1;
|
||||
@ -3025,13 +3023,12 @@ int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
CERT *const cert = ssl->cert;
|
||||
OPENSSL_free(cert->peer_sigalgs);
|
||||
cert->peer_sigalgs = NULL;
|
||||
cert->peer_sigalgslen = 0;
|
||||
SSL_HANDSHAKE *hs = ssl->s3->hs;
|
||||
OPENSSL_free(hs->peer_sigalgs);
|
||||
hs->peer_sigalgs = NULL;
|
||||
hs->num_peer_sigalgs = 0;
|
||||
|
||||
size_t num_sigalgs = CBS_len(in_sigalgs);
|
||||
|
||||
if (num_sigalgs % 2 != 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -3045,18 +3042,16 @@ int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
|
||||
|
||||
/* This multiplication doesn't overflow because sizeof(uint16_t) is two
|
||||
* and we just divided |num_sigalgs| by two. */
|
||||
cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
|
||||
if (cert->peer_sigalgs == NULL) {
|
||||
hs->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(uint16_t));
|
||||
if (hs->peer_sigalgs == NULL) {
|
||||
return 0;
|
||||
}
|
||||
cert->peer_sigalgslen = num_sigalgs;
|
||||
hs->num_peer_sigalgs = num_sigalgs;
|
||||
|
||||
CBS sigalgs;
|
||||
CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < num_sigalgs; i++) {
|
||||
if (!CBS_get_u16(&sigalgs, &cert->peer_sigalgs[i])) {
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
if (!CBS_get_u16(&sigalgs, &hs->peer_sigalgs[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -3066,7 +3061,7 @@ int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
|
||||
|
||||
int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out) {
|
||||
CERT *cert = ssl->cert;
|
||||
size_t i, j;
|
||||
SSL_HANDSHAKE *hs = ssl->s3->hs;
|
||||
|
||||
/* Before TLS 1.2, the signature algorithm isn't negotiated as part of the
|
||||
* handshake. It is fixed at MD5-SHA1 for RSA and SHA1 for ECDSA. */
|
||||
@ -3085,25 +3080,25 @@ int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out) {
|
||||
}
|
||||
|
||||
const uint16_t *sigalgs;
|
||||
size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
if (cert->sigalgs != NULL) {
|
||||
sigalgs = cert->sigalgs;
|
||||
sigalgs_len = cert->sigalgs_len;
|
||||
num_sigalgs = cert->num_sigalgs;
|
||||
}
|
||||
|
||||
const uint16_t *peer_sigalgs = cert->peer_sigalgs;
|
||||
size_t peer_sigalgs_len = cert->peer_sigalgslen;
|
||||
if (peer_sigalgs_len == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
|
||||
const uint16_t *peer_sigalgs = hs->peer_sigalgs;
|
||||
size_t num_peer_sigalgs = hs->num_peer_sigalgs;
|
||||
if (num_peer_sigalgs == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
|
||||
/* If the client didn't specify any signature_algorithms extension then
|
||||
* we can assume that it supports SHA1. See
|
||||
* http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
|
||||
static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1,
|
||||
SSL_SIGN_ECDSA_SHA1};
|
||||
peer_sigalgs = kDefaultPeerAlgorithms;
|
||||
peer_sigalgs_len = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
|
||||
num_peer_sigalgs = OPENSSL_ARRAY_SIZE(kDefaultPeerAlgorithms);
|
||||
}
|
||||
|
||||
for (i = 0; i < sigalgs_len; i++) {
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
uint16_t sigalg = sigalgs[i];
|
||||
/* SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be
|
||||
* negotiated. */
|
||||
@ -3112,7 +3107,7 @@ int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < peer_sigalgs_len; j++) {
|
||||
for (size_t j = 0; j < num_peer_sigalgs; j++) {
|
||||
if (sigalg == peer_sigalgs[j]) {
|
||||
*out = sigalg;
|
||||
return 1;
|
||||
|
@ -399,12 +399,12 @@ static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
|
||||
}
|
||||
|
||||
const uint16_t *sigalgs;
|
||||
size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
|
||||
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sigalgs_len; i++) {
|
||||
for (size_t i = 0; i < num_sigalgs; i++) {
|
||||
if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) {
|
||||
goto err;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user