Make it possible to tell what curve was used on the server. We don't actually have an API to let you know if the value is legal to interpret as a curve ID. (This was kind of a poor API. Oh well.) Also add tests for key_exchange_info. I've intentionally left server-side plain RSA missing for now because the SSL_PRIVATE_KEY_METHOD abstraction only gives you bytes and it's probably better to tweak this API instead. (key_exchange_info also wasn't populated on the server, though due to a rebasing error, that fix ended up in the parent CL. Oh well.) Change-Id: I74a322c8ad03f25b02059da7568c9e1a78419069 Reviewed-on: https://boringssl-review.googlesource.com/6783 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 589f4c4..681066c 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -1061,6 +1061,9 @@ /* SSL_CIPHER_is_ECDSA returns one if |cipher| uses ECDSA. */ OPENSSL_EXPORT int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher); +/* SSL_CIPHER_is_ECDHE returns one if |cipher| uses ECDHE. */ +OPENSSL_EXPORT int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher); + /* SSL_CIPHER_get_min_version returns the minimum protocol version required * for |cipher|. */ OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher);
diff --git a/ssl/ssl_cipher.c b/ssl/ssl_cipher.c index 6d8237d..77fa8fa 100644 --- a/ssl/ssl_cipher.c +++ b/ssl/ssl_cipher.c
@@ -1616,6 +1616,10 @@ return (cipher->algorithm_auth & SSL_aECDSA) != 0; } +int SSL_CIPHER_is_ECDHE(const SSL_CIPHER *cipher) { + return (cipher->algorithm_mkey & SSL_kECDHE) != 0; +} + uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) { /* Cipher suites before TLS 1.2 use the default PRF, while all those added
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index 562e6c5..74674a4 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -12,6 +12,10 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + #include <openssl/base.h> #if !defined(OPENSSL_WINDOWS) @@ -32,6 +36,7 @@ #pragma comment(lib, "Ws2_32.lib") #endif +#include <inttypes.h> #include <string.h> #include <openssl/bio.h> @@ -1087,6 +1092,15 @@ return false; } + if (config->expect_key_exchange_info != 0) { + uint32_t info = SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl)); + if (static_cast<uint32_t>(config->expect_key_exchange_info) != info) { + fprintf(stderr, "key_exchange_info was %" PRIu32 ", wanted %" PRIu32 "\n", + info, static_cast<uint32_t>(config->expect_key_exchange_info)); + 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 5600ec6..45bb0b7 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -4670,6 +4670,61 @@ } } +func addKeyExchangeInfoTests() { + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-RSA-Client", + config: Config{ + CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, + }, + // key.pem is a 1024-bit RSA key. + flags: []string{"-expect-key-exchange-info", "1024"}, + }) + // TODO(davidben): key_exchange_info doesn't work for plain RSA on the + // server. Either fix this or change the API as it's not very useful in + // this case. + + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-DHE-Client", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + Bugs: ProtocolBugs{ + // This is a 1234-bit prime number, generated + // with: + // openssl gendh 1234 | openssl asn1parse -i + DHGroupPrime: bigFromHex("0215C589A86BE450D1255A86D7A08877A70E124C11F0C75E476BA6A2186B1C830D4A132555973F2D5881D5F737BB800B7F417C01EC5960AEBF79478F8E0BBB6A021269BD10590C64C57F50AD8169D5488B56EE38DC5E02DA1A16ED3B5F41FEB2AD184B78A31F3A5B2BEC8441928343DA35DE3D4F89F0D4CEDE0034045084A0D1E6182E5EF7FCA325DD33CE81BE7FA87D43613E8FA7A1457099AB53"), + }, + }, + flags: []string{"-expect-key-exchange-info", "1234"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "KeyExchangeInfo-DHE-Server", + config: Config{ + CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, + }, + // bssl_shim as a server configures a 2048-bit DHE group. + flags: []string{"-expect-key-exchange-info", "2048"}, + }) + + testCases = append(testCases, testCase{ + name: "KeyExchangeInfo-ECDHE-Client", + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveX25519}, + }, + flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, + }) + testCases = append(testCases, testCase{ + testType: serverTest, + name: "KeyExchangeInfo-ECDHE-Server", + config: Config{ + CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + CurvePreferences: []CurveID{CurveX25519}, + }, + flags: []string{"-expect-key-exchange-info", "29", "-enable-all-curves"}, + }) +} + func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { defer wg.Done() @@ -4768,6 +4823,7 @@ addCustomExtensionTests() addRSAClientKeyExchangeTests() addCurveTests() + addKeyExchangeInfoTests() for _, async := range []bool{false, true} { for _, splitHandshake := range []bool{false, true} { for _, protocol := range []protocol{tls, dtls} {
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 46991fa..1cf316d 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc
@@ -143,6 +143,8 @@ { "-expect-total-renegotiations", &TestConfig::expect_total_renegotiations }, { "-expect-server-key-exchange-hash", &TestConfig::expect_server_key_exchange_hash }, + { "-expect-key-exchange-info", + &TestConfig::expect_key_exchange_info }, }; } // namespace
diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index 685f92d..4e0a46a 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h
@@ -101,6 +101,7 @@ bool p384_only = false; bool enable_all_curves = false; bool use_sparse_dh_prime = false; + int expect_key_exchange_info = 0; }; bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/tool/transport_common.cc b/tool/transport_common.cc index cfda6c3..2c15c00 100644 --- a/tool/transport_common.cc +++ b/tool/transport_common.cc
@@ -172,6 +172,11 @@ fprintf(stderr, " Resumed session: %s\n", SSL_session_reused(ssl) ? "yes" : "no"); fprintf(stderr, " Cipher: %s\n", SSL_CIPHER_get_name(cipher)); + if (SSL_CIPHER_is_ECDHE(cipher)) { + fprintf(stderr, " ECDHE curve: %s\n", + SSL_get_curve_name( + SSL_SESSION_get_key_exchange_info(SSL_get_session(ssl)))); + } fprintf(stderr, " Secure renegotiation: %s\n", SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no");