--- eid-mw-4.4.11/tests/unit/sign.c 2018-10-31 11:30:22.000000000 +0100 +++ eid-mw-4.4.11/tests/unit/sign.c 2019-08-04 17:40:08.683942928 +0200 @@ -19,10 +19,13 @@ **************************************************************************** */ #ifdef WIN32 #include +#pragma pack(push, cryptoki, 1) +#include "pkcs11.h" +#pragma pack(pop, cryptoki) #else #include -#endif #include +#endif #include #include #include @@ -33,66 +36,88 @@ #include #endif +#include + #if HAVE_OPENSSL -#include +#include +#include #include -#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) -static int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { - if(!r || !n || !e) { - return 0; - } - r->n = n; - r->e = e; - r->d = d; - return 1; -} -#endif - -CK_BYTE digest_sha256[] = { - 0x2c, 0x26, 0xb4, 0x6b, - 0x68, 0xff, 0xc6, 0x8f, - 0xf9, 0x9b, 0x45, 0x3c, - 0x1d, 0x30, 0x41, 0x34, - 0x13, 0x42, 0x2d, 0x70, - 0x64, 0x83, 0xbf, 0xa0, - 0xf9, 0x8a, 0x5e, 0x88, - 0x62, 0x66, 0xe7, 0xae -}; - -int verify_sig(unsigned char* sig, CK_ULONG siglen, CK_BYTE_PTR modulus, CK_ULONG modlen, CK_BYTE_PTR exponent, CK_ULONG explen) { - RSA* rsa = RSA_new(); - unsigned char* s = malloc(siglen); - int ret; - - RSA_set0_key(rsa, BN_bin2bn(modulus, (int) modlen, NULL), BN_bin2bn(exponent, (int) explen, NULL), NULL); - - int v = RSA_verify(NID_sha256, digest_sha256, sizeof(digest_sha256), sig, siglen, rsa); - - printf("Signature verification returned: %d\n", v); - if(!v) { - unsigned long e = ERR_get_error(); - printf("error %ld: %s\n", e, ERR_error_string(e, NULL)); - ret = TEST_RV_FAIL; - } else { - ret = TEST_RV_OK; +// These were copied from eid-test-ca:derencode.c +int verify_sig(const unsigned char *sig_in, CK_ULONG siglen, const unsigned char *certificate, size_t certlen, bool is_rsa) { +#if OPENSSL_VERSION_NUMBER > 0x10100000L + X509 *cert = NULL; + EVP_PKEY *pkey = NULL; + EVP_MD_CTX *mdctx; + EVP_PKEY_CTX *pctx; + const EVP_MD *md = EVP_get_digestbyname("sha256"); + unsigned char *sig = (unsigned char*)sig_in; + + if(d2i_X509(&cert, &certificate, certlen) == NULL) { + fprintf(stderr, "E: could not parse X509 certificate\n"); + return TEST_RV_FAIL; + } + pkey = X509_get0_pubkey(cert); + if(pkey == NULL) { + fprintf(stderr, "E: could not find public key in certificate\n"); + return TEST_RV_FAIL; + } + mdctx = EVP_MD_CTX_new(); + if(EVP_DigestVerifyInit(mdctx, &pctx, md, NULL, pkey) != 1) { + fprintf(stderr, "E: initialization for signature validation failed!\n"); + return TEST_RV_FAIL; + } + if(EVP_DigestVerifyUpdate(mdctx, (const unsigned char*)"foo", 3) != 1) { + fprintf(stderr, "E: hashing for signature failed!\n"); + return TEST_RV_FAIL; } - free(s); - RSA_free(rsa); - - return ret; + ECDSA_SIG* ec_sig; + if(!is_rsa) { + BIGNUM *r; + BIGNUM *s; + ec_sig = ECDSA_SIG_new(); + if((r = BN_bin2bn(sig, siglen / 2, NULL)) == NULL) { + fprintf(stderr, "E: could not convert R part of ECDSA signature!\n"); + return TEST_RV_FAIL; + } + if((s = BN_bin2bn(sig + (siglen / 2), siglen / 2, NULL)) == NULL) { + fprintf(stderr, "E: could not convert S part of ECDSA signature!\n"); + return TEST_RV_FAIL; + } + if(ECDSA_SIG_set0(ec_sig, r, s) == 0) { + fprintf(stderr, "E: could not set ECDSA_SIG structure!\n"); + return TEST_RV_FAIL; + } + siglen = i2d_ECDSA_SIG(ec_sig, NULL); + unsigned char *dersig = sig = malloc(siglen); + siglen = i2d_ECDSA_SIG(ec_sig, &dersig); + } + if(EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { + fprintf(stderr, "E: signature fails validation!\n"); + return TEST_RV_FAIL; + } + if(!is_rsa) { + free(sig); + } + printf("signature verified\n"); + return TEST_RV_OK; +#else + printf("OpenSSL too old for verification\n"); +#endif } - #endif int test_key(char* label, CK_SESSION_HANDLE session, CK_SLOT_ID slot) { CK_ATTRIBUTE attr[2]; CK_MECHANISM mech; + CK_MECHANISM_TYPE_PTR mechlist; CK_BYTE data[] = { 'f', 'o', 'o' }; CK_BYTE_PTR sig, mod, exp; CK_ULONG sig_len, type, count; - CK_OBJECT_HANDLE privatekey, publickey; + CK_OBJECT_HANDLE privatekey, publickey, certificate; + bool is_rsa = false; + int i; attr[0].type = CKA_CLASS; attr[0].pValue = &type; @@ -113,7 +138,22 @@ return TEST_RV_SKIP; } - mech.mechanism = CKM_SHA256_RSA_PKCS; + check_rv(C_GetMechanismList(slot, NULL_PTR, &count)); + mechlist = malloc(sizeof(CK_MECHANISM_TYPE) * count); +#undef CHECK_RV_DEALLOCATE +#define CHECK_RV_DEALLOCATE free(mechlist) + + check_rv(C_GetMechanismList(slot, mechlist, &count)); + + for(i=0; i 0x10100000L + unsigned char cert[4096]; + attr[0].type = CKA_CLASS; + attr[0].pValue = &type; + type = CKO_CERTIFICATE; + attr[0].ulValueLen = sizeof(CK_ULONG); + + attr[1].type = CKA_LABEL; + attr[1].pValue = label; + attr[1].ulValueLen = strlen(label); + + check_rv(C_FindObjectsInit(session, attr, 2)); + check_rv(C_FindObjects(session, &certificate, 1, &count)); + verbose_assert(count == 1); + check_rv(C_FindObjectsFinal(session)); + + attr[0].type = CKA_VALUE; + attr[0].pValue = cert; + attr[0].ulValueLen = sizeof(cert); + + check_rv(C_GetAttributeValue(session, certificate, attr, 1)); + + printf("Received certificate with length %lu:\n", attr[0].ulValueLen); + hex_dump((char*)cert, attr[0].ulValueLen); + + return verify_sig(sig, sig_len, cert, attr[0].ulValueLen, is_rsa); #else return TEST_RV_OK; #endif