Commit ee5b6a42 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add options to check TLS signing hashes

parent 424baabd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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`
+3 −0
Original line number Diff line number Diff line
@@ -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);

+4 −0
Original line number Diff line number Diff line
@@ -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);
+26 −12
Original line number Diff line number Diff line
@@ -187,38 +187,50 @@ 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,
    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,
    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,
    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);
}

/*
 * This could be further simplified by constructing an expected
 * HANDSHAKE_RESULT, and implementing comparison methods for
@@ -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;
}
+35 −0
Original line number Diff line number Diff line
@@ -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. */
Loading