mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 03:47:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
289
security/nss/lib/crmf/cmmfchal.c
Normal file
289
security/nss/lib/crmf/cmmfchal.c
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/* -*- Mode: C; tab-width: 8 -*-*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "cmmf.h"
|
||||
#include "cmmfi.h"
|
||||
#include "sechash.h"
|
||||
#include "genname.h"
|
||||
#include "pk11func.h"
|
||||
#include "cert.h"
|
||||
#include "secitem.h"
|
||||
#include "secmod.h"
|
||||
#include "keyhi.h"
|
||||
|
||||
static int
|
||||
cmmf_create_witness_and_challenge(PLArenaPool *poolp,
|
||||
CMMFChallenge *challenge,
|
||||
long inRandom,
|
||||
SECItem *senderDER,
|
||||
SECKEYPublicKey *inPubKey,
|
||||
void *passwdArg)
|
||||
{
|
||||
SECItem *encodedRandNum;
|
||||
SECItem encodedRandStr = { siBuffer, NULL, 0 };
|
||||
SECItem *dummy;
|
||||
unsigned char *randHash, *senderHash, *encChal = NULL;
|
||||
unsigned modulusLen = 0;
|
||||
SECStatus rv = SECFailure;
|
||||
CMMFRand randStr = { { siBuffer, NULL, 0 }, { siBuffer, NULL, 0 } };
|
||||
PK11SlotInfo *slot;
|
||||
PK11SymKey *symKey = NULL;
|
||||
CERTSubjectPublicKeyInfo *spki = NULL;
|
||||
|
||||
encodedRandNum = SEC_ASN1EncodeInteger(poolp, &challenge->randomNumber,
|
||||
inRandom);
|
||||
if (!encodedRandNum) {
|
||||
goto loser;
|
||||
}
|
||||
randHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
|
||||
senderHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH);
|
||||
if (randHash == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
rv = PK11_HashBuf(SEC_OID_SHA1, randHash, encodedRandNum->data,
|
||||
(PRUint32)encodedRandNum->len);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = PK11_HashBuf(SEC_OID_SHA1, senderHash, senderDER->data,
|
||||
(PRUint32)senderDER->len);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
challenge->witness.data = randHash;
|
||||
challenge->witness.len = SHA1_LENGTH;
|
||||
|
||||
randStr.integer = *encodedRandNum;
|
||||
randStr.senderHash.data = senderHash;
|
||||
randStr.senderHash.len = SHA1_LENGTH;
|
||||
dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr,
|
||||
CMMFRandTemplate);
|
||||
if (dummy != &encodedRandStr) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
/* XXXX Now I have to encrypt encodedRandStr and stash it away. */
|
||||
modulusLen = SECKEY_PublicKeyStrength(inPubKey);
|
||||
encChal = PORT_ArenaNewArray(poolp, unsigned char, modulusLen);
|
||||
if (encChal == NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
slot = PK11_GetBestSlotWithAttributes(CKM_RSA_PKCS, CKF_WRAP, 0, passwdArg);
|
||||
if (slot == NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
(void)PK11_ImportPublicKey(slot, inPubKey, PR_FALSE);
|
||||
/* In order to properly encrypt the data, we import as a symmetric
|
||||
* key, and then wrap that key. That in essence encrypts the data.
|
||||
* This is the method recommended in the PK11 world in order
|
||||
* to prevent threading issues as well as breaking any other semantics
|
||||
* the PK11 libraries depend on.
|
||||
*/
|
||||
symKey = PK11_ImportSymKey(slot, CKM_RSA_PKCS, PK11_OriginGenerated,
|
||||
CKA_VALUE, &encodedRandStr, passwdArg);
|
||||
if (symKey == NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
challenge->challenge.data = encChal;
|
||||
challenge->challenge.len = modulusLen;
|
||||
rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey,
|
||||
&challenge->challenge);
|
||||
PK11_FreeSlot(slot);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
rv = SECITEM_CopyItem(poolp, &challenge->senderDER, senderDER);
|
||||
crmf_get_public_value(inPubKey, &challenge->key);
|
||||
/* Fall through */
|
||||
loser:
|
||||
if (spki != NULL) {
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
}
|
||||
if (encodedRandStr.data != NULL) {
|
||||
PORT_Free(encodedRandStr.data);
|
||||
}
|
||||
if (encodedRandNum != NULL) {
|
||||
SECITEM_FreeItem(encodedRandNum, PR_TRUE);
|
||||
}
|
||||
if (symKey != NULL) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
cmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent,
|
||||
long inRandom,
|
||||
SECItem *senderDER,
|
||||
SECKEYPublicKey *inPubKey,
|
||||
void *passwdArg)
|
||||
{
|
||||
SECOidData *oidData;
|
||||
CMMFChallenge *challenge;
|
||||
SECAlgorithmID *algId;
|
||||
PLArenaPool *poolp;
|
||||
SECStatus rv;
|
||||
|
||||
oidData = SECOID_FindOIDByTag(SEC_OID_SHA1);
|
||||
if (oidData == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
poolp = challContent->poolp;
|
||||
challenge = PORT_ArenaZNew(poolp, CMMFChallenge);
|
||||
if (challenge == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
algId = challenge->owf = PORT_ArenaZNew(poolp, SECAlgorithmID);
|
||||
if (algId == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = SECITEM_CopyItem(poolp, &algId->algorithm, &oidData->oid);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = cmmf_create_witness_and_challenge(poolp, challenge, inRandom,
|
||||
senderDER, inPubKey, passwdArg);
|
||||
challContent->challenges[0] = (rv == SECSuccess) ? challenge : NULL;
|
||||
challContent->numChallenges++;
|
||||
return rv;
|
||||
}
|
||||
|
||||
CMMFPOPODecKeyChallContent *
|
||||
CMMF_CreatePOPODecKeyChallContent(void)
|
||||
{
|
||||
PLArenaPool *poolp;
|
||||
CMMFPOPODecKeyChallContent *challContent;
|
||||
|
||||
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
|
||||
if (poolp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
challContent = PORT_ArenaZNew(poolp, CMMFPOPODecKeyChallContent);
|
||||
if (challContent == NULL) {
|
||||
PORT_FreeArena(poolp, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
challContent->poolp = poolp;
|
||||
return challContent;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CMMF_POPODecKeyChallContentSetNextChallenge(CMMFPOPODecKeyChallContent *inDecKeyChall,
|
||||
long inRandom,
|
||||
CERTGeneralName *inSender,
|
||||
SECKEYPublicKey *inPubKey,
|
||||
void *passwdArg)
|
||||
{
|
||||
CMMFChallenge *curChallenge;
|
||||
PLArenaPool *genNamePool = NULL, *poolp;
|
||||
SECStatus rv;
|
||||
SECItem *genNameDER;
|
||||
void *mark;
|
||||
|
||||
PORT_Assert(inDecKeyChall != NULL &&
|
||||
inSender != NULL &&
|
||||
inPubKey != NULL);
|
||||
|
||||
if (inDecKeyChall == NULL ||
|
||||
inSender == NULL || inPubKey == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
poolp = inDecKeyChall->poolp;
|
||||
mark = PORT_ArenaMark(poolp);
|
||||
|
||||
genNamePool = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
|
||||
genNameDER = CERT_EncodeGeneralName(inSender, NULL, genNamePool);
|
||||
if (genNameDER == NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
if (inDecKeyChall->challenges == NULL) {
|
||||
inDecKeyChall->challenges =
|
||||
PORT_ArenaZNewArray(poolp, CMMFChallenge *, (CMMF_MAX_CHALLENGES + 1));
|
||||
inDecKeyChall->numAllocated = CMMF_MAX_CHALLENGES;
|
||||
}
|
||||
|
||||
if (inDecKeyChall->numChallenges >= inDecKeyChall->numAllocated) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (inDecKeyChall->numChallenges == 0) {
|
||||
rv = cmmf_create_first_challenge(inDecKeyChall, inRandom,
|
||||
genNameDER, inPubKey, passwdArg);
|
||||
} else {
|
||||
curChallenge = PORT_ArenaZNew(poolp, CMMFChallenge);
|
||||
if (curChallenge == NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
rv = cmmf_create_witness_and_challenge(poolp, curChallenge, inRandom,
|
||||
genNameDER, inPubKey,
|
||||
passwdArg);
|
||||
if (rv == SECSuccess) {
|
||||
inDecKeyChall->challenges[inDecKeyChall->numChallenges] =
|
||||
curChallenge;
|
||||
inDecKeyChall->numChallenges++;
|
||||
}
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_ArenaUnmark(poolp, mark);
|
||||
PORT_FreeArena(genNamePool, PR_FALSE);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_ArenaRelease(poolp, mark);
|
||||
if (genNamePool != NULL) {
|
||||
PORT_FreeArena(genNamePool, PR_FALSE);
|
||||
}
|
||||
PORT_Assert(rv != SECSuccess);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp)
|
||||
{
|
||||
PORT_Assert(inDecKeyResp != NULL);
|
||||
if (inDecKeyResp != NULL && inDecKeyResp->poolp != NULL) {
|
||||
PORT_FreeArena(inDecKeyResp->poolp, PR_FALSE);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
int
|
||||
CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont)
|
||||
{
|
||||
int numResponses = 0;
|
||||
|
||||
PORT_Assert(inRespCont != NULL);
|
||||
if (inRespCont == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (inRespCont->responses[numResponses] != NULL) {
|
||||
numResponses++;
|
||||
}
|
||||
return numResponses;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CMMF_POPODecKeyRespContentGetResponse(CMMFPOPODecKeyRespContent *inRespCont,
|
||||
int inIndex,
|
||||
long *inDest)
|
||||
{
|
||||
PORT_Assert(inRespCont != NULL);
|
||||
|
||||
if (inRespCont == NULL || inIndex < 0 ||
|
||||
inIndex >= CMMF_POPODecKeyRespContentGetNumResponses(inRespCont)) {
|
||||
return SECFailure;
|
||||
}
|
||||
*inDest = DER_GetInteger(inRespCont->responses[inIndex]);
|
||||
return (*inDest == -1) ? SECFailure : SECSuccess;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue