📄 pkcs7callbacks.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pkcs7Callbacks.c,v 1.11 2002/08/06 20:11:06 dallen Exp $
____________________________________________________________________________*/
/*
* Author: Michael_Elkins@NAI.com
* Last Edit: December 9, 1999
*/
#include "x509CMS.h"
#include "pgpHash.h"
#include "pgpErrors.h"
#include "pgpSymmetricCipher.h"
#include "pgpCBC.h"
#include "pgpDebug.h"
int
pkcs7HashCallback (
PKIOCTET_STRING *hashValue, /* OUT */
const char *hashAlgorithm,
const unsigned char *tbs,
size_t tbsLen,
void *data,
PKICONTEXT *asnmem
)
{
PGPError err;
PGPHashContextRef hash;
PGPSize hashLen;
PGPHashAlgorithm algid;
X509CMSCallbackData *pgpData = (X509CMSCallbackData *) data;
if (!strcmp (SM_OID_ALG_MD5, hashAlgorithm))
algid = kPGPHashAlgorithm_MD5;
else if (!strcmp (SM_OID_ALG_SHA, hashAlgorithm))
algid = kPGPHashAlgorithm_SHA;
else
return PKCS7_ERROR_HASH_ALG;
err = PGPNewHashContext (pgpData->context, algid, &hash);
if (IsPGPError (err))
return PKCS7_ERROR_HASH_CALLBACK;
err = PGPContinueHash (hash, tbs, tbsLen);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPGetHashSize (hash, &hashLen);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_HASH_CALLBACK;
}
hashValue->len = hashLen;
hashValue->val = PKIAlloc (asnmem->memMgr, hashLen);
err = PGPFinalizeHash (hash, hashValue->val);
if (IsPGPError (err))
{
PKIFree (asnmem->memMgr, hashValue->val);
hashValue->val = NULL;
hashValue->len = 0;
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPFreeHashContext (hash);
return PKCS7_OK;
}
int
pkcs7SignCallback (
PKIOCTET_STRING *sigValue, /* OUT */
const char *hashAlgorithm,
const char *signatureAlgorithm,
PKICertificate *signerCertificate,
unsigned char *tbs,
size_t tbsLen,
void *data,
PKICONTEXT *asnmem)
{
PGPError err;
PGPHashContextRef hash;
PGPHashAlgorithm algid;
PGPPrivateKeyContextRef privkey;
X509CMSCallbackData *pgpData = (X509CMSCallbackData *) data;
PGPOptionListRef pass;
(void) signatureAlgorithm;
(void) signerCertificate;
if (!strcmp (SM_OID_ALG_MD5, hashAlgorithm))
algid = kPGPHashAlgorithm_MD5;
else if (!strcmp (SM_OID_ALG_SHA, hashAlgorithm))
algid = kPGPHashAlgorithm_SHA;
else
return PKCS7_ERROR_HASH_ALG;
err = PGPNewHashContext (pgpData->context, algid, &hash);
if (IsPGPError (err))
return PKCS7_ERROR_SIGN_CALLBACK;
err = PGPContinueHash (hash, tbs, tbsLen);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_SIGN_CALLBACK;
}
if( pgpData->passphrase == NULL )
pass = PGPONullOption( pgpData->context );
else
PGPCopyOptionList (pgpData->passphrase, &pass);
err = PGPNewPrivateKeyContext (pgpData->key,
kPGPPublicKeyMessageFormat_X509,
&privkey,
pass,
PGPOLastOption (pgpData->context));
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_SIGN_CALLBACK;
}
err = PGPGetPrivateKeyOperationSizes (privkey, NULL, NULL, &sigValue->len);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
err = PGPFreePrivateKeyContext (privkey);
return PKCS7_ERROR_SIGN_CALLBACK;
}
sigValue->val = PKIAlloc (asnmem->memMgr, sigValue->len);
err = PGPPrivateKeySign (privkey, hash, sigValue->val, &sigValue->len);
if (IsPGPError (err))
{
PKIFree (asnmem->memMgr, sigValue->val);
sigValue->val = NULL;
sigValue->len = 0;
err = PGPFreeHashContext (hash);
err = PGPFreePrivateKeyContext (privkey);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPFreePrivateKeyContext (privkey);
return PKCS7_OK;
}
int
pkcs7VerifyCallback (
const unsigned char *tbs, /* signed data */
size_t tbsLen, /* signed data len */
const char *digestAlg, /* hash alg */
const char *digestEncryptionAlg, /* alg to decrypt sig */
PKIEncryptedDigest *signature, /* encrypted sig */
PKICertificate *cert, /* signer cert */
void *data, /* [IN] callback data
(optional) */
PKICONTEXT *asnmem
)
{
X509CMSCallbackData *pgpData = (X509CMSCallbackData *) data;
PGPHashAlgorithm algid;
PGPPublicKeyContextRef pubkey;
PGPError err;
PGPHashContextRef hash;
PGPContextRef context;
(void) digestEncryptionAlg;
(void) cert;
(void) asnmem;
if (!strcmp (SM_OID_ALG_MD5, digestAlg))
algid = kPGPHashAlgorithm_MD5;
else if (!strcmp (SM_OID_ALG_SHA, digestAlg))
algid = kPGPHashAlgorithm_SHA;
else
return PKCS7_ERROR_HASH_ALG;
context = PGPPeekKeyDBObjContext (pgpData->key);
err = PGPNewHashContext (pgpData->context, algid, &hash);
if (IsPGPError (err))
return PKCS7_ERROR_HASH_CALLBACK;
err = PGPContinueHash (hash, tbs, tbsLen);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPNewPublicKeyContext (
pgpData->key,
kPGPPublicKeyMessageFormat_X509,
&pubkey);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPPublicKeyVerifySignature (pubkey,
hash,
signature->val,
signature->len);
if (IsPGPError (err))
{
err = PGPFreeHashContext (hash);
err = PGPFreePublicKeyContext (pubkey);
return PKCS7_ERROR_HASH_CALLBACK;
}
err = PGPFreePublicKeyContext (pubkey);
return PKCS7_OK;
}
int
pkcs7EncryptCallback (
PKIOCTET_STRING *encryptedData, /* [OUT] encrypted data */
PKIANY *encryptParam, /* [OUT] data encryption
parameters (e.g.,
initialization vector) */
const char *dataEncAlg, /* [IN] data encryption alg */
const unsigned char *tbe, /* [IN] data to encrypt */
size_t tbelen, /* [IN] size of data */
List *recips, /* [IN/OUT] who to encrypt to.
The callback also returns
the encrypted session key
for each recipient in this
variable. */
void *data, /* [IN] user supplied data */
PKICONTEXT *asnmem
)
{
PGPSymmetricCipherContextRef cipherRef;
PGPError err;
PGPCipherAlgorithm cipherAlg;
X509CMSCallbackData *pgpData = (X509CMSCallbackData *) data;
PGPMemoryMgrRef mem = PGPPeekContextMemoryMgr (pgpData->context);
PGPSize blockSize, plainTextLen, lastBlockLen, keySize;
List *pRecip;
int e = 0, singleDES = 0, ret = PKCS7_ERROR_CALLBACK;
/* must be free'd before exiting this function */
PGPPublicKeyContextRef pubKey;
PGPCBCContextRef cbcRef;
PKIOCTET_STRING *iv = NULL;
PGPByte *randomBuf = NULL;
PGPByte *lastBlock = NULL;
if (!strcmp (dataEncAlg, SM_OID_ALG_3DES))
cipherAlg = kPGPCipherAlgorithm_3DES;
else if (!strcmp (dataEncAlg, SM_OID_ALG_DES)) /* DES-CBC */
{
/* PGPsdk does not support 1DES, but we can fake it using 3DES with
the same key repeated */
cipherAlg = kPGPCipherAlgorithm_3DES;
singleDES = 1;
}
else
return PKCS7_ERROR_CALLBACK; /* unsupported algorithm */
err = PGPNewSymmetricCipherContext (pgpData->context, cipherAlg, &cipherRef);
if (IsPGPError (err))
return PKCS7_ERROR_CALLBACK;
err = PGPGetSymmetricCipherSizes (cipherRef, &keySize, &blockSize);
if (IsPGPError (err))
goto error;
err = PGPNewCBCContext (cipherRef, &cbcRef);
if (IsPGPError (err))
goto error;
cipherRef = NULL; /* cbcRef destroys this */
/* Generate a random session key and IV */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -