From 6c610fd305c965e7ab83d3ffc0ab0e94733f01e6 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 13 Nov 2009 04:58:38 +0000 Subject: Basic DH public and private key checks. --- src/key.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/src/key.c b/src/key.c index 95b0fb7..a47cc48 100644 --- a/src/key.c +++ b/src/key.c @@ -228,6 +228,59 @@ test_dsa_public(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) return CONTINUE; } +static int +test_dh_public (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_ATTRIBUTE attr; + CK_BYTE buffer[16384]; + int codes = 0; + CK_RV rv; + DH* dh; + + P11T_SECTION ("CKK_DH Public"); + + dh = DH_new (); + assert (dh); + + attr.type = CKA_PRIME; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_PRIME", rv, CKR_OK); + dh->p = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->p == NULL) + P11T_CHECK_FAIL_MSG ("CKA_PRIME", p11t_msg_openssl ()); + + attr.type = CKA_BASE; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_BASE", rv, CKR_OK); + dh->g = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->g == NULL) + P11T_CHECK_FAIL_MSG ("CKA_BASE", p11t_msg_openssl ()); + + attr.type = CKA_VALUE; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_VALUE", rv, CKR_OK); + dh->pub_key = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->pub_key == NULL) + P11T_CHECK_FAIL_MSG ("CKA_VALUE", p11t_msg_openssl()); + + if (!DH_check (dh, &codes)) + P11T_CHECK_FAIL_MSG ("Check DH Params", "OpenSSL couldn't check DH params"); + if (codes) + P11T_CHECK_FAIL_MSG ("Check DH Params", "Unsafe or unsuitable DH params"); + if (BN_cmp (dh->p, dh->pub_key) <= 0) + P11T_CHECK_FAIL_MSG ("CKA_VALUE", "Prime is bigger than public value"); + + DH_free (dh); + + return CONTINUE; +} + static int test_rsa_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) { @@ -418,6 +471,72 @@ test_dsa_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) return CONTINUE; } +static int +test_dh_private (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_ATTRIBUTE attr; + CK_BYTE buffer[16384]; + CK_ULONG bits; + int codes; + CK_RV rv; + DH* dh; + + P11T_SECTION ("CKK_DH Private"); + + dh = DH_new (); + assert (dh); + + attr.type = CKA_PRIME; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_PRIME", rv, CKR_OK); + dh->p = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->p == NULL) + P11T_CHECK_FAIL_MSG ("CKA_PRIME", p11t_msg_openssl ()); + + attr.type = CKA_BASE; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_BASE", rv, CKR_OK); + dh->g = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->g == NULL) + P11T_CHECK_FAIL_MSG ("CKA_BASE", p11t_msg_openssl ()); + + attr.type = CKA_VALUE; + attr.pValue = buffer; + attr.ulValueLen = sizeof (buffer); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + if (rv != CKR_ATTRIBUTE_SENSITIVE) { + P11T_CHECK_RV ("CKA_VALUE", rv, CKR_OK); + dh->priv_key = BN_bin2bn (attr.pValue, attr.ulValueLen, NULL); + if (dh->priv_key == NULL) + P11T_CHECK_FAIL_MSG ("CKA_VALUE", p11t_msg_openssl()); + if (BN_cmp (dh->p, dh->priv_key) <= 0) + P11T_CHECK_FAIL_MSG ("CKA_VALUE", "Prime is bigger than private value"); + + attr.type = CKA_VALUE_BITS; + attr.pValue = &bits; + attr.ulValueLen = sizeof (bits); + rv = (p11t_module_funcs->C_GetAttributeValue) (session, object, &attr, 1); + P11T_CHECK_RV ("CKA_VALUE_BITS", rv, CKR_OK); + if (bits != BN_num_bits (dh->priv_key)) + P11T_CHECK_FAIL_MSG ("CKA_VALUE_BITS", "Does not match number of significant bits in CKA_VALUE"); + + } + + if (!DH_check (dh, &codes)) + P11T_CHECK_FAIL_MSG ("Check DH Params", "OpenSSL couldn't check DH params"); + if (codes) + P11T_CHECK_FAIL_MSG ("Check DH Params", "Unsafe or unsuitable DH params"); + + DH_free (dh); + + return CONTINUE; +} + + static int test_rsa_public_create(CK_SESSION_HANDLE session, CK_BBOOL token, RSA *rsa, CK_OBJECT_HANDLE_PTR result) { @@ -692,6 +811,114 @@ test_dsa_private_create(CK_SESSION_HANDLE session, CK_BBOOL token, DSA *dsa, CK_ return CONTINUE; } +static int +test_dh_public_create(CK_SESSION_HANDLE session, CK_BBOOL token, DH *dh, CK_OBJECT_HANDLE_PTR result) +{ + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attrs[10]; + CK_KEY_TYPE key_type = CKK_DH; + CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY; + CK_RV rv; + + P11T_SECTION("C_CreateObject"); + + /* Fill in all the attributes */ + attrs[0].type = CKA_TOKEN; + attrs[0].pValue = &token; + attrs[0].ulValueLen = sizeof (token); + + attrs[1].type = CKA_CLASS; + attrs[1].ulValueLen = sizeof (klass); + attrs[1].pValue = &klass; + + attrs[2].type = CKA_LABEL; + attrs[2].pValue = "Test DH Public Key"; + attrs[2].ulValueLen = 19; + + attrs[3].type = CKA_KEY_TYPE; + attrs[3].pValue = &key_type; + attrs[3].ulValueLen = sizeof (key_type); + + attrs[4].type = CKA_PRIME; + attrs[4].ulValueLen = BN_num_bytes (dh->p); + attrs[4].pValue = alloca (attrs[4].ulValueLen); + BN_bn2bin (dh->p, (unsigned char*)attrs[4].pValue); + + attrs[5].type = CKA_BASE; + attrs[5].ulValueLen = BN_num_bytes (dh->g); + attrs[5].pValue = alloca (attrs[5].ulValueLen); + BN_bn2bin (dh->g, (unsigned char*)attrs[5].pValue); + + attrs[6].type = CKA_VALUE; + attrs[6].ulValueLen = BN_num_bytes (dh->pub_key); + attrs[6].pValue = alloca (attrs[6].ulValueLen); + BN_bn2bin (dh->pub_key, (unsigned char*)attrs[6].pValue); + + rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 7, &object); + if (rv == CKR_TEMPLATE_INCOMPLETE) + return CONTINUE; + P11T_CHECK_RV("DH Public Key", rv, CKR_OK); + + test_dh_public (session, object); + + *result = object; + return CONTINUE; +} + +static int +test_dh_private_create(CK_SESSION_HANDLE session, CK_BBOOL token, DH *dh, CK_OBJECT_HANDLE_PTR result) +{ + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attrs[10]; + CK_KEY_TYPE key_type = CKK_DH; + CK_OBJECT_CLASS klass = CKO_PRIVATE_KEY; + CK_RV rv; + + P11T_SECTION("C_CreateObject"); + + /* Fill in all the attributes */ + attrs[0].type = CKA_TOKEN; + attrs[0].pValue = &token; + attrs[0].ulValueLen = sizeof (token); + + attrs[1].type = CKA_CLASS; + attrs[1].ulValueLen = sizeof (klass); + attrs[1].pValue = &klass; + + attrs[2].type = CKA_LABEL; + attrs[2].pValue = "Test DH Private Key"; + attrs[2].ulValueLen = 20; + + attrs[3].type = CKA_KEY_TYPE; + attrs[3].pValue = &key_type; + attrs[3].ulValueLen = sizeof (key_type); + + attrs[4].type = CKA_PRIME; + attrs[4].ulValueLen = BN_num_bytes (dh->p); + attrs[4].pValue = alloca (attrs[4].ulValueLen); + BN_bn2bin (dh->p, (unsigned char*)attrs[4].pValue); + + attrs[5].type = CKA_BASE; + attrs[5].ulValueLen = BN_num_bytes (dh->g); + attrs[5].pValue = alloca (attrs[5].ulValueLen); + BN_bn2bin (dh->g, (unsigned char*)attrs[5].pValue); + + attrs[6].type = CKA_VALUE; + attrs[6].ulValueLen = BN_num_bytes (dh->priv_key); + attrs[6].pValue = alloca (attrs[6].ulValueLen); + BN_bn2bin (dh->priv_key, (unsigned char*)attrs[6].pValue); + + rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 7, &object); + if (rv == CKR_TEMPLATE_INCOMPLETE) + return CONTINUE; + P11T_CHECK_RV("DH Private Key", rv, CKR_OK); + + test_dh_private (session, object); + + *result = object; + return CONTINUE; +} + static int test_dsa_create(CK_SESSION_HANDLE session, CK_BBOOL token) { @@ -723,6 +950,39 @@ test_dsa_create(CK_SESSION_HANDLE session, CK_BBOOL token) return CONTINUE; } +static int +test_dh_create(CK_SESSION_HANDLE session, CK_BBOOL token) +{ + CK_OBJECT_HANDLE pub, prv; + CK_RV rv; + DH *dh; + int ret; + + dh = DH_generate_parameters (256, 2, NULL, NULL); + assert (dh); + ret = DH_generate_key (dh); + assert (ret == 1); + + pub = prv = 0; + test_dh_public_create (session, token, dh, &pub); + test_dh_private_create (session, token, dh, &prv); + +#if 0 + if (pub != 0) + p11t_dh_test_public_key (session, pub); + if (prv != 0) + p11t_dh_test_private_key (session, prv); +#endif + + P11T_SECTION("C_DestroyObject"); + + rv = (p11t_module_funcs->C_DestroyObject)(session, pub); + P11T_CHECK_RV("DH Public Key", rv, CKR_OK); + + DH_free (dh); + return CONTINUE; +} + static int test_create_unexpected(CK_SESSION_HANDLE session) { @@ -955,6 +1215,8 @@ p11t_key_tests(void) test_rsa_public(session, object); else if(key_type == CKK_DSA) test_dsa_public(session, object); + else if(key_type == CKK_DH) + test_dh_public(session, object); } } @@ -978,6 +1240,8 @@ p11t_key_tests(void) test_rsa_private(session, object); else if(key_type == CKK_DSA) test_dsa_private(session, object); + else if (key_type == CKK_DH) + test_dh_private (session, object); } } free(objects); @@ -985,6 +1249,7 @@ p11t_key_tests(void) if (p11t_test_write_session) { test_rsa_create (session, CK_FALSE); test_dsa_create (session, CK_FALSE); + test_dh_create (session, CK_FALSE); } } -- cgit v1.2.3