summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2017-01-08 19:30:41 +0000
committerDr. Stephen Henson <steve@openssl.org>2017-01-15 00:23:33 +0000
commit7f5f35af223f9c1d641f46446f6bbf9d1493a9e6 (patch)
treead1997b23e2dcb3df7b67358b2d378e271663316
parent5071824321e1bbe20b859c1a3609ea5ab09fb3f2 (diff)
Add options to check certificate types.
Reviewed-by: Emilia Käsper <emilia@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2224)
-rw-r--r--test/README.ssltest.md3
-rw-r--r--test/handshake_helper.c39
-rw-r--r--test/handshake_helper.h4
-rw-r--r--test/ssl_test.c35
-rw-r--r--test/ssl_test_ctx.c36
-rw-r--r--test/ssl_test_ctx.h4
6 files changed, 101 insertions, 20 deletions
diff --git a/test/README.ssltest.md b/test/README.ssltest.md
index c1edda5aed..48d5474a08 100644
--- a/test/README.ssltest.md
+++ b/test/README.ssltest.md
@@ -89,6 +89,9 @@ handshake.
* ExpectedTmpKeyType - the expected algorithm or curve of server temp key
+* ExpectedServerKeyType, ExpectedClientKeyType - the expected algorithm or
+ curve of server or client certificate
+
## Configuring the client and server
The client and server configurations can be any valid `SSL_CTX`
diff --git a/test/handshake_helper.c b/test/handshake_helper.c
index 9ffd0bf427..01a30c850f 100644
--- a/test/handshake_helper.c
+++ b/test/handshake_helper.c
@@ -847,6 +847,32 @@ static char *dup_str(const unsigned char *in, size_t len)
return ret;
}
+static int pkey_type(EVP_PKEY *pkey)
+{
+ int nid = EVP_PKEY_id(pkey);
+
+#ifndef OPENSSL_NO_EC
+ if (nid == EVP_PKEY_EC) {
+ const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
+ return EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+ }
+#endif
+ return nid;
+}
+
+static int peer_pkey_type(SSL *s)
+{
+ X509 *x = SSL_get_peer_certificate(s);
+
+ if (x != NULL) {
+ int nid = pkey_type(X509_get0_pubkey(x));
+
+ X509_free(x);
+ return nid;
+ }
+ return NID_undef;
+}
+
/*
* Note that |extra| points to the correct client/server configuration
* within |test_ctx|. When configuring the handshake, general mode settings
@@ -1040,18 +1066,13 @@ static HANDSHAKE_RESULT *do_handshake_internal(
*session_out = SSL_get1_session(client.ssl);
if (SSL_get_server_tmp_key(client.ssl, &tmp_key)) {
- int nid = EVP_PKEY_id(tmp_key);
-
-#ifndef OPENSSL_NO_EC
- if (nid == EVP_PKEY_EC) {
- EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmp_key);
- nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
- }
-#endif
+ ret->tmp_key_type = pkey_type(tmp_key);
EVP_PKEY_free(tmp_key);
- ret->tmp_key_type = nid;
}
+ ret->server_cert_type = peer_pkey_type(client.ssl);
+ ret->client_cert_type = peer_pkey_type(server.ssl);
+
ctx_data_free_data(&server_ctx_data);
ctx_data_free_data(&server2_ctx_data);
ctx_data_free_data(&client_ctx_data);
diff --git a/test/handshake_helper.h b/test/handshake_helper.h
index 4f70592a18..1cdd6fa055 100644
--- a/test/handshake_helper.h
+++ b/test/handshake_helper.h
@@ -45,6 +45,10 @@ typedef struct handshake_result {
int server_resumed;
/* Temporary key type */
int tmp_key_type;
+ /* server certificate key type */
+ int server_cert_type;
+ /* client certificate key type */
+ int client_cert_type;
} HANDSHAKE_RESULT;
HANDSHAKE_RESULT *HANDSHAKE_RESULT_new(void);
diff --git a/test/ssl_test.c b/test/ssl_test.c
index 61850eb9f6..af92aa13cf 100644
--- a/test/ssl_test.c
+++ b/test/ssl_test.c
@@ -187,17 +187,38 @@ static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
return 1;
}
-static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
+static int check_key_type(const char *name,int expected_key_type, int key_type)
{
- if (test_ctx->expected_tmp_key_type == 0
- || test_ctx->expected_tmp_key_type == result->tmp_key_type)
+ if (expected_key_type == 0 || expected_key_type == key_type)
return 1;
- fprintf(stderr, "Tmp key type mismatch, %s vs %s\n",
- OBJ_nid2ln(test_ctx->expected_tmp_key_type),
- OBJ_nid2ln(result->tmp_key_type));
+ fprintf(stderr, "%s type mismatch, %s vs %s\n",
+ name, OBJ_nid2ln(expected_key_type),
+ key_type == NID_undef ? "absent" : OBJ_nid2ln(key_type));
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);
+}
+
+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);
+}
+
+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);
+}
+
/*
* This could be further simplified by constructing an expected
* HANDSHAKE_RESULT, and implementing comparison methods for
@@ -219,6 +240,8 @@ static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
ret &= check_alpn(result, 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_client_cert_type(result, test_ctx);
}
return ret;
}
diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c
index 2c5ba1e5bb..f8d5ecda14 100644
--- a/test/ssl_test_ctx.c
+++ b/test/ssl_test_ctx.c
@@ -433,17 +433,21 @@ IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, app_data_size)
IMPLEMENT_SSL_TEST_INT_OPTION(SSL_TEST_CTX, test, max_fragment_size)
/***********************/
-/* ExpectedTmpKeyType */
+/* Expected key types */
/***********************/
-__owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx,
- const char *value)
+__owur static int parse_expected_key_type(int *ptype, const char *value)
{
int nid;
+ const EVP_PKEY_ASN1_METHOD *ameth;
if (value == NULL)
return 0;
- nid = OBJ_sn2nid(value);
+ ameth = EVP_PKEY_asn1_find_str(NULL, value, -1);
+ if (ameth != NULL)
+ EVP_PKEY_asn1_get0_info(&nid, NULL, NULL, NULL, NULL, ameth);
+ else
+ nid = OBJ_sn2nid(value);
if (nid == NID_undef)
nid = OBJ_ln2nid(value);
#ifndef OPENSSL_NO_EC
@@ -452,10 +456,30 @@ __owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx,
#endif
if (nid == NID_undef)
return 0;
- test_ctx->expected_tmp_key_type = nid;
+ *ptype = nid;
return 1;
}
+__owur static int parse_expected_tmp_key_type(SSL_TEST_CTX *test_ctx,
+ const char *value)
+{
+ return parse_expected_key_type(&test_ctx->expected_tmp_key_type, value);
+}
+
+__owur static int parse_expected_server_cert_type(SSL_TEST_CTX *test_ctx,
+ const char *value)
+{
+ return parse_expected_key_type(&test_ctx->expected_server_cert_type,
+ value);
+}
+
+__owur static int parse_expected_client_cert_type(SSL_TEST_CTX *test_ctx,
+ const char *value)
+{
+ return parse_expected_key_type(&test_ctx->expected_client_cert_type,
+ value);
+}
+
/*************************************************************/
/* Known test options and their corresponding parse methods. */
/*************************************************************/
@@ -481,6 +505,8 @@ static const ssl_test_ctx_option ssl_test_ctx_options[] = {
{ "ApplicationData", &parse_test_app_data_size },
{ "MaxFragmentSize", &parse_test_max_fragment_size },
{ "ExpectedTmpKeyType", &parse_expected_tmp_key_type },
+ { "ExpectedServerCertType", &parse_expected_server_cert_type },
+ { "ExpectedClientCertType", &parse_expected_client_cert_type },
};
/* Nested client options. */
diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h
index 995d518ed3..f67f01ad87 100644
--- a/test/ssl_test_ctx.h
+++ b/test/ssl_test_ctx.h
@@ -161,6 +161,10 @@ typedef struct {
int resumption_expected;
/* Expected temporary key type */
int expected_tmp_key_type;
+ /* Expected server certificate key type */
+ int expected_server_cert_type;
+ /* Expected client certificate key type */
+ int expected_client_cert_type;
} SSL_TEST_CTX;
const char *ssl_test_result_name(ssl_test_result_t result);