mirror of
https://github.com/openssl/openssl.git
synced 2025-01-12 13:36:28 +08:00
Add options to check certificate types.
Reviewed-by: Emilia Käsper <emilia@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2224)
This commit is contained in:
parent
5071824321
commit
7f5f35af22
@ -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`
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -187,15 +187,36 @@ 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)
|
||||
{
|
||||
if (expected_key_type == 0 || expected_key_type == key_type)
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
|
||||
{
|
||||
if (test_ctx->expected_tmp_key_type == 0
|
||||
|| test_ctx->expected_tmp_key_type == result->tmp_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));
|
||||
return 0;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user