From 8c535c184f41dff417eb23069fec511f911f8ae6 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Thu, 4 Oct 2018 15:59:11 +0200 Subject: [PATCH] removed duplicate code for adding padding Fixes padding handling of SC_ALGORITHM_RSA_PAD_NONE introduced with e5707b545e5a2dc33b0ca52a8bf63f36f71b3d85 --- src/libopensc/padding.c | 9 +-- src/minidriver/minidriver.c | 140 +++++++++++++++--------------------- 2 files changed, 62 insertions(+), 87 deletions(-) diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index 934fc67d..75c92b65 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -487,18 +487,19 @@ int sc_get_encoding_flags(sc_context_t *ctx, *pflags = 0; } else if ((caps & SC_ALGORITHM_RSA_PAD_PSS) && - (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { + (iflags & SC_ALGORITHM_RSA_PAD_PSS)) { *sflags |= SC_ALGORITHM_RSA_PAD_PSS; } else if (((caps & SC_ALGORITHM_RSA_RAW) && - (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) - || iflags & SC_ALGORITHM_RSA_PAD_PSS) { + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) + || iflags & SC_ALGORITHM_RSA_PAD_PSS + || iflags & SC_ALGORITHM_RSA_PAD_NONE) { /* Use the card's raw RSA capability on the padded input */ *sflags = SC_ALGORITHM_RSA_PAD_NONE; *pflags = iflags; } else if ((caps & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) && - (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { + (iflags & SC_ALGORITHM_RSA_PAD_PKCS1)) { /* A corner case - the card can partially do PKCS1, if we prepend the * DigestInfo bit it will do the rest. */ *sflags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 2ffffcc1..bc1c58d1 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -4581,7 +4581,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO ALG_ID hashAlg; sc_pkcs15_prkey_info_t *prkey_info; BYTE dataToSign[0x200]; - int r, opt_crypt_flags = 0, opt_hash_flags = 0; + int opt_crypt_flags; size_t dataToSignLen = sizeof(dataToSign); sc_pkcs15_object_t *pkey; @@ -4663,112 +4663,86 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO memcpy(dataToSign, pInfo->pbData, pInfo->cbData); dataToSignLen = pInfo->cbData; - if (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags) { - BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; - if (CARD_PADDING_PSS == pInfo->dwPaddingType) { - logprintf(pCardData, 0, "unsupported paddingtype CARD_PADDING_PSS\n"); - dwret = SCARD_E_UNSUPPORTED_FEATURE; - goto err; - } - else if (CARD_PADDING_PKCS1 != pInfo->dwPaddingType) { - logprintf(pCardData, 0, "unsupported paddingtype\n"); - dwret = SCARD_E_INVALID_PARAMETER; - goto err; - } - - if (!pinf->pszAlgId) { - /* hashAlg = CALG_SSL3_SHAMD5; */ - logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; - } - else { - if (wcscmp(pinf->pszAlgId, L"MD5") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5; - else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; - else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA224; - else if (wcscmp(pinf->pszAlgId, L"SHA256") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256; - else if (wcscmp(pinf->pszAlgId, L"SHA384") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384; - else if (wcscmp(pinf->pszAlgId, L"SHA512") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512; - else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; - else { - logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); - dwret = SCARD_E_UNSUPPORTED_FEATURE; - goto err; - } - } - } - else { + if (0 == (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags)) { + /* When CARD_PADDING_INFO_PRESENT is not set in dwSigningFlags, this is + * the basic version of the signing structure. (If this is not the + * basic verison of the signing structure, the minidriver should return + * ERROR_REVISION_MISMATCH.) The minidriver should only do PKCS1 + * padding and use the value in aiHashAlg. */ logprintf(pCardData, 3, "CARD_PADDING_INFO_PRESENT not set\n"); + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; if (hashAlg == CALG_MD5) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; else if (hashAlg == CALG_SHA1) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; else if (hashAlg == CALG_SSL3_SHAMD5) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; else if (hashAlg == CALG_SHA_256) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA256; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; else if (hashAlg == CALG_SHA_384) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA384; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; else if (hashAlg == CALG_SHA_512) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA512; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; else if (hashAlg == (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_RIPEMD160)) - opt_hash_flags = SC_ALGORITHM_RSA_HASH_RIPEMD160; + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; else if (hashAlg !=0) { logprintf(pCardData, 0, "bogus aiHashAlg %i\n", hashAlg); dwret = SCARD_E_UNSUPPORTED_FEATURE; goto err; } - } - opt_hash_flags |= SC_ALGORITHM_RSA_PAD_NONE; - - if (pInfo->dwSigningFlags & CARD_PADDING_NONE) - { - /* do not add the digest info when called from CryptSignHash(CRYPT_NOHASHOID) + } else { + switch (pInfo->dwPaddingType) { + case CARD_PADDING_NONE: + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_NONE; + break; - Note: SC_ALGORITHM_RSA_HASH_MD5_SHA1 aka CALG_SSL3_SHAMD5 do not have a digest info to be added - CryptSignHash(CALG_SSL3_SHAMD5,CRYPT_NOHASHOID) is the same than CryptSignHash(CALG_SSL3_SHAMD5) - */ - opt_hash_flags = 0; - } + case CARD_PADDING_PKCS1: + opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1; + BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo; - /* From sc-minidriver_specs_v7.docx pp.76: - * 'The Base CSP/KSP performs the hashing operation on the data before passing it - * to CardSignData for signature.' - * So, the SC_ALGORITHM_RSA_HASH_* flags should not be passed to pkcs15 library - * when calculating the signature . - * - * From sc-minidriver_specs_v7.docx pp.76: - * 'If the aiHashAlg member is nonzero, it specifies the hash algorithm’s object identifier (OID) - * that is encoded in the PKCS padding.' - * So, the digest info has be included into the data to be signed. - * */ - if (opt_hash_flags) { - logprintf(pCardData, 2, "include digest info of the algorithm 0x%08X\n", opt_hash_flags); - dataToSignLen = sizeof(dataToSign); - r = sc_pkcs1_encode(vs->ctx, opt_hash_flags, pInfo->pbData, pInfo->cbData, dataToSign, &dataToSignLen, 0); - if (r) { - logprintf(pCardData, 2, "PKCS#1 encode error %s\n", sc_strerror(r)); - dwret = SCARD_E_INVALID_VALUE; - goto err; + if (!pinf->pszAlgId) { + /* hashAlg = CALG_SSL3_SHAMD5; */ + logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5 hashAlg\n"); + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + } else { + if (wcscmp(pinf->pszAlgId, L"MD5") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; + else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; + else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; + else if (wcscmp(pinf->pszAlgId, L"SHA224") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; + else if (wcscmp(pinf->pszAlgId, L"SHA256") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; + else if (wcscmp(pinf->pszAlgId, L"SHA384") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; + else if (wcscmp(pinf->pszAlgId, L"SHA512") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; + else if (wcscmp(pinf->pszAlgId, L"RIPEMD160") == 0) + opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160; + else { + logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId)); + dwret = SCARD_E_UNSUPPORTED_FEATURE; + goto err; + } + } + break; + + default: + logprintf(pCardData, 0, "unsupported paddingtype\n"); + dwret = SCARD_E_INVALID_PARAMETER; + goto err; } } + /* Compute output size */ if ( prkey_info->modulus_length > 0) { /* RSA */ pInfo->cbSignedData = (DWORD) prkey_info->modulus_length / 8; - opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE; } else if ( prkey_info->field_length > 0) { - opt_crypt_flags = SC_ALGORITHM_ECDSA_HASH_NONE; switch(prkey_info->field_length) { case 256: /* ECDSA_P256 */