Add options to check TLS signing hashes
authorDr. Stephen Henson <steve@openssl.org>
Fri, 13 Jan 2017 15:20:42 +0000 (15:20 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 20 Jan 2017 01:16:31 +0000 (01:16 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2235)

test/README.ssltest.md
test/handshake_helper.c
test/handshake_helper.h
test/ssl_test.c
test/ssl_test_ctx.c
test/ssl_test_ctx.h

index 1c4c4820696f3eb10b288f484384cfcb71599acd..5e2b2d76fc1422554aa26b3a5c2fa9cb077f0789 100644 (file)
@@ -92,6 +92,9 @@ handshake.
 * ExpectedServerCertType, ExpectedClientCertType - the expected algorithm or
   curve of server or client certificate
 
+* ExpectedServerSignatureHash, ExpectedClientSignatureHash - the expected
+  signing hash used by server or client certificate
+
 ## Configuring the client and server
 
 The client and server configurations can be any valid `SSL_CTX`
index 01a30c850f4e16021f50e96308f3de491db7c80e..c8fd47430a1840e17c6abe26afd7f0a5494effa7 100644 (file)
@@ -1070,6 +1070,9 @@ static HANDSHAKE_RESULT *do_handshake_internal(
         EVP_PKEY_free(tmp_key);
     }
 
+    SSL_get_peer_signature_nid(client.ssl, &ret->server_sign_hash);
+    SSL_get_peer_signature_nid(server.ssl, &ret->client_sign_hash);
+
     ret->server_cert_type = peer_pkey_type(client.ssl);
     ret->client_cert_type = peer_pkey_type(server.ssl);
 
index 1cdd6fa055d690edfd0badd97f135f58d6dac602..604eed9bbac8f0ec24a326092f08bed1298e07c7 100644 (file)
@@ -47,8 +47,12 @@ typedef struct handshake_result {
     int tmp_key_type;
     /* server certificate key type */
     int server_cert_type;
+    /* server signing hash */
+    int server_sign_hash;
     /* client certificate key type */
     int client_cert_type;
+    /* client signing hash */
+    int client_sign_hash;
 } HANDSHAKE_RESULT;
 
 HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void);
index 0d0c35ecca19a11335f0e134dfb1b4746af710cd..58ddca4ec059bbf321bdbba2dcaacf9e26a88309 100644 (file)
@@ -187,36 +187,48 @@ static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
     return 1;
 }
 
-static int check_key_type(const char *name, int expected_key_type, int key_type)
+static int check_nid(const char *name, int expected_nid, int nid)
 {
-    if (expected_key_type == 0 || expected_key_type == key_type)
+    if (expected_nid == 0 || expected_nid == nid)
         return 1;
     fprintf(stderr, "%s type mismatch, %s vs %s\n",
-            name, OBJ_nid2ln(expected_key_type),
-            key_type == NID_undef ? "absent" : OBJ_nid2ln(key_type));
+            name, OBJ_nid2ln(expected_nid),
+            nid == NID_undef ? "absent" : OBJ_nid2ln(nid));
     return 0;
 }
 
 static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
 {
-    return check_key_type("Tmp key", test_ctx->expected_tmp_key_type,
-                          result->tmp_key_type);
+    return check_nid("Tmp key", test_ctx->expected_tmp_key_type,
+                     result->tmp_key_type);
 }
 
 static int check_server_cert_type(HANDSHAKE_RESULT *result,
                                   SSL_TEST_CTX *test_ctx)
 {
-    return check_key_type("Server certificate",
-                          test_ctx->expected_server_cert_type,
-                          result->server_cert_type);
+    return check_nid("Server certificate", test_ctx->expected_server_cert_type,
+                     result->server_cert_type);
+}
+
+static int check_server_sign_hash(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Server signing hash", test_ctx->expected_server_sign_hash,
+                     result->server_sign_hash);
 }
 
 static int check_client_cert_type(HANDSHAKE_RESULT *result,
                                   SSL_TEST_CTX *test_ctx)
 {
-    return check_key_type("Client certificate",
-                          test_ctx->expected_client_cert_type,
-                          result->client_cert_type);
+    return check_nid("Client certificate", test_ctx->expected_client_cert_type,
+                     result->client_cert_type);
+}
+
+static int check_client_sign_hash(HANDSHAKE_RESULT *result,
+                                  SSL_TEST_CTX *test_ctx)
+{
+    return check_nid("Client signing hash", test_ctx->expected_client_sign_hash,
+                     result->client_sign_hash);
 }
 
 /*
@@ -241,7 +253,9 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
         ret &= check_resumption(result, test_ctx);
         ret &= check_tmp_key(result, test_ctx);
         ret &= check_server_cert_type(result, test_ctx);
+        ret &= check_server_sign_hash(result, test_ctx);
         ret &= check_client_cert_type(result, test_ctx);
+        ret &= check_client_sign_hash(result, test_ctx);
     }
     return ret;
 }
index f8d5ecda14260ce05caa1cd024146a78cb0b2a58..242602d88ed8f47c2572ead5495e363058ddfa22 100644 (file)
@@ -480,6 +480,39 @@ __owur static int parse_expected_client_cert_type(SSL_TEST_CTX *test_ctx,
                                    value);
 }
 
+/*************************/
+/* Expected signing hash */
+/*************************/
+
+__owur static int parse_expected_sign_hash(int *ptype, const char *value)
+{
+    int nid;
+
+    if (value == NULL)
+        return 0;
+    nid = OBJ_sn2nid(value);
+    if (nid == NID_undef)
+        nid = OBJ_ln2nid(value);
+    if (nid == NID_undef)
+        return 0;
+    *ptype = nid;
+    return 1;
+}
+
+__owur static int parse_expected_server_sign_hash(SSL_TEST_CTX *test_ctx,
+                                                  const char *value)
+{
+    return parse_expected_sign_hash(&test_ctx->expected_server_sign_hash,
+                                    value);
+}
+
+__owur static int parse_expected_client_sign_hash(SSL_TEST_CTX *test_ctx,
+                                                  const char *value)
+{
+    return parse_expected_sign_hash(&test_ctx->expected_server_sign_hash,
+                                    value);
+}
+
 /*************************************************************/
 /* Known test options and their corresponding parse methods. */
 /*************************************************************/
@@ -506,7 +539,9 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
     { "MaxFragmentSize", &parse_test_max_fragment_size },
     { "ExpectedTmpKeyType", &parse_expected_tmp_key_type },
     { "ExpectedServerCertType", &parse_expected_server_cert_type },
+    { "ExpectedServerSignHash", &parse_expected_server_sign_hash },
     { "ExpectedClientCertType", &parse_expected_client_cert_type },
+    { "ExpectedClientSignHash", &parse_expected_client_sign_hash },
 };
 
 /* Nested client options. */
index f67f01ad877e201e9b2f80196b51ea8ebfe726f5..b34efe327cfe94cd4b76c83aa58a6dd99300dc3e 100644 (file)
@@ -163,8 +163,12 @@ typedef struct {
     int expected_tmp_key_type;
     /* Expected server certificate key type */
     int expected_server_cert_type;
+    /* Expected server signing hash */
+    int expected_server_sign_hash;
     /* Expected client certificate key type */
     int expected_client_cert_type;
+    /* Expected client signing hash */
+    int expected_client_sign_hash;
 } SSL_TEST_CTX;
 
 const char *ssl_test_result_name(ssl_test_result_t result);