зеркало из https://github.com/mozilla/gecko-dev.git
fix for #92940, PKCS#12 broken in FIPS mode. Force keygen to occur on token, added new PKCS#11 mechanisms to handle PKCS#12 integrity key generation.
This commit is contained in:
Родитель
bec1d3cddc
Коммит
9d98643622
|
@ -455,6 +455,17 @@ void PK11_SetFortezzaHack(PK11SymKey *symKey) ;
|
|||
/**********************************************************************
|
||||
* PBE functions
|
||||
**********************************************************************/
|
||||
|
||||
/* This function creates PBE parameters from the given inputs. The result
|
||||
* can be used to create a password integrity key for PKCS#12, by sending
|
||||
* the return value to PK11_KeyGen along with the appropriate mechanism.
|
||||
*/
|
||||
SECItem *
|
||||
PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations);
|
||||
|
||||
/* free params created above (can be called after keygen is done */
|
||||
void PK11_DestroyPBEParams(SECItem *params);
|
||||
|
||||
SECAlgorithmID *
|
||||
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt);
|
||||
PK11SymKey *
|
||||
|
|
|
@ -1207,7 +1207,7 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
|
|||
int keySize, SECItem *keyid, PRBool isToken, void *wincx)
|
||||
{
|
||||
PK11SymKey *symKey;
|
||||
CK_ATTRIBUTE genTemplate[4];
|
||||
CK_ATTRIBUTE genTemplate[5];
|
||||
CK_ATTRIBUTE *attrs = genTemplate;
|
||||
int count = sizeof(genTemplate)/sizeof(genTemplate[0]);
|
||||
CK_SESSION_HANDLE session;
|
||||
|
@ -1243,6 +1243,8 @@ PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param,
|
|||
PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
|
||||
}
|
||||
|
||||
PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(cktrue)); attrs++;
|
||||
|
||||
count = attrs - genTemplate;
|
||||
PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE));
|
||||
|
||||
|
@ -4053,6 +4055,49 @@ PK11_DigestFinal(PK11Context *context,unsigned char *data,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void
|
||||
pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params)
|
||||
{
|
||||
if (pbe_params) {
|
||||
if (pbe_params->pPassword)
|
||||
PORT_ZFree(pbe_params->pPassword, PR_FALSE);
|
||||
if (pbe_params->pSalt)
|
||||
PORT_ZFree(pbe_params->pSalt, PR_FALSE);
|
||||
PORT_ZFree(pbe_params, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
SECItem *
|
||||
PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
|
||||
{
|
||||
CK_PBE_PARAMS *pbe_params = NULL;
|
||||
SECItem *paramRV = NULL;
|
||||
pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS));
|
||||
pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len);
|
||||
if (pbe_params->pPassword != NULL) {
|
||||
PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
|
||||
pbe_params->ulPasswordLen = pwd->len;
|
||||
} else goto loser;
|
||||
pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
|
||||
if (pbe_params->pSalt != NULL) {
|
||||
PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len);
|
||||
pbe_params->ulSaltLen = salt->len;
|
||||
} else goto loser;
|
||||
pbe_params->ulIteration = (CK_ULONG)iterations;
|
||||
paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS));
|
||||
paramRV->data = (unsigned char *)pbe_params;
|
||||
return paramRV;
|
||||
loser:
|
||||
pk11_destroy_ck_pbe_params(pbe_params);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
PK11_DestroyPBEParams(SECItem *params)
|
||||
{
|
||||
pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data);
|
||||
}
|
||||
|
||||
SECAlgorithmID *
|
||||
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
|
||||
{
|
||||
|
|
|
@ -2829,6 +2829,9 @@ PK11_GetKeyGen(CK_MECHANISM_TYPE type)
|
|||
return CKM_GENERIC_SECRET_KEY_GEN;
|
||||
case CKM_PBE_MD2_DES_CBC:
|
||||
case CKM_PBE_MD5_DES_CBC:
|
||||
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
|
||||
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
|
||||
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
|
||||
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
|
||||
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
|
||||
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
|
||||
|
|
|
@ -1152,14 +1152,16 @@ static SECStatus
|
|||
sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
PBEBitGenContext *pbeCtxt = NULL;
|
||||
SECItem *hmacKey = NULL, hmacRes;
|
||||
SECItem hmacRes;
|
||||
unsigned char buf[IN_BUF_LEN];
|
||||
unsigned int bufLen;
|
||||
int iteration;
|
||||
PK11Context *pk11cx;
|
||||
SECOidTag algtag;
|
||||
SECItem ignore = {0};
|
||||
PK11SymKey *symKey;
|
||||
SECItem *params;
|
||||
SECOidTag algtag;
|
||||
CK_MECHANISM_TYPE integrityMech;
|
||||
|
||||
if(!p12dcx || p12dcx->error) {
|
||||
return SECFailure;
|
||||
|
@ -1171,28 +1173,28 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx)
|
|||
} else {
|
||||
iteration = 1;
|
||||
}
|
||||
pbeCtxt = PBE_CreateContext(SECOID_GetAlgorithmTag(
|
||||
&p12dcx->macData.safeMac.digestAlgorithm),
|
||||
pbeBitGenIntegrityKey, p12dcx->pwitem,
|
||||
&p12dcx->macData.macSalt, 160, iteration);
|
||||
if(!pbeCtxt) {
|
||||
return SECFailure;
|
||||
}
|
||||
hmacKey = PBE_GenerateBits(pbeCtxt);
|
||||
PBE_DestroyContext(pbeCtxt);
|
||||
pbeCtxt = NULL;
|
||||
if(!hmacKey) {
|
||||
return SECFailure;
|
||||
|
||||
params = PK11_CreatePBEParams(&p12dcx->macData.macSalt, p12dcx->pwitem,
|
||||
iteration);
|
||||
|
||||
algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
|
||||
switch (algtag) {
|
||||
case SEC_OID_SHA1:
|
||||
integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
|
||||
case SEC_OID_MD5:
|
||||
integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
|
||||
case SEC_OID_MD2:
|
||||
integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
|
||||
default:
|
||||
goto loser;
|
||||
}
|
||||
|
||||
symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
|
||||
PK11_DestroyPBEParams(params);
|
||||
if (!symKey) goto loser;
|
||||
/* init hmac */
|
||||
algtag = SECOID_GetAlgorithmTag(&p12dcx->macData.safeMac.digestAlgorithm);
|
||||
pk11cx = PK11_CreateContextByRawKey(NULL,
|
||||
sec_pkcs12_algtag_to_mech(algtag),
|
||||
PK11_OriginDerive, CKA_SIGN,
|
||||
hmacKey, &ignore, NULL);
|
||||
SECITEM_ZfreeItem(hmacKey, PR_TRUE);
|
||||
hmacKey = NULL;
|
||||
pk11cx = PK11_CreateContextBySymKey(sec_pkcs12_algtag_to_mech(algtag),
|
||||
CKA_SIGN, symKey, &ignore);
|
||||
if(!pk11cx) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return SECFailure;
|
||||
|
@ -1247,10 +1249,6 @@ loser:
|
|||
PK11_DestroyContext(pk11cx, PR_TRUE);
|
||||
}
|
||||
|
||||
if(hmacKey) {
|
||||
SECITEM_ZfreeItem(hmacKey, PR_TRUE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -1660,9 +1660,11 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
|
|||
|
||||
/* init password pased integrity mode */
|
||||
if(p12exp->integrityEnabled) {
|
||||
SECItem pwd = {siBuffer,NULL, 0}, *key;
|
||||
SECItem pwd = {siBuffer,NULL, 0};
|
||||
SECItem *salt = sec_pkcs12_generate_salt();
|
||||
PBEBitGenContext *pbeCtxt = NULL;
|
||||
PK11SymKey *symKey;
|
||||
SECItem *params;
|
||||
CK_MECHANISM_TYPE integrityMech;
|
||||
|
||||
/* zero out macData and set values */
|
||||
PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData));
|
||||
|
@ -1676,7 +1678,6 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
|
|||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
}
|
||||
SECITEM_ZfreeItem(salt, PR_TRUE);
|
||||
|
||||
/* generate HMAC key */
|
||||
if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd,
|
||||
|
@ -1684,25 +1685,32 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
|
|||
PR_TRUE, PR_TRUE)) {
|
||||
goto loser;
|
||||
}
|
||||
pbeCtxt = PBE_CreateContext(p12exp->integrityInfo.pwdInfo.algorithm,
|
||||
pbeBitGenIntegrityKey, &pwd,
|
||||
&(p12enc->mac.macSalt), 160, 1);
|
||||
|
||||
params = PK11_CreatePBEParams(salt, &pwd, 1);
|
||||
SECITEM_ZfreeItem(salt, PR_TRUE);
|
||||
SECITEM_ZfreeItem(&pwd, PR_FALSE);
|
||||
if(!pbeCtxt) {
|
||||
|
||||
switch (p12exp->integrityInfo.pwdInfo.algorithm) {
|
||||
case SEC_OID_SHA1:
|
||||
integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
|
||||
case SEC_OID_MD5:
|
||||
integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; break;
|
||||
case SEC_OID_MD2:
|
||||
integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break;
|
||||
default:
|
||||
goto loser;
|
||||
}
|
||||
key = PBE_GenerateBits(pbeCtxt);
|
||||
PBE_DestroyContext(pbeCtxt);
|
||||
if(!key) {
|
||||
|
||||
symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
|
||||
PK11_DestroyPBEParams(params);
|
||||
if(!symKey) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* initialize hmac */
|
||||
p12enc->hmacCx = PK11_CreateContextByRawKey(NULL,
|
||||
p12enc->hmacCx = PK11_CreateContextBySymKey(
|
||||
sec_pkcs12_algtag_to_mech(p12exp->integrityInfo.pwdInfo.algorithm),
|
||||
PK11_OriginDerive, CKA_SIGN,
|
||||
key, &ignore, NULL);
|
||||
SECITEM_ZfreeItem(key, PR_TRUE);
|
||||
CKA_SIGN, symKey, &ignore);
|
||||
if(!p12enc->hmacCx) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto loser;
|
||||
|
|
|
@ -406,6 +406,9 @@ static struct mechanismList mechanisms[] = {
|
|||
{CKM_PBE_SHA1_RC2_128_CBC, {128,128, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_PBE_SHA1_RC4_40, {40,40, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_PBE_SHA1_RC4_128, {128,128, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
|
||||
};
|
||||
static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
|
||||
/* load up our token database */
|
||||
|
|
|
@ -2832,6 +2832,40 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
|
|||
**************************** Key Functions: ************************
|
||||
*/
|
||||
|
||||
CK_RV
|
||||
pk11_pbe_hmac_key_gen(CK_MECHANISM_PTR pMechanism, char *buf,
|
||||
unsigned long *len, PRBool faultyPBE3DES)
|
||||
{
|
||||
PBEBitGenContext *pbeCx;
|
||||
SECItem pwd, salt, *key;
|
||||
SECOidTag hashAlg;
|
||||
unsigned long keylenbits;
|
||||
CK_PBE_PARAMS *pbe_params = NULL;
|
||||
pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
|
||||
pwd.data = (unsigned char *)pbe_params->pPassword;
|
||||
pwd.len = (unsigned int)pbe_params->ulPasswordLen;
|
||||
salt.data = (unsigned char *)pbe_params->pSalt;
|
||||
salt.len = (unsigned int)pbe_params->ulSaltLen;
|
||||
switch (pMechanism->mechanism) {
|
||||
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
|
||||
hashAlg = SEC_OID_SHA1; keylenbits = 160; break;
|
||||
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
|
||||
hashAlg = SEC_OID_MD5; keylenbits = 128; break;
|
||||
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
|
||||
hashAlg = SEC_OID_MD2; keylenbits = 128; break;
|
||||
default:
|
||||
return CKR_MECHANISM_INVALID;
|
||||
}
|
||||
pbeCx = PBE_CreateContext(hashAlg, pbeBitGenIntegrityKey, &pwd,
|
||||
&salt, keylenbits, pbe_params->ulIteration);
|
||||
key = PBE_GenerateBits(pbeCx);
|
||||
PORT_Memcpy(buf, key->data, key->len);
|
||||
*len = key->len;
|
||||
PBE_DestroyContext(pbeCx);
|
||||
SECITEM_ZfreeItem(key, PR_TRUE);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* generate a password based encryption key. This code uses
|
||||
* PKCS5 to do the work. Note that it calls PBE_PK11ParamToAlgid, which is
|
||||
|
@ -3041,7 +3075,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
|
|||
int i;
|
||||
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
|
||||
char buf[MAX_KEY_LEN];
|
||||
enum {pk11_pbe, pk11_ssl, pk11_bulk} key_gen_type;
|
||||
enum {pk11_pbe, pk11_pbe_hmac, pk11_ssl, pk11_bulk} key_gen_type;
|
||||
SECOidTag algtag = SEC_OID_UNKNOWN;
|
||||
SSL3RSAPreMasterSecret *rsa_pms;
|
||||
CK_VERSION *version;
|
||||
|
@ -3106,6 +3140,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
|
|||
break;
|
||||
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
|
||||
faultyPBE3DES = PR_TRUE;
|
||||
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
|
||||
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
|
||||
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
|
||||
key_gen_type = pk11_pbe_hmac;
|
||||
break;
|
||||
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
|
||||
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
|
||||
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
|
||||
|
@ -3142,6 +3181,10 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
|
|||
* now to the actual key gen.
|
||||
*/
|
||||
switch (key_gen_type) {
|
||||
case pk11_pbe_hmac:
|
||||
crv = pk11_pbe_hmac_key_gen(pMechanism, buf, &key_length,
|
||||
faultyPBE3DES);
|
||||
break;
|
||||
case pk11_pbe:
|
||||
crv = pk11_pbe_key_gen(algtag, pMechanism, buf, &key_length,
|
||||
faultyPBE3DES);
|
||||
|
|
|
@ -1112,6 +1112,9 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
|
|||
#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
|
||||
#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L
|
||||
#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL
|
||||
#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL
|
||||
#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
|
||||
#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
|
||||
#define CKM_TLS_PRF_GENERAL 0x80000373L
|
||||
|
|
Загрузка…
Ссылка в новой задаче