⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkcs7callbacks.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	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 + -