📄 pkcs7callbacks.c
字号:
return PKCS7_ERROR_CALLBACK;
}
/* Generate a random session key and IV */
randomBuf = PGPNewSecureData (mem, keySize, 0);
err = PGPContextGetRandomBytes (pgpData->context, randomBuf, keySize);
if (IsPGPError (err))
{
PGPFreeData (randomBuf);
PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
iv = PKINewOCTET_STRING (asnmem);
iv->len = blockSize;
iv->val = PKIAlloc (asnmem->memMgr, iv->len);
err = PGPContextGetRandomBytes (pgpData->context, iv->val, iv->len);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
err = PGPInitCBC (cbcRef, randomBuf, iv->val);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
/* encrypt all full blocks in one pass */
plainTextLen = tbelen - (tbelen % blockSize);
encryptedData->len = plainTextLen + blockSize;
encryptedData->val = PKIAlloc (asnmem->memMgr, encryptedData->len);
err = PGPCBCEncrypt (cbcRef, tbe, plainTextLen, encryptedData->val);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
/* pad the last block according to PKCS-7 */
lastBlockLen = tbelen - plainTextLen;
lastBlock = PGPNewSecureData (mem, blockSize, 0);
memcpy (lastBlock, tbe + plainTextLen, lastBlockLen);
for (i = lastBlockLen; i < blockSize; i++)
lastBlock[i] = blockSize - lastBlockLen;
err = PGPCBCEncrypt (cbcRef, lastBlock, blockSize, encryptedData->val + plainTextLen);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
PGPFreeData (lastBlock);
PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
PGPFreeData (lastBlock);
err = PGPFreeCBCContext (cbcRef);
if (IsPGPError (err))
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
encryptParam->len = PKISizeofOCTET_STRING (asnmem, iv, TRUE);
encryptParam->val = PKIAlloc (asnmem->memMgr, encryptParam->len);
PKIPackOCTET_STRING (asnmem, encryptParam->val, encryptParam->len, iv, &e);
if (e)
{
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
PKIFreeOCTET_STRING (asnmem, iv);
/* encrypt session key for each recipient */
for (pRecip = recips; pRecip; pRecip = pRecip->next)
{
PGPSize decSize;
PGPSize sigSize;
EncryptRecipient *info = (EncryptRecipient *) pRecip->data;
err = PGPNewPublicKeyContext ((PGPKeyRef) info->data,
kPGPPublicKeyMessageFormat_PKCS1, /* HACK - only for RSA */
&pubKey);
if (IsPGPError (err))
{
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
err = PGPGetPublicKeyOperationSizes (pubKey,
&decSize,
&info->encryptedKeyLen,
&sigSize);
if (IsPGPError (err))
{
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
info->encryptedKey = PKIAlloc (asnmem->memMgr, info->encryptedKeyLen);
err = PGPPublicKeyEncrypt (pubKey,
randomBuf,
keySize,
info->encryptedKey,
&info->encryptedKeyLen);
if (IsPGPError (err))
{
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
err = PGPFreePublicKeyContext (pubKey);
if (IsPGPError (err))
{
PGPFreeData (randomBuf);
return PKCS7_ERROR_CALLBACK;
}
/* ??? should this be part of the PKCS7 library rather than the
responsibility of the callback? */
info->algorithm = sm_OIDToString (&info->certificate->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm, asnmem);
}
PGPFreeData (randomBuf);
return PKCS7_OK;
}
int
pkcs7DecryptCallback (
unsigned char **msg, /* [OUT] decrypted data */
size_t *msgLen, /* [OUT] decrypted data len */
const char *contentEncAlg, /* [IN] data encrypted alg */
PKIANY *param, /* [IN] data encryption
parameter (e.g.,
initialization vector) */
PKIEncryptedContent *content, /* [IN] encrypted data */
const char *keyEncAlg, /* [IN] key encryption alg */
PKIEncryptedKey *enckey, /* [IN] encrypted key */
PKICertificate *cert, /* [IN] key to decrypt with */
void *data, /* [IN] callback data
(optional) */
PKICONTEXT *asnmem
)
{
X509CMSCallbackData *pgpData = (X509CMSCallbackData *) data;
PGPError err;
PGPSize decmax;
PGPByte *encKeyData;
PGPMemoryMgrRef mem;
PGPCipherAlgorithm symKeyAlg;
PGPSymmetricCipherContextRef cipherRef;
PGPCBCContextRef cbcRef;
PGPPrivateKeyContextRef privKey;
PGPSize keySize;
PGPSize blockSize;
PGPOptionListRef pass;
PKIOCTET_STRING *iv;
int e = 0;
size_t pad;
(void) keyEncAlg;
(void) cert;
*msg = NULL;
*msgLen = 0;
if (!strcmp (contentEncAlg, SM_OID_ALG_3DES))
symKeyAlg = kPGPCipherAlgorithm_3DES;
else
{
/* unsupported algorithm */
return PKCS7_ERROR_CALLBACK;
}
/* decrypt the encrypted session key with our private key */
PGPCopyOptionList (pgpData->passphrase, &pass);
err = PGPNewPrivateKeyContext (pgpData->key,
kPGPPublicKeyMessageFormat_PKCS1,
&privKey,
pass,
PGPOLastOption (pgpData->context));
if (IsPGPError (err))
return PKCS7_ERROR_CALLBACK;
err = PGPGetPrivateKeyOperationSizes (privKey, &decmax, NULL, NULL);
if (IsPGPError (err))
{
err = PGPFreePrivateKeyContext (privKey);
return PKCS7_ERROR_CALLBACK;
}
mem = PGPGetContextMemoryMgr (pgpData->context);
encKeyData = PGPNewSecureData (mem, decmax, 0);
err = PGPPrivateKeyDecrypt (privKey,
enckey->val,
enckey->len,
encKeyData,
&decmax);
if (IsPGPError (err))
{
PGPFreeData (encKeyData);
err = PGPFreePrivateKeyContext (privKey);
return PKCS7_ERROR_CALLBACK;
}
err = PGPFreePrivateKeyContext (privKey);
/* unpack the parameters for the decryption (IV) */
PKIUnpackOCTET_STRING (asnmem, &iv, param->val, param->len, &e);
if (e)
{
PGPFreeData (encKeyData);
return PKCS7_ERROR_CALLBACK;
}
/* now decrypt the message data with the extracted key */
err = PGPNewSymmetricCipherContext (mem, symKeyAlg, decmax, &cipherRef);
if (IsPGPError (err))
{
PGPFreeData (encKeyData);
PKIFreeOCTET_STRING (asnmem, iv);
return PKCS7_ERROR_CALLBACK;
}
err = PGPGetSymmetricCipherSizes (cipherRef, &keySize, &blockSize);
if (IsPGPError (err))
{
PGPFreeData (encKeyData);
PKIFreeOCTET_STRING (asnmem, iv);
err = PGPFreeSymmetricCipherContext (cipherRef);
return PKCS7_ERROR_CALLBACK;
}
err = PGPNewCBCContext (cipherRef, &cbcRef);
if (IsPGPError (err))
{
PGPFreeData (encKeyData);
err = PGPFreeSymmetricCipherContext (cipherRef);
PKIFreeOCTET_STRING (asnmem, iv);
return PKCS7_ERROR_CALLBACK;
}
err = PGPInitCBC (cbcRef, encKeyData, iv->val);
if (IsPGPError (err))
{
err = PGPFreeCBCContext (cbcRef);
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (encKeyData);
return PKCS7_ERROR_CALLBACK;
}
PKIFreeOCTET_STRING (asnmem, iv);
PGPFreeData (encKeyData);
*msgLen = content->len;
*msg = PKIAlloc (asnmem->memMgr, content->len);
err = PGPCBCDecrypt (cbcRef, content->val, content->len, *msg);
if (IsPGPError (err))
{
PKIFree (asnmem->memMgr, *msg);
*msg = NULL;
*msgLen = 0;
err = PGPFreeCBCContext (cbcRef);
return PKCS7_ERROR_CALLBACK;
}
/* remove PKCS7 padding in last block */
pad = *(*msg + *msgLen - 1);
if (pad < 1 || pad > blockSize)
return PKCS7_ERROR_CALLBACK; /* invalid pad, decryption failed */
*msgLen -= pad;
return PKCS7_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -