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

📄 export.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: export.c,v 1.13 2002/08/06 20:11:08 dallen Exp $
____________________________________________________________________________*/

/*
 * export.c - code to export a PKCS-8 PrivateKeyInfo and X.509
 * Certificate as a PKCS-12 message
 */

#include "pbe12.h"
#include "pkcs7_oid.h"

static PGPError
pbe12ShroudKey (PGPContextRef context,
		PKICONTEXT *pki,
		PGPPBEAlgorithm alg,
		const PGPByte *pass,
		PGPSize passSize,
		int iterations,
		const PGPByte *privKey,
		PGPSize privKeySize,
		PGPByte **out,
		PGPSize *outSize)
{
    PKIEncryptedPrivateKeyInfo *epki = 0;
    PKIpkcs_12PbeParams *pbeParam = 0;
    PGPError err;
    PGPMemoryMgrRef mem = PGPPeekContextMemoryMgr (context);
    PGPSize keySize = 24; /* size of 3DES key */
    PGPByte *iv = 0;
    PGPByte *key = 0;
    PGPSymmetricCipherContextRef symRef = 0;
    PGPCBCContextRef cbcRef = 0;
    PGPByte block[8];
    PGPSize extraBytes;
    int asnerr;
    
    (void) alg; /* unused */

    *out = 0;
    *outSize = 0;
    
    epki = PKINewEncryptedPrivateKeyInfo (pki);

    PKIPutOctVal (pki, &epki->encryptionAlgorithm.algorithm,
		  PKIpbeWithSHA1And3_KeyTripleDES_CBC_OID,
		  PKIpbeWithSHA1And3_KeyTripleDES_CBC_OID_LEN);

    /* generate pbe parameters */
    pbeParam = PKINewpkcs_12PbeParams (pki);
    PKIPutIntVal (pki, &pbeParam->iterationCount, iterations);

    /* generate random salt value.  PKCS-12 says that in general the salt
       should be as long as the key used */
    pbeParam->salt.len = keySize;
    pbeParam->salt.val = PGPNewData (mem, keySize, 0);
    err = PGPContextGetRandomBytes (context, pbeParam->salt.val,
				    pbeParam->salt.len);
    if (err)
	goto error;

    /* pack pbe params */
    epki->encryptionAlgorithm.parameters = PKINewANY (pki);
    epki->encryptionAlgorithm.parameters->len = PKISizeofpkcs_12PbeParams (pki, pbeParam, PKITRUE);
    epki->encryptionAlgorithm.parameters->val = PGPNewData (mem, epki->encryptionAlgorithm.parameters->len, 0);
    asnerr = 0;
    PKIPackpkcs_12PbeParams (pki, epki->encryptionAlgorithm.parameters->val,
			     epki->encryptionAlgorithm.parameters->len,
			     pbeParam, &asnerr);
    if (asnerr)
	{
	    err = kPGPError_ASNPackFailure;
	    goto error;    
	}
    
    /* generate IV for symmetric encryption */
    err = pbe12GenerateRandomBits (context,
				   kPGPHashAlgorithm_SHA,
				   kPGPPBEIDIV,
				   iterations,
				   pbeParam->salt.val,
				   pbeParam->salt.len,
				   pass,
				   passSize,
				   keySize,
				   &iv);
    if (err)
	goto error;
    
    /* generate key for symmetric encryption */
    err = pbe12GenerateRandomBits (context,
				   kPGPHashAlgorithm_SHA,
				   kPGPPBEIDEncryptKey,
				   iterations,
				   pbeParam->salt.val,
				   pbeParam->salt.len,
				   pass,
				   passSize,
				   keySize,
				   &key);
    if (err)
	goto error;

    /* create encryption context */
    err = PGPNewSymmetricCipherContext (context,
					kPGPCipherAlgorithm_3DES,
					&symRef);
    if (err)
	goto error;

    /* create CBC context */
    err = PGPNewCBCContext (symRef, &cbcRef);
    if (err)
	goto error;
    symRef = 0; /* FreeCBCContext() takes care of destroying symRef */
    
    /* initialiaze */
    err = PGPInitCBC (cbcRef, key, iv);
    if (err)
	goto error;

    extraBytes = privKeySize % 8;

    /* output will be a multiple of the block size, which for 3DES is 8.  we
       add an extra block for the pkcs-5 style padding */
    epki->encryptedData.len = privKeySize - extraBytes + 8;
    epki->encryptedData.val = PGPNewData (mem, epki->encryptedData.len, 0);

    /* encrypt all but last block */
    err = PGPCBCEncrypt (cbcRef, privKey, privKeySize - extraBytes,
			 epki->encryptedData.val);
    if (err)
	goto error;

    /* copy remaining unencrypted bytes into block[] */
    memcpy (block, privKey + privKeySize - extraBytes, extraBytes);

    /* add pkcs-5 pad */
    memset (block + extraBytes, 8 - extraBytes, 8 - extraBytes);

    /* encrypt final block */
    err = PGPCBCEncrypt (cbcRef, block, 8,
			 epki->encryptedData.val + privKeySize - extraBytes);
    if (err)
	goto error;

    /* pack up ASN.1 structure */
    *outSize = PKISizeofEncryptedPrivateKeyInfo (pki, epki, PKITRUE);
    *out = PGPNewData (mem, *outSize, 0);
    asnerr = 0;
    PKIPackEncryptedPrivateKeyInfo (pki, *out, *outSize, epki, &asnerr);
    if (asnerr)
	{
	    err = kPGPError_ASNPackFailure;
	    goto error;    
	}

    /* success */
    err = kPGPError_NoErr;
    
 error:
    
    if (IsPGPError (err))
	{
	    if (*out)
		{
		    PGPFreeData (*out);
		    *out = 0;
		}
	    *outSize = 0;
	}
    
    if (pbeParam)
	PKIFreepkcs_12PbeParams (pki, pbeParam);
    if (epki)
	PKIFreeEncryptedPrivateKeyInfo (pki, epki);
    if (cbcRef)
	PGPFreeCBCContext (cbcRef);
    if (symRef)
	PGPFreeSymmetricCipherContext (symRef);
    if (iv)
	PGPFreeData (iv);
    if (key)
	PGPFreeData (key);
    
    return err;
}

/* 1 3 14 3 2 26 */
const PGPByte PKIsha1_OID[] = { 0x2B, 0x0e, 0x03, 0x02, 0x1a };
#define PKIsha1_OID_LEN 5

static PGPError
pkcs12GenerateMAC (PGPContextRef context,
		   PKICONTEXT *pki,
		   PKIPFX *pfx,
		   PKIOCTET_STRING *tbh,
		   int iterations,
		   const PGPByte *pass,
		   PGPSize passSize,
		   PGPHashAlgorithm alg)
{
    PGPError err;
    PGPMemoryMgrRef mem = PGPPeekContextMemoryMgr (context);
    PGPByte *key = 0;
    PGPHMACContextRef hashRef = 0;
    PGPSize keySize;
    
    switch (alg)
	{
	case kPGPHashAlgorithm_SHA:
	    keySize = 20;
	    break;
#if 0
	case kPGPHashAlgorithm_MD5:
	    keySize = 16;
	    break;
#endif
	default:
	    return kPGPError_LazyProgrammer; /* bad hash algorithm */
	}

    /* allocate storage for the mac data */
    pfx->macData = PKINewMacData (pki);
    if (iterations != 1)
	{
	    pfx->macData->macIterationCount = PKINewINTEGER (pki);
	    PKIPutIntVal (pki, pfx->macData->macIterationCount, iterations);
	}
    
    PKIPutOctVal (pki, &pfx->macData->mac.digestAlgorithm.algorithm,
		  PKIsha1_OID, PKIsha1_OID_LEN);

    /* generate salt value */
    pfx->macData->macSalt.len = keySize;
    pfx->macData->macSalt.val = PGPNewData (mem, keySize, 0);
    err = PGPContextGetRandomBytes (context, pfx->macData->macSalt.val, keySize);
    if (IsPGPError (err))
	goto error;

    /* generate MAC key */
    err = pbe12GenerateRandomBits (context,
				   alg,
				   kPGPPBEIDMACKey,
				   iterations,
				   pfx->macData->macSalt.val,
				   pfx->macData->macSalt.len,
				   pass,
				   passSize,
				   keySize,
				   &key);
    /* set up HMAC context */
    err = PGPNewHMACContext (context, alg, key, keySize, &hashRef);
    if (IsPGPError (err))
	goto error;
    err = PGPContinueHMAC (hashRef, tbh->val, tbh->len);
    if (IsPGPError (err))
	goto error;

    pfx->macData->mac.digest.len = keySize;
    pfx->macData->mac.digest.val = PGPNewData (mem, keySize, 0);
    err = PGPFinalizeHMAC (hashRef, pfx->macData->mac.digest.val);
    if (IsPGPError (err))
	goto error;
    
    err = kPGPError_NoErr;
    
 error:
    if (key)
	PGPFreeData (key);
    if (hashRef)
	PGPFreeHMACContext (hashRef);
    return err;
    
}

/* Set necessary attributes on the bag */
static PGPError
pkcs12SetAttributes (PGPContextRef context,
		     PKICONTEXT *pki,
		     PKISafeBag *sb,
		     PGPByte const *friendlyName,
		     PGPSize friendlyLen,
		     int includeKeyID )
{
    PGPMemoryMgrRef mem = PGPPeekContextMemoryMgr (context);
    PGPByte *buf;
    PGPSize len;
    PKIBMPString *fname;
#define PKIfriendlyName_OID_LEN 9
    PGPByte PKIfriendlyName_OID[PKIfriendlyName_OID_LEN] = {
	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14 };
#define PKIlocalKeyID_OID_LEN 9
    PGPByte PKIlocalKeyID_OID[PKIfriendlyName_OID_LEN] = {
	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15 };
    PGPByte lKeyID[6] = { 0x04, 0x04, 0x00, 0x11, 0x22, 0x33 }; /* oct str */
    int asnerr = 0;

    (void)includeKeyID;

    sb->bagAttributes = PKINewAttributes (pki);
    PKIAddOfElement(pki, PKINewAttribute(pki), sb->bagAttributes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -