mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #2645 from cconlon/cmsrsacb
CMS SignedData RSA sign callback for raw digestpull/2658/head
commit
05e672428d
87
tests/api.c
87
tests/api.c
|
@ -16708,6 +16708,71 @@ static void test_wc_PKCS7_EncodeData (void)
|
||||||
} /* END test_wc_PKCS7_EncodeData */
|
} /* END test_wc_PKCS7_EncodeData */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && \
|
||||||
|
!defined(NO_RSA) && !defined(NO_SHA256)
|
||||||
|
/* RSA sign raw digest callback */
|
||||||
|
static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
|
||||||
|
byte* out, word32 outSz, byte* privateKey,
|
||||||
|
word32 privateKeySz, int devid, int hashOID)
|
||||||
|
{
|
||||||
|
/* specific DigestInfo ASN.1 encoding prefix for a SHA2565 digest */
|
||||||
|
byte digInfoEncoding[] = {
|
||||||
|
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
|
||||||
|
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
|
||||||
|
0x00, 0x04, 0x20
|
||||||
|
};
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
byte digestInfo[ONEK_BUF];
|
||||||
|
byte sig[FOURK_BUF];
|
||||||
|
word32 digestInfoSz = 0;
|
||||||
|
word32 idx = 0;
|
||||||
|
RsaKey rsa;
|
||||||
|
|
||||||
|
/* SHA-256 required only for this example callback due to above
|
||||||
|
* digInfoEncoding[] */
|
||||||
|
if (pkcs7 == NULL || digest == NULL || out == NULL ||
|
||||||
|
(sizeof(digestInfo) < sizeof(digInfoEncoding) + digestSz) ||
|
||||||
|
(hashOID != SHA256h)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build DigestInfo */
|
||||||
|
XMEMCPY(digestInfo, digInfoEncoding, sizeof(digInfoEncoding));
|
||||||
|
digestInfoSz += sizeof(digInfoEncoding);
|
||||||
|
XMEMCPY(digestInfo + digestInfoSz, digest, digestSz);
|
||||||
|
digestInfoSz += digestSz;
|
||||||
|
|
||||||
|
/* set up RSA key */
|
||||||
|
ret = wc_InitRsaKey_ex(&rsa, pkcs7->heap, devid);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wc_RsaPrivateKeyDecode(privateKey, &idx, &rsa, privateKeySz);
|
||||||
|
|
||||||
|
/* sign DigestInfo */
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_RsaSSL_Sign(digestInfo, digestInfoSz, sig, sizeof(sig),
|
||||||
|
&rsa, pkcs7->rng);
|
||||||
|
if (ret > 0) {
|
||||||
|
if (ret > (int)outSz) {
|
||||||
|
/* output buffer too small */
|
||||||
|
ret = -1;
|
||||||
|
} else {
|
||||||
|
/* success, ret holds sig size */
|
||||||
|
XMEMCPY(out, sig, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wc_FreeRsaKey(&rsa);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Testing wc_PKCS7_EncodeSignedData()
|
* Testing wc_PKCS7_EncodeSignedData()
|
||||||
*/
|
*/
|
||||||
|
@ -16819,6 +16884,27 @@ static void test_wc_PKCS7_EncodeSignedData(void)
|
||||||
pkcs7->hashOID = 0; /* bad hashOID */
|
pkcs7->hashOID = 0; /* bad hashOID */
|
||||||
AssertIntEQ(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), BAD_FUNC_ARG);
|
AssertIntEQ(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), BAD_FUNC_ARG);
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && \
|
||||||
|
!defined(NO_RSA) && !defined(NO_SHA256)
|
||||||
|
/* test RSA sign raw digest callback, if using RSA and compiled in.
|
||||||
|
* Example callback assumes SHA-256, so only run test if compiled in. */
|
||||||
|
wc_PKCS7_Free(pkcs7);
|
||||||
|
AssertNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, devId));
|
||||||
|
AssertIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);
|
||||||
|
|
||||||
|
pkcs7->content = data;
|
||||||
|
pkcs7->contentSz = (word32)sizeof(data);
|
||||||
|
pkcs7->privateKey = key;
|
||||||
|
pkcs7->privateKeySz = (word32)sizeof(key);
|
||||||
|
pkcs7->encryptOID = RSAk;
|
||||||
|
pkcs7->hashOID = SHA256h;
|
||||||
|
pkcs7->rng = &rng;
|
||||||
|
|
||||||
|
AssertIntEQ(wc_PKCS7_SetRsaSignRawDigestCb(pkcs7, rsaSignRawDigestCb), 0);
|
||||||
|
|
||||||
|
AssertIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
printf(resultFmt, passed);
|
printf(resultFmt, passed);
|
||||||
|
|
||||||
wc_PKCS7_Free(pkcs7);
|
wc_PKCS7_Free(pkcs7);
|
||||||
|
@ -16827,6 +16913,7 @@ static void test_wc_PKCS7_EncodeSignedData(void)
|
||||||
#endif
|
#endif
|
||||||
} /* END test_wc_PKCS7_EncodeSignedData */
|
} /* END test_wc_PKCS7_EncodeSignedData */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Testing wc_PKCS7_EncodeSignedData_ex() and wc_PKCS7_VerifySignedData_ex()
|
* Testing wc_PKCS7_EncodeSignedData_ex() and wc_PKCS7_VerifySignedData_ex()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1982,8 +1982,12 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
||||||
ESD* esd)
|
ESD* esd)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
#ifdef HAVE_ECC
|
#if defined(HAVE_ECC) || \
|
||||||
|
(defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
|
||||||
int hashSz = 0;
|
int hashSz = 0;
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
|
||||||
|
int hashOID;
|
||||||
#endif
|
#endif
|
||||||
word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
|
word32 digestInfoSz = MAX_PKCS7_DIGEST_SZ;
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
@ -2014,11 +2018,37 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_ECC) || \
|
||||||
|
(defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA))
|
||||||
|
/* get digest size from hash type */
|
||||||
|
hashSz = wc_HashGetDigestSize(esd->hashType);
|
||||||
|
if (hashSz < 0) {
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return hashSz;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* sign digestInfo */
|
/* sign digestInfo */
|
||||||
switch (pkcs7->publicKeyOID) {
|
switch (pkcs7->publicKeyOID) {
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
case RSAk:
|
case RSAk:
|
||||||
|
#ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
|
||||||
|
if (pkcs7->rsaSignRawDigestCb != NULL) {
|
||||||
|
/* get hash OID */
|
||||||
|
hashOID = wc_HashGetOID(esd->hashType);
|
||||||
|
|
||||||
|
/* user signing plain digest, build DigestInfo themselves */
|
||||||
|
ret = pkcs7->rsaSignRawDigestCb(pkcs7,
|
||||||
|
esd->contentAttribsDigest, hashSz,
|
||||||
|
esd->encContentDigest, sizeof(esd->encContentDigest),
|
||||||
|
pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
|
||||||
|
hashOID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
|
ret = wc_PKCS7_RsaSign(pkcs7, digestInfo, digestInfoSz, esd);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2027,14 +2057,6 @@ static int wc_PKCS7_SignedDataBuildSignature(PKCS7* pkcs7,
|
||||||
case ECDSAk:
|
case ECDSAk:
|
||||||
/* CMS with ECDSA does not sign DigestInfo structure
|
/* CMS with ECDSA does not sign DigestInfo structure
|
||||||
* like PKCS#7 with RSA does */
|
* like PKCS#7 with RSA does */
|
||||||
hashSz = wc_HashGetDigestSize(esd->hashType);
|
|
||||||
if (hashSz < 0) {
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(digestInfo, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
|
||||||
#endif
|
|
||||||
return hashSz;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
|
ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
|
||||||
hashSz, esd);
|
hashSz, esd);
|
||||||
break;
|
break;
|
||||||
|
@ -3032,6 +3054,20 @@ int wc_PKCS7_EncodeSignedEncryptedCompressedFPD(PKCS7* pkcs7, byte* encryptKey,
|
||||||
|
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
|
|
||||||
|
#ifdef HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
|
||||||
|
/* register raw RSA sign digest callback */
|
||||||
|
int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
|
||||||
|
{
|
||||||
|
if (pkcs7 == NULL || cb == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkcs7->rsaSignRawDigestCb = cb;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* returns size of signature put into out, negative on error */
|
/* returns size of signature put into out, negative on error */
|
||||||
static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
static int wc_PKCS7_RsaVerify(PKCS7* pkcs7, byte* sig, int sigSz,
|
||||||
byte* hash, word32 hashSz)
|
byte* hash, word32 hashSz)
|
||||||
|
|
|
@ -220,6 +220,14 @@ typedef int (*CallbackWrapCEK)(PKCS7* pkcs7, byte* cek, word32 cekSz,
|
||||||
byte* out, word32 outSz,
|
byte* out, word32 outSz,
|
||||||
int keyWrapAlgo, int type, int dir);
|
int keyWrapAlgo, int type, int dir);
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
|
||||||
|
/* RSA sign raw digest callback, user builds DigestInfo */
|
||||||
|
typedef int (*CallbackRsaSignRawDigest)(PKCS7* pkcs7, byte* digest,
|
||||||
|
word32 digestSz, byte* out, word32 outSz,
|
||||||
|
byte* privateKey, word32 privateKeySz,
|
||||||
|
int devId, int hashOID);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Public Structure Warning:
|
/* Public Structure Warning:
|
||||||
* Existing members must not be changed to maintain backwards compatibility!
|
* Existing members must not be changed to maintain backwards compatibility!
|
||||||
*/
|
*/
|
||||||
|
@ -318,6 +326,10 @@ struct PKCS7 {
|
||||||
word32 signatureSz;
|
word32 signatureSz;
|
||||||
word32 plainDigestSz;
|
word32 plainDigestSz;
|
||||||
word32 pkcs7DigestSz;
|
word32 pkcs7DigestSz;
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
|
||||||
|
CallbackRsaSignRawDigest rsaSignRawDigestCb;
|
||||||
|
#endif
|
||||||
/* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */
|
/* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -439,6 +451,11 @@ WOLFSSL_API int wc_PKCS7_AddRecipient_ORI(PKCS7* pkcs7, CallbackOriEncrypt cb,
|
||||||
WOLFSSL_API int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_SetWrapCEKCb(PKCS7* pkcs7,
|
||||||
CallbackWrapCEK wrapCEKCb);
|
CallbackWrapCEK wrapCEKCb);
|
||||||
|
|
||||||
|
#if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA)
|
||||||
|
WOLFSSL_API int wc_PKCS7_SetRsaSignRawDigestCb(PKCS7* pkcs7,
|
||||||
|
CallbackRsaSignRawDigest cb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* CMS/PKCS#7 EnvelopedData */
|
/* CMS/PKCS#7 EnvelopedData */
|
||||||
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
|
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
|
|
Loading…
Reference in New Issue