📄 export.c
字号:
/*____________________________________________________________________________
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 + -