Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2015-11-02 20:02:20 +0300
committerAdam Langley <agl@google.com>2015-11-07 01:35:28 +0300
commit6e8076577486a5d3d67682dbc4acae932daa6731 (patch)
treefbdbe9de19eb380892e6e6a559945333f41ccc9f
parent788be4a3f47cea5fcb86abf59321c729057830ed (diff)
Add SSL_get_server_key_exchange_hash.
This exposes the ServerKeyExchange signature hash type used in the most recent handshake, for histogramming on the client. BUG=549662 Change-Id: I8a4e00ac735b1ecd2c2df824112c3a0bc62332a7 Reviewed-on: https://boringssl-review.googlesource.com/6413 Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r--include/openssl/ssl.h10
-rw-r--r--ssl/internal.h9
-rw-r--r--ssl/s3_clnt.c10
-rw-r--r--ssl/s3_srvr.c14
-rw-r--r--ssl/ssl_lib.c3
-rw-r--r--ssl/t1_lib.c22
-rw-r--r--ssl/test/bssl_shim.cc9
-rw-r--r--ssl/test/runner/runner.go13
-rw-r--r--ssl/test/test_config.cc2
-rw-r--r--ssl/test/test_config.h1
10 files changed, 70 insertions, 23 deletions
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index bf53d5e4..38d838d3 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2911,6 +2911,11 @@ OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
* respectively. */
OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
+/* SSL_get_server_key_exchange_hash, on a client, returns the hash the server
+ * used to sign the ServerKeyExchange in TLS 1.2. If not applicable, it returns
+ * |TLSEXT_hash_none|. */
+OPENSSL_EXPORT uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl);
+
/* Deprecated functions. */
@@ -4157,6 +4162,11 @@ typedef struct ssl3_state_st {
* False Start. The client may write data at this point. */
char in_false_start;
+ /* server_key_exchange_hash, on a client, is the hash the server used to
+ * sign the ServerKeyExchange in TLS 1.2. If not applicable, it is
+ * |TLSEXT_hash_none|. */
+ uint8_t server_key_exchange_hash;
+
/* peer_dh_tmp, on a client, is the server's DHE public key. */
DH *peer_dh_tmp;
diff --git a/ssl/internal.h b/ssl/internal.h
index aa8c4ef6..520131e6 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -1294,8 +1294,13 @@ int tls1_parse_peer_sigalgs(SSL *s, const CBS *sigalgs);
const EVP_MD *tls1_choose_signing_digest(SSL *ssl);
size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs);
-int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
- CBS *cbs, EVP_PKEY *pkey);
+
+/* tls12_check_peer_sigalg checks that |hash| and |signature| are consistent
+ * with |pkey| and |ssl|'s sent, supported signature algorithms and, if so,
+ * writes the relevant digest into |*out_md| and returns 1. Otherwise it
+ * returns 0 and writes an alert into |*out_alert|. */
+int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
+ uint8_t hash, uint8_t signature, EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
#endif /* OPENSSL_HEADER_SSL_INTERNAL_H */
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 04c06ddb..843403b3 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1244,9 +1244,17 @@ int ssl3_get_server_key_exchange(SSL *s) {
}
if (SSL_USE_SIGALGS(s)) {
- if (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey)) {
+ uint8_t hash, signature;
+ if (!CBS_get_u8(&server_key_exchange, &hash) ||
+ !CBS_get_u8(&server_key_exchange, &signature)) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
+ if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature, pkey)) {
+ goto f_err;
+ }
+ s->s3->tmp.server_key_exchange_hash = hash;
} else if (pkey->type == EVP_PKEY_RSA) {
md = EVP_md5_sha1();
} else {
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index fad2d0a9..8cfa0e6c 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2056,9 +2056,17 @@ int ssl3_get_cert_verify(SSL *s) {
CBS_init(&certificate_verify, s->init_msg, n);
/* Determine the digest type if needbe. */
- if (SSL_USE_SIGALGS(s) &&
- !tls12_check_peer_sigalg(&md, &al, s, &certificate_verify, pkey)) {
- goto f_err;
+ if (SSL_USE_SIGALGS(s)) {
+ uint8_t hash, signature_type;
+ if (!CBS_get_u8(&certificate_verify, &hash) ||
+ !CBS_get_u8(&certificate_verify, &signature_type)) {
+ al = SSL_AD_DECODE_ERROR;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ goto f_err;
+ }
+ if (!tls12_check_peer_sigalg(s, &md, &al, hash, signature_type, pkey)) {
+ goto f_err;
+ }
}
/* Compute the digest. */
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 68eb4ac0..16c24dfa 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2651,6 +2651,9 @@ int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv,
}
return 1;
+
+uint8_t SSL_get_server_key_exchange_hash(const SSL *ssl) {
+ return ssl->s3->tmp.server_key_exchange_hash;
}
int SSL_clear(SSL *ssl) {
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 301d49a1..9a290283 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -640,16 +640,11 @@ size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) {
return sizeof(tls12_sigalgs);
}
-/* tls12_check_peer_sigalg parses a SignatureAndHashAlgorithm out of |cbs|. It
- * checks it is consistent with |s|'s sent supported signature algorithms and,
- * if so, writes the relevant digest into |*out_md| and returns 1. Otherwise it
- * returns 0 and writes an alert into |*out_alert|. */
-int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
- CBS *cbs, EVP_PKEY *pkey) {
+int tls12_check_peer_sigalg(SSL *ssl, const EVP_MD **out_md, int *out_alert,
+ uint8_t hash, uint8_t signature, EVP_PKEY *pkey) {
const uint8_t *sent_sigs;
size_t sent_sigslen, i;
int sigalg = tls12_get_sigid(pkey->type);
- uint8_t hash, signature;
/* Should never happen */
if (sigalg == -1) {
@@ -658,13 +653,6 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
return 0;
}
- if (!CBS_get_u8(cbs, &hash) ||
- !CBS_get_u8(cbs, &signature)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
/* Check key type is consistent with signature */
if (sigalg != signature) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
@@ -681,8 +669,8 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
return 0;
}
- if (s->server && (!tls1_check_curve_id(s, curve_id) ||
- comp_id != TLSEXT_ECPOINTFORMAT_uncompressed)) {
+ if (ssl->server && (!tls1_check_curve_id(ssl, curve_id) ||
+ comp_id != TLSEXT_ECPOINTFORMAT_uncompressed)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
@@ -690,7 +678,7 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
}
/* Check signature matches a type we sent */
- sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
+ sent_sigslen = tls12_get_psigalgs(ssl, &sent_sigs);
for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
if (hash == sent_sigs[0] && signature == sent_sigs[1]) {
break;
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc
index fe3dd6f3..07ba9f59 100644
--- a/ssl/test/bssl_shim.cc
+++ b/ssl/test/bssl_shim.cc
@@ -1061,6 +1061,15 @@ static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
}
}
+ if (config->expect_server_key_exchange_hash != 0 &&
+ config->expect_server_key_exchange_hash !=
+ SSL_get_server_key_exchange_hash(ssl)) {
+ fprintf(stderr, "ServerKeyExchange hash was %d, wanted %d.\n",
+ SSL_get_server_key_exchange_hash(ssl),
+ config->expect_server_key_exchange_hash);
+ return false;
+ }
+
if (!config->is_server) {
/* Clients should expect a peer certificate chain iff this was not a PSK
* cipher suite. */
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 158f0823..6ab71cf2 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -4026,6 +4026,19 @@ func addSigningHashTests() {
},
},
})
+
+ testCases = append(testCases, testCase{
+ name: "SigningHash-ServerKeyExchange-Verify-" + hash.name,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, 42},
+ {signatureRSA, hash.id},
+ {signatureRSA, 255},
+ },
+ },
+ flags: []string{"-expect-server-key-exchange-hash", strconv.Itoa(int(hash.id))},
+ })
}
// Test that hash resolution takes the signature type into account.
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 8b540c3a..50e6b234 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -141,6 +141,8 @@ const Flag<int> kIntFlags[] = {
{ "-mtu", &TestConfig::mtu },
{ "-export-keying-material", &TestConfig::export_keying_material },
{ "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations },
+ { "-expect-server-key-exchange-hash",
+ &TestConfig::expect_server_key_exchange_hash },
};
} // namespace
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h
index a72d66b7..9f295aeb 100644
--- a/ssl/test/test_config.h
+++ b/ssl/test/test_config.h
@@ -100,6 +100,7 @@ struct TestConfig {
bool renegotiate_freely = false;
bool renegotiate_ignore = false;
bool disable_npn = false;
+ int expect_server_key_exchange_hash = 0;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);