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

📄 import.c

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

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

/*
 * import.c - routines for importing a PKCS-12
 * Author: Michael_Elkins@NAI.com
 */

#include "pbe12.h"
#include "pgpSymmetricCipherPriv.h" /* For RC2 ciphers */

#define kPGPMACSize 20	/* pkcs#12 requires 160-bit MAC keys */

/* compute HMAC-SHA */
/* If it doesn't verify, assume it's because of a bad passphrase */
static PGPError
pkcs12VerifyMAC (
    PKICONTEXT		*context,
    PKIPFX		*pfx,
    const unsigned char	*password,
    size_t		passwordLen)
{
    unsigned char	*mackey=NULL;
    unsigned char	mac[kPGPMACSize];
    size_t		mackeylen = kPGPMACSize;
    int			asnerror=0;

    PKIOCTET_STRING *oct=NULL;
    PGPError err=kPGPError_LazyProgrammer;
    PGPHMACContextRef hmacref;

    if(!context||!pfx)
	return err;
    if(!pfx->macData)
	return kPGPError_NoErr;/*nothing to do*/

#ifdef LOUD
    pbe12DumpBytes("HMAC salt:", pfx->macData->macSalt.val,pfx->macData->macSalt.len);
#endif
    pbe12GenerateRandomBits(context->customValue,
	kPGPHashAlgorithm_SHA,
	kPGPPBEIDMACKey,
	pfx->macData->macIterationCount ? PKIGetIntVal(context,pfx->macData->macIterationCount,&asnerror) : 1,
	pfx->macData->macSalt.val,
	pfx->macData->macSalt.len,
	password,
	passwordLen,
	mackeylen,
	&mackey);

    PKIUnpackOCTET_STRING(context,&oct,pfx->authSafes.content->val,pfx->authSafes.content->len,&asnerror);
    if(asnerror)
	goto error;

    err = PGPNewHMACContext(context->customValue,
	kPGPHashAlgorithm_SHA,
	mackey,
	mackeylen,
	&hmacref);
    if (IsPGPError(err))
	goto error;
    err = PGPContinueHMAC(hmacref,oct->val,oct->len);
    if (IsPGPError(err))
	goto error;
    err = PGPFinalizeHMAC(hmacref,mac);
    if (IsPGPError(err))
	goto error;
    err = PGPFreeHMACContext(hmacref);
    if (IsPGPError(err))
	goto error;
    if (pfx->macData->mac.digest.len != kPGPMACSize ||
	memcmp(mac,pfx->macData->mac.digest.val,kPGPMACSize))
    {
	err = kPGPError_BadPassphrase;
	goto error;
    }

    err=kPGPError_NoErr;

error:
    if (mackey)
	PKIFree(context->memMgr,mackey);
    if (oct)
	PKIFreeOCTET_STRING(context,oct);

    return err;
}

static PGPPBEAlgorithm
pkcs12PBEAlgorithm (const unsigned char *oid, size_t oidsize)
{
    if (oidsize == PKIpbeWithSHA1And3_KeyTripleDES_CBC_OID_LEN &&
	!memcmp (oid,PKIpbeWithSHA1And3_KeyTripleDES_CBC_OID,oidsize))
	return kPGPPBEAlgorithm_SHA3DES;
    if (oidsize == PKIpbeWithSHA1And2_KeyTripleDES_CBC_OID_LEN &&
	!memcmp (oid,PKIpbeWithSHA1And2_KeyTripleDES_CBC_OID,oidsize))
	return kPGPPBEAlgorithm_SHADESEDE2;
    if (oidsize == PKIpbeWithSHA1And128BitRC4_OID_LEN &&
	!memcmp (oid, PKIpbeWithSHA1And128BitRC4_OID, oidsize))
	return kPGPPBEAlgorithm_SHARC4_128;
    if (oidsize == PKIpbeWithSHA1And40BitRC4_OID_LEN &&
	!memcmp (oid, PKIpbeWithSHA1And40BitRC4_OID, oidsize))
	return kPGPPBEAlgorithm_SHARC4_40;
    if (oidsize == PKIpbeWithSHA1And128BitRC2_CBC_OID_LEN &&
	!memcmp (oid, PKIpbeWithSHA1And128BitRC2_CBC_OID, oidsize))
	return kPGPPBEAlgorithm_SHARC2_128;
    if (oidsize == PKIpbeWithSHA1And40BitRC2_CBC_OID_LEN &&
	!memcmp (oid, PKIpbeWithSHA1And40BitRC2_CBC_OID, oidsize))
	return kPGPPBEAlgorithm_SHARC2_40;
    return kPGPPBEAlgorithm_Unknown;
}

typedef enum {
    kPGPBagType_Unknown,
    kPGPBagType_KeyBag,
    kPGPBagType_PKCS8ShroudedKeyBag,
    kPGPBagType_CertBag,
    kPGPBagType_CRLBag,
    kPGPBagType_SecretBag,
    kPGPBagType_SafeContentsBag
} PGPBagType;

static PGPBagType
pkcs12BagType (
    const unsigned char	*oid,
    size_t				oidsize)
{
    if(oidsize==PKIkeyBag_OID_LEN && !memcmp(PKIkeyBag_OID,oid,oidsize))
	return kPGPBagType_KeyBag;
    if(oidsize==PKIpkcs_8ShroudedKeyBag_OID_LEN && !memcmp(PKIpkcs_8ShroudedKeyBag_OID,oid,oidsize))
	return kPGPBagType_PKCS8ShroudedKeyBag;
    if(oidsize==PKIcertBag_OID_LEN && !memcmp(PKIcertBag_OID,oid,oidsize))
	return kPGPBagType_CertBag;
    if(oidsize==PKIcrlBag_OID_LEN && !memcmp(PKIcrlBag_OID,oid,oidsize))
	return kPGPBagType_CRLBag;
    if(oidsize==PKIsecretBag_OID_LEN && !memcmp(PKIsecretBag_OID,oid,oidsize))
	return kPGPBagType_SecretBag;
    if(oidsize==PKIsafeContentsBag_OID_LEN && !memcmp(PKIsafeContentsBag_OID,oid,oidsize))
	return kPGPBagType_SafeContentsBag;
    return kPGPBagType_Unknown;
}

#if 0
static unsigned char pbe12OddParity[256] = {
  1,   1,   2,   2,   4,   4,   7,   7,   8,   8,  11,  11,  13,  13,  14,  14, 
 16,  16,  19,  19,  21,  21,  22,  22,  25,  25,  26,  26,  28,  28,  31,  31, 
 32,  32,  35,  35,  37,  37,  38,  38,  41,  41,  42,  42,  44,  44,  47,  47, 
 49,  49,  50,  50,  52,  52,  55,  55,  56,  56,  59,  59,  61,  61,  62,  62, 
 64,  64,  67,  67,  69,  69,  70,  70,  73,  73,  74,  74,  76,  76,  79,  79, 
 81,  81,  82,  82,  84,  84,  87,  87,  88,  88,  91,  91,  93,  93,  94,  94, 
 97,  97,  98,  98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, 110, 
112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, 127, 
128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, 143, 
145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, 158, 
161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, 174, 
176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, 191, 
193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, 206, 
208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, 223, 
224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, 239, 
241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, 254
};

static void pbe12SetOddParity (PGPByte *b)
{
    int i;

    for (i = 0; i < 24; i++)
	b[i] = pbe12OddParity[b[i]];
}
#endif

/*
 * Do a PKCS-12 style decryption of a buffer into a dynamically allocated
 * buffer
 */
static PGPError
pkcs12Decrypt(
    PGPContextRef		context,	/* [IN] */
    const PGPByte		*pass,		/* [IN] */
    PGPSize			passsize,	/* [IN] */
    const PGPByte		*encdata,	/* [IN] data to decrypt */
    PGPSize			encdatasize,	/* [IN] size of data to decrypt
						   (bytes) */
    PKIEncryptionAlgorithmIdentifier *alginfo,	/* [IN] alg info */
    PKICONTEXT			*pki,		/* [IN] asn.1 compiler
						   context */
    PGPByte			**outbuf,	/* [OUT] outptu buffer */
    PGPSize			*outbufsize)	/* [OUT] output size */
{
    PKIpkcs_12PbeParams		*param = NULL;
    int				asnerr = 0, itercount;
    PGPPBEAlgorithm		alg;
    PGPError			err;
    PGPByte			*symkey = NULL, *iv = NULL, pad;
    PGPSize			keysize, blocksize, i;
    PGPHashAlgorithm		hashalg;
    PGPCipherAlgorithm		encalg;
    PGPCBCContextRef		cbcref = NULL;
    PGPSymmetricCipherContextRef	symref = NULL;
    PGPMemoryMgrRef		mem = PGPPeekContextMemoryMgr (context);


    /* determine what algorithm was used to encrypt */
    alg = pkcs12PBEAlgorithm (alginfo->algorithm.val,alginfo->algorithm.len);
    switch (alg)
    {
	case kPGPPBEAlgorithm_SHA3DES:
	    hashalg = kPGPHashAlgorithm_SHA;
	    encalg = kPGPCipherAlgorithm_3DES;
	    keysize = 24;
	    break;
	case kPGPPBEAlgorithm_SHARC2_40:
	    hashalg = kPGPHashAlgorithm_SHA;
	    encalg = (PGPCipherAlgorithm)kPGPCipherAlgorithm_RC2_40;
	    keysize = 40/8;
	    break;
        case kPGPPBEAlgorithm_SHARC2_128:
	    hashalg = kPGPHashAlgorithm_SHA;
	    encalg = (PGPCipherAlgorithm)kPGPCipherAlgorithm_RC2_128;
	    keysize = 128/8;
	    break;
	default:
	    err = kPGPError_BadHashNumber;
	    goto error;
    }

    /* set up encryption context */
    err = PGPNewSymmetricCipherContext (context, encalg, &symref);
    if (IsPGPError (err))
	goto error;
    /* determine key and block sizes */
    err = PGPGetSymmetricCipherSizes (symref, &keysize, &blocksize);
    if (IsPGPError (err))
	goto error;

    /* decode pbe parameters */
    /* this assumes that we aren't using any of the PKCS-5 modes */
    PKIUnpackpkcs_12PbeParams (pki, &param, alginfo->parameters->val,
			       alginfo->parameters->len, &asnerr);
    if (asnerr)
    {
	err = kPGPError_LazyProgrammer;
	goto error;
    }

    itercount = PKIGetIntVal (pki, &param->iterationCount, &asnerr);
    if (asnerr)
    {
	err = kPGPError_LazyProgrammer;
	goto error;
    }

    /* generate the symmetric cipher key */
    err = pbe12GenerateRandomBits (context,
	hashalg,
	kPGPPBEIDEncryptKey,
	itercount,
	param->salt.val,
	param->salt.len,
	pass,
	passsize,
	keysize,
	&symkey);
    if (IsPGPError (err))
	goto error;

    /* generate the IV */
    err = pbe12GenerateRandomBits (context,
	hashalg,
	kPGPPBEIDIV,
	itercount,
	param->salt.val,
	param->salt.len,
	pass,
	passsize,
	blocksize,
	&iv);
    if (IsPGPError (err))
	goto error;

    err = PGPNewCBCContext (symref, &cbcref);
    if (IsPGPError (err))
	goto error;
    symref = NULL; /* dont free this, PGPFreeCBCContext does it */
    err = PGPInitCBC (cbcref, symkey, iv);
    if (IsPGPError (err))
	goto error;
    *outbufsize = encdatasize;
    *outbuf = PGPNewData (mem, *outbufsize, 0);
    err = PGPCBCDecrypt (cbcref, encdata, encdatasize, *outbuf);
    if (IsPGPError (err))
	goto error;
    /* remove padding */
    pad = (*outbuf)[*outbufsize - 1];
    if (pad < 1 || pad > blocksize)
    {
	/* invalid pad size, decryption failed */
	err = kPGPError_LazyProgrammer;
	goto error;
    }
    *outbufsize -= pad;
    /* ensure that we have a valid pad */
    for (i = 0; i < pad; i++)
	if ((*outbuf)[*outbufsize + i] != pad)
	{
	    /* invalid pad, decryption failed */
	    err = kPGPError_LazyProgrammer;
	    goto error;
	}

    err = kPGPError_NoErr;

error:
    if (symref)
	err = PGPFreeSymmetricCipherContext (symref);
    if (cbcref)
	err = PGPFreeCBCContext (cbcref);
    if (param)
	PKIFreepkcs_12PbeParams (pki, param);
    if (symkey)
	PGPFreeData (symkey);
    if (iv)
	PGPFreeData (iv);
    return err;
}


/* processes a PKCS #8 EncryptedPrivateKeyInfo ASN.1 blob */
static PGPError
pkcs8Decrypt (
    PGPContextRef		context,	/* [IN] */
    const PGPByte		*pass,		/* [IN] */
    PGPSize			passsize,	/* [IN] */
    const PGPByte		*encdata,	/* [IN] data to decrypt */
    PGPSize			encdatasize,	/* [IN] size of data to decrypt
						   (bytes) */
    PKICONTEXT			*pki,		/* [IN] asn.1 compiler
						   context */
    PGPByte			**privkey,	/* [OUT] PrivateKeyInfo ASN.1 */
    PGPSize			*privkeysize)	/* [OUT] asn.1 binary size */

⌨️ 快捷键说明

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