mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-16 04:20:32 +01:00
98d377b37b
bug920719, bug1026148, bug1028647, bug963150, bug1030486, bug1025729, bug836658, bug1028582, bug1038728, bug1038526, bug1042634, bug1047210, bug1043891, bug1043108, bug1046735, bug1043082, bug1036735, bug1046718, bug1050107, bug1054625, bug1057465, bug1057476, bug1041326, bug1058933, bug1064636, bug1057161, bug1078669, bug1049435, bug1070493, bug1083360, bug1028764, bug1065990, bug1073330, bug1064670, bug1094650
979 lines
25 KiB
C
979 lines
25 KiB
C
/* -*- 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 "secitem.h"
|
|
#include "keyhi.h"
|
|
#include "secder.h"
|
|
|
|
CRMFEncryptedKeyChoice
|
|
CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey)
|
|
{
|
|
PORT_Assert(inEncrKey != NULL);
|
|
if (inEncrKey == NULL) {
|
|
return crmfNoEncryptedKeyChoice;
|
|
}
|
|
return inEncrKey->encKeyChoice;
|
|
}
|
|
|
|
CRMFEncryptedValue*
|
|
CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey)
|
|
{
|
|
CRMFEncryptedValue *newEncrValue = NULL;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inEncrKey != NULL);
|
|
if (inEncrKey == NULL ||
|
|
CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) {
|
|
goto loser;
|
|
}
|
|
newEncrValue = PORT_ZNew(CRMFEncryptedValue);
|
|
if (newEncrValue == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = crmf_copy_encryptedvalue(NULL, &inEncrKey->value.encryptedValue,
|
|
newEncrValue);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newEncrValue;
|
|
loser:
|
|
if (newEncrValue != NULL) {
|
|
CRMF_DestroyEncryptedValue(newEncrValue);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static SECItem*
|
|
crmf_get_encvalue_bitstring(SECItem *srcItem)
|
|
{
|
|
SECItem *newItem = NULL;
|
|
SECStatus rv;
|
|
|
|
if (srcItem->data == NULL) {
|
|
return NULL;
|
|
}
|
|
newItem = PORT_ZNew(SECItem);
|
|
if (newItem == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = crmf_make_bitstring_copy(NULL, newItem, srcItem);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newItem;
|
|
loser:
|
|
if (newItem != NULL) {
|
|
SECITEM_FreeItem(newItem, PR_TRUE);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue)
|
|
{
|
|
if (inEncValue == NULL) {
|
|
return NULL;
|
|
}
|
|
return crmf_get_encvalue_bitstring(&inEncValue->encSymmKey);
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue)
|
|
{
|
|
if (inEncrValue == NULL || inEncrValue->encValue.data == NULL) {
|
|
return NULL;
|
|
}
|
|
return crmf_get_encvalue_bitstring(&inEncrValue->encValue);
|
|
}
|
|
|
|
static SECAlgorithmID*
|
|
crmf_get_encvalue_algid(SECAlgorithmID *srcAlg)
|
|
{
|
|
SECStatus rv;
|
|
SECAlgorithmID *newAlgID;
|
|
|
|
if (srcAlg == NULL) {
|
|
return NULL;
|
|
}
|
|
rv = crmf_copy_encryptedvalue_secalg(NULL, srcAlg, &newAlgID);
|
|
if (rv != SECSuccess) {
|
|
return NULL;
|
|
}
|
|
return newAlgID;
|
|
}
|
|
|
|
SECAlgorithmID*
|
|
CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue)
|
|
{
|
|
if (inEncValue == NULL) {
|
|
return NULL;
|
|
}
|
|
return crmf_get_encvalue_algid(inEncValue->intendedAlg);
|
|
}
|
|
|
|
SECAlgorithmID*
|
|
CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue)
|
|
{
|
|
if (inEncValue == NULL) {
|
|
return NULL;
|
|
}
|
|
return crmf_get_encvalue_algid(inEncValue->keyAlg);
|
|
}
|
|
|
|
SECAlgorithmID*
|
|
CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue)
|
|
{
|
|
if (inEncValue == NULL) {
|
|
return NULL;
|
|
}
|
|
return crmf_get_encvalue_algid(inEncValue->symmAlg);
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue)
|
|
{
|
|
if (inEncValue == NULL || inEncValue->valueHint.data == NULL) {
|
|
return NULL;
|
|
}
|
|
return SECITEM_DupItem(&inEncValue->valueHint);
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt,
|
|
PRBool *destVal)
|
|
{
|
|
if (inOpt == NULL || destVal == NULL ||
|
|
CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey){
|
|
return SECFailure;
|
|
}
|
|
*destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse)
|
|
? PR_FALSE:
|
|
PR_TRUE;
|
|
return SECSuccess;
|
|
}
|
|
|
|
CRMFEncryptedKey*
|
|
CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts)
|
|
{
|
|
CRMFEncryptedKey *newEncrKey = NULL;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inOpts != NULL);
|
|
if (inOpts == NULL ||
|
|
CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey){
|
|
return NULL;
|
|
}
|
|
newEncrKey = PORT_ZNew(CRMFEncryptedKey);
|
|
if (newEncrKey == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = crmf_copy_encryptedkey(NULL, &inOpts->option.encryptedKey,
|
|
newEncrKey);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newEncrKey;
|
|
loser:
|
|
if (newEncrKey != NULL) {
|
|
CRMF_DestroyEncryptedKey(newEncrKey);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions)
|
|
{
|
|
if (inOptions == NULL ||
|
|
CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters ||
|
|
inOptions->option.keyGenParameters.data == NULL) {
|
|
return NULL;
|
|
}
|
|
return SECITEM_DupItem(&inOptions->option.keyGenParameters);
|
|
}
|
|
|
|
CRMFPKIArchiveOptionsType
|
|
CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions)
|
|
{
|
|
PORT_Assert (inOptions != NULL);
|
|
if (inOptions == NULL) {
|
|
return crmfNoArchiveOptions;
|
|
}
|
|
return inOptions->archOption;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_extract_long_from_item(SECItem *intItem, long *destLong)
|
|
{
|
|
*destLong = DER_GetInteger(intItem);
|
|
return (*destLong == -1) ? SECFailure : SECSuccess;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey *inKey,
|
|
CRMFSubseqMessOptions *destOpt)
|
|
{
|
|
long value;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inKey != NULL);
|
|
if (inKey == NULL ||
|
|
inKey->messageChoice != crmfSubsequentMessage) {
|
|
return SECFailure;
|
|
}
|
|
rv = crmf_extract_long_from_item(&inKey->message.subsequentMessage,&value);
|
|
if (rv != SECSuccess) {
|
|
return SECFailure;
|
|
}
|
|
switch (value) {
|
|
case 0:
|
|
*destOpt = crmfEncrCert;
|
|
break;
|
|
case 1:
|
|
*destOpt = crmfChallengeResp;
|
|
break;
|
|
default:
|
|
rv = SECFailure;
|
|
}
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
return SECSuccess;
|
|
}
|
|
|
|
CRMFPOPOPrivKeyChoice
|
|
CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inPrivKey)
|
|
{
|
|
PORT_Assert(inPrivKey != NULL);
|
|
if (inPrivKey != NULL) {
|
|
return inPrivKey->messageChoice;
|
|
}
|
|
return crmfNoMessage;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey, SECItem *destMAC)
|
|
{
|
|
PORT_Assert(inKey != NULL);
|
|
if (inKey == NULL || inKey->message.dhMAC.data == NULL) {
|
|
return SECFailure;
|
|
}
|
|
return crmf_make_bitstring_copy(NULL, destMAC, &inKey->message.dhMAC);
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey,
|
|
SECItem *destString)
|
|
{
|
|
PORT_Assert(inKey != NULL);
|
|
if (inKey == NULL ||
|
|
inKey->messageChoice != crmfThisMessage) {
|
|
return SECFailure;
|
|
}
|
|
|
|
return crmf_make_bitstring_copy(NULL, destString,
|
|
&inKey->message.thisMessage);
|
|
}
|
|
|
|
SECAlgorithmID*
|
|
CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey)
|
|
{
|
|
SECAlgorithmID *newAlgId = NULL;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inSignKey != NULL);
|
|
if (inSignKey == NULL) {
|
|
return NULL;
|
|
}
|
|
newAlgId = PORT_ZNew(SECAlgorithmID);
|
|
if (newAlgId == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = SECOID_CopyAlgorithmID(NULL, newAlgId,
|
|
inSignKey->algorithmIdentifier);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newAlgId;
|
|
|
|
loser:
|
|
if (newAlgId != NULL) {
|
|
SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey)
|
|
{
|
|
PORT_Assert(inSignKey != NULL);
|
|
if (inSignKey == NULL || inSignKey->derInput.data == NULL) {
|
|
return NULL;
|
|
}
|
|
return SECITEM_DupItem(&inSignKey->derInput);
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey)
|
|
{
|
|
SECItem *newSig = NULL;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inSignKey != NULL);
|
|
if (inSignKey == NULL) {
|
|
return NULL;
|
|
}
|
|
newSig = PORT_ZNew(SECItem);
|
|
if (newSig == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = crmf_make_bitstring_copy(NULL, newSig, &inSignKey->signature);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newSig;
|
|
loser:
|
|
if (newSig != NULL) {
|
|
SECITEM_FreeItem(newSig, PR_TRUE);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_copy_poposigningkey(PLArenaPool *poolp,
|
|
CRMFPOPOSigningKey *inPopoSignKey,
|
|
CRMFPOPOSigningKey *destPopoSignKey)
|
|
{
|
|
SECStatus rv;
|
|
|
|
/* We don't support use of the POPOSigningKeyInput, so we'll only
|
|
* store away the DER encoding.
|
|
*/
|
|
if (inPopoSignKey->derInput.data != NULL) {
|
|
rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput,
|
|
&inPopoSignKey->derInput);
|
|
}
|
|
destPopoSignKey->algorithmIdentifier = (poolp == NULL) ?
|
|
PORT_ZNew(SECAlgorithmID) :
|
|
PORT_ArenaZNew(poolp, SECAlgorithmID);
|
|
|
|
if (destPopoSignKey->algorithmIdentifier == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = SECOID_CopyAlgorithmID(poolp, destPopoSignKey->algorithmIdentifier,
|
|
inPopoSignKey->algorithmIdentifier);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
|
|
rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature,
|
|
&inPopoSignKey->signature);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return SECSuccess;
|
|
loser:
|
|
if (poolp == NULL) {
|
|
CRMF_DestroyPOPOSigningKey(destPopoSignKey);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_copy_popoprivkey(PLArenaPool *poolp,
|
|
CRMFPOPOPrivKey *srcPrivKey,
|
|
CRMFPOPOPrivKey *destPrivKey)
|
|
{
|
|
SECStatus rv;
|
|
|
|
destPrivKey->messageChoice = srcPrivKey->messageChoice;
|
|
switch (destPrivKey->messageChoice) {
|
|
case crmfThisMessage:
|
|
case crmfDHMAC:
|
|
/* I've got a union, so taking the address of one, will also give
|
|
* me a pointer to the other (eg, message.dhMAC)
|
|
*/
|
|
rv = crmf_make_bitstring_copy(poolp, &destPrivKey->message.thisMessage,
|
|
&srcPrivKey->message.thisMessage);
|
|
break;
|
|
case crmfSubsequentMessage:
|
|
rv = SECITEM_CopyItem(poolp, &destPrivKey->message.subsequentMessage,
|
|
&srcPrivKey->message.subsequentMessage);
|
|
break;
|
|
default:
|
|
rv = SECFailure;
|
|
}
|
|
|
|
if (rv != SECSuccess && poolp == NULL) {
|
|
CRMF_DestroyPOPOPrivKey(destPrivKey);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
static CRMFProofOfPossession*
|
|
crmf_copy_pop(PLArenaPool *poolp, CRMFProofOfPossession *srcPOP)
|
|
{
|
|
CRMFProofOfPossession *newPOP;
|
|
SECStatus rv;
|
|
|
|
/*
|
|
* Proof Of Possession structures are always part of the Request
|
|
* message, so there will always be an arena for allocating memory.
|
|
*/
|
|
if (poolp == NULL) {
|
|
return NULL;
|
|
}
|
|
newPOP = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
|
|
if (newPOP == NULL) {
|
|
return NULL;
|
|
}
|
|
switch (srcPOP->popUsed) {
|
|
case crmfRAVerified:
|
|
newPOP->popChoice.raVerified.data = NULL;
|
|
newPOP->popChoice.raVerified.len = 0;
|
|
break;
|
|
case crmfSignature:
|
|
rv = crmf_copy_poposigningkey(poolp, &srcPOP->popChoice.signature,
|
|
&newPOP->popChoice.signature);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
break;
|
|
case crmfKeyEncipherment:
|
|
case crmfKeyAgreement:
|
|
/* We've got a union, so a pointer to one, is a pointer to the
|
|
* other one.
|
|
*/
|
|
rv = crmf_copy_popoprivkey(poolp, &srcPOP->popChoice.keyEncipherment,
|
|
&newPOP->popChoice.keyEncipherment);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
break;
|
|
default:
|
|
goto loser;
|
|
}
|
|
newPOP->popUsed = srcPOP->popUsed;
|
|
return newPOP;
|
|
|
|
loser:
|
|
return NULL;
|
|
}
|
|
|
|
static CRMFCertReqMsg*
|
|
crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg)
|
|
{
|
|
CRMFCertReqMsg *newReqMsg;
|
|
PLArenaPool *poolp;
|
|
|
|
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
|
|
if (poolp == NULL) {
|
|
return NULL;
|
|
}
|
|
newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
|
|
if (newReqMsg == NULL) {
|
|
PORT_FreeArena(poolp, PR_TRUE);
|
|
return NULL;
|
|
}
|
|
|
|
newReqMsg->poolp = poolp;
|
|
newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq);
|
|
if (newReqMsg->certReq == NULL) {
|
|
goto loser;
|
|
}
|
|
newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop);
|
|
if (newReqMsg->pop == NULL) {
|
|
goto loser;
|
|
}
|
|
/* None of my set/get routines operate on the regInfo field, so
|
|
* for now, that won't get copied over.
|
|
*/
|
|
return newReqMsg;
|
|
|
|
loser:
|
|
if (newReqMsg != NULL) {
|
|
CRMF_DestroyCertReqMsg(newReqMsg);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CRMFCertReqMsg*
|
|
CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
|
|
int index)
|
|
{
|
|
int numMsgs;
|
|
|
|
PORT_Assert(inReqMsgs != NULL && index >= 0);
|
|
if (inReqMsgs == NULL) {
|
|
return NULL;
|
|
}
|
|
numMsgs = CRMF_CertReqMessagesGetNumMessages(inReqMsgs);
|
|
if (index < 0 || index >= numMsgs) {
|
|
return NULL;
|
|
}
|
|
return crmf_copy_cert_req_msg(inReqMsgs->messages[index]);
|
|
}
|
|
|
|
int
|
|
CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs)
|
|
{
|
|
int numMessages = 0;
|
|
|
|
PORT_Assert(inCertReqMsgs != NULL);
|
|
if (inCertReqMsgs == NULL) {
|
|
return 0;
|
|
}
|
|
while (inCertReqMsgs->messages[numMessages] != NULL) {
|
|
numMessages++;
|
|
}
|
|
return numMessages;
|
|
}
|
|
|
|
CRMFCertRequest*
|
|
CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg)
|
|
{
|
|
PLArenaPool *poolp = NULL;
|
|
CRMFCertRequest *newCertReq = NULL;
|
|
|
|
PORT_Assert(inCertReqMsg != NULL);
|
|
|
|
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
|
|
if (poolp == NULL) {
|
|
goto loser;
|
|
}
|
|
newCertReq = crmf_copy_cert_request(poolp, inCertReqMsg->certReq);
|
|
if (newCertReq == NULL) {
|
|
goto loser;
|
|
}
|
|
newCertReq->poolp = poolp;
|
|
return newCertReq;
|
|
loser:
|
|
if (poolp != NULL) {
|
|
PORT_FreeArena(poolp, PR_FALSE);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg, long *destID)
|
|
{
|
|
PORT_Assert(inCertReqMsg != NULL && destID != NULL);
|
|
if (inCertReqMsg == NULL || inCertReqMsg->certReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId,
|
|
destID);
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFPOPOPrivKey **destKey)
|
|
{
|
|
PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
|
|
if (inCertReqMsg == NULL || destKey == NULL ||
|
|
CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) {
|
|
return SECFailure;
|
|
}
|
|
*destKey = PORT_ZNew(CRMFPOPOPrivKey);
|
|
if (*destKey == NULL) {
|
|
return SECFailure;
|
|
}
|
|
return crmf_copy_popoprivkey(NULL,
|
|
&inCertReqMsg->pop->popChoice.keyAgreement,
|
|
*destKey);
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFPOPOPrivKey **destKey)
|
|
{
|
|
PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
|
|
if (inCertReqMsg == NULL || destKey == NULL ||
|
|
CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) {
|
|
return SECFailure;
|
|
}
|
|
*destKey = PORT_ZNew(CRMFPOPOPrivKey);
|
|
if (*destKey == NULL) {
|
|
return SECFailure;
|
|
}
|
|
return crmf_copy_popoprivkey(NULL,
|
|
&inCertReqMsg->pop->popChoice.keyEncipherment,
|
|
*destKey);
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFPOPOSigningKey **destKey)
|
|
{
|
|
CRMFProofOfPossession *pop;
|
|
PORT_Assert(inCertReqMsg != NULL);
|
|
if (inCertReqMsg == NULL) {
|
|
return SECFailure;
|
|
}
|
|
pop = inCertReqMsg->pop;;
|
|
if (pop->popUsed != crmfSignature) {
|
|
return SECFailure;
|
|
}
|
|
*destKey = PORT_ZNew(CRMFPOPOSigningKey);
|
|
if (*destKey == NULL) {
|
|
return SECFailure;
|
|
}
|
|
return crmf_copy_poposigningkey(NULL,&pop->popChoice.signature, *destKey);
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_copy_name(CERTName *destName, CERTName *srcName)
|
|
{
|
|
PLArenaPool *poolp = NULL;
|
|
SECStatus rv;
|
|
|
|
if (destName->arena != NULL) {
|
|
poolp = destName->arena;
|
|
} else {
|
|
poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
|
|
}
|
|
if (poolp == NULL) {
|
|
return SECFailure;
|
|
}
|
|
/* Need to do this so that CERT_CopyName doesn't free out
|
|
* the arena from underneath us.
|
|
*/
|
|
destName->arena = NULL;
|
|
rv = CERT_CopyName(poolp, destName, srcName);
|
|
destName->arena = poolp;
|
|
return rv;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq,
|
|
CERTName *destIssuer)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuer)) {
|
|
return crmf_copy_name(destIssuer,
|
|
inCertReq->certTemplate.issuer);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
|
|
SECItem *destIssuerUID)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuerUID)) {
|
|
return crmf_make_bitstring_copy(NULL, destIssuerUID,
|
|
&inCertReq->certTemplate.issuerUID);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq,
|
|
CERTSubjectPublicKeyInfo *destPublicKey)
|
|
{
|
|
PORT_Assert (inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfPublicKey)) {
|
|
return SECKEY_CopySubjectPublicKeyInfo(NULL, destPublicKey,
|
|
inCertReq->certTemplate.publicKey);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
|
|
long *serialNumber)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfSerialNumber)) {
|
|
return
|
|
crmf_extract_long_from_item(&inCertReq->certTemplate.serialNumber,
|
|
serialNumber);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
|
|
SECAlgorithmID *destAlg)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfSigningAlg)) {
|
|
return SECOID_CopyAlgorithmID(NULL, destAlg,
|
|
inCertReq->certTemplate.signingAlg);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq,
|
|
CERTName *destSubject)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfSubject)) {
|
|
return crmf_copy_name(destSubject, inCertReq->certTemplate.subject);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateSubjectUID(CRMFCertRequest *inCertReq,
|
|
SECItem *destSubjectUID)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfSubjectUID)) {
|
|
return crmf_make_bitstring_copy(NULL, destSubjectUID,
|
|
&inCertReq->certTemplate.subjectUID);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq,
|
|
long *version)
|
|
{
|
|
PORT_Assert (inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfVersion)) {
|
|
return crmf_extract_long_from_item(&inCertReq->certTemplate.version,
|
|
version);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_copy_validity(CRMFGetValidity *destValidity,
|
|
CRMFOptionalValidity *src)
|
|
{
|
|
SECStatus rv;
|
|
|
|
destValidity->notBefore = destValidity->notAfter = NULL;
|
|
if (src->notBefore.data != NULL) {
|
|
rv = crmf_create_prtime(&src->notBefore,
|
|
&destValidity->notBefore);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
}
|
|
if (src->notAfter.data != NULL) {
|
|
rv = crmf_create_prtime(&src->notAfter,
|
|
&destValidity->notAfter);
|
|
if (rv != SECSuccess) {
|
|
return rv;
|
|
}
|
|
}
|
|
return SECSuccess;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq,
|
|
CRMFGetValidity *destValidity)
|
|
{
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return SECFailure;
|
|
}
|
|
if (CRMF_DoesRequestHaveField(inCertReq, crmfValidity)) {
|
|
return crmf_copy_validity(destValidity,
|
|
inCertReq->certTemplate.validity);
|
|
}
|
|
return SECFailure;
|
|
}
|
|
|
|
CRMFControl*
|
|
CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index)
|
|
{
|
|
CRMFControl *newControl, *srcControl;
|
|
int numControls;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inCertReq != NULL);
|
|
if (inCertReq == NULL) {
|
|
return NULL;
|
|
}
|
|
numControls = CRMF_CertRequestGetNumControls(inCertReq);
|
|
if (index >= numControls || index < 0) {
|
|
return NULL;
|
|
}
|
|
newControl = PORT_ZNew(CRMFControl);
|
|
if (newControl == NULL) {
|
|
return NULL;
|
|
}
|
|
srcControl = inCertReq->controls[index];
|
|
newControl->tag = srcControl->tag;
|
|
rv = SECITEM_CopyItem (NULL, &newControl->derTag, &srcControl->derTag);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
|
|
rv = SECITEM_CopyItem(NULL, &newControl->derValue,
|
|
&srcControl->derValue);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
/* Copy over the PKIArchiveOptions stuff */
|
|
switch (srcControl->tag) {
|
|
case SEC_OID_PKIX_REGCTRL_REGTOKEN:
|
|
case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
|
|
/* No further processing necessary for these types. */
|
|
rv = SECSuccess;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
|
|
case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
|
|
case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
|
|
/* These aren't supported yet, so no post-processing will
|
|
* be done at this time. But we don't want to fail in case
|
|
* we read in DER that has one of these options.
|
|
*/
|
|
rv = SECSuccess;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
|
|
rv = crmf_copy_pkiarchiveoptions(NULL,
|
|
&newControl->value.archiveOptions,
|
|
&srcControl->value.archiveOptions);
|
|
break;
|
|
default:
|
|
rv = SECFailure;
|
|
}
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
return newControl;
|
|
loser:
|
|
if (newControl != NULL) {
|
|
CRMF_DestroyControl(newControl);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static SECItem*
|
|
crmf_copy_control_value(CRMFControl *inControl)
|
|
{
|
|
return SECITEM_DupItem(&inControl->derValue);
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_ControlGetAuthenticatorControlValue(CRMFControl *inControl)
|
|
{
|
|
PORT_Assert (inControl!= NULL);
|
|
if (inControl == NULL ||
|
|
CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) {
|
|
return NULL;
|
|
}
|
|
return crmf_copy_control_value(inControl);
|
|
}
|
|
|
|
CRMFControlType
|
|
CRMF_ControlGetControlType(CRMFControl *inControl)
|
|
{
|
|
CRMFControlType retType;
|
|
|
|
PORT_Assert(inControl != NULL);
|
|
switch (inControl->tag) {
|
|
case SEC_OID_PKIX_REGCTRL_REGTOKEN:
|
|
retType = crmfRegTokenControl;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
|
|
retType = crmfAuthenticatorControl;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
|
|
retType = crmfPKIPublicationInfoControl;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
|
|
retType = crmfPKIArchiveOptionsControl;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
|
|
retType = crmfOldCertIDControl;
|
|
break;
|
|
case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
|
|
retType = crmfProtocolEncrKeyControl;
|
|
break;
|
|
default:
|
|
retType = crmfNoControl;
|
|
}
|
|
return retType;
|
|
}
|
|
|
|
CRMFPKIArchiveOptions*
|
|
CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl)
|
|
{
|
|
CRMFPKIArchiveOptions *newOpt = NULL;
|
|
SECStatus rv;
|
|
|
|
PORT_Assert(inControl != NULL);
|
|
if (inControl == NULL ||
|
|
CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl){
|
|
goto loser;
|
|
}
|
|
newOpt = PORT_ZNew(CRMFPKIArchiveOptions);
|
|
if (newOpt == NULL) {
|
|
goto loser;
|
|
}
|
|
rv = crmf_copy_pkiarchiveoptions(NULL, newOpt,
|
|
&inControl->value.archiveOptions);
|
|
if (rv != SECSuccess) {
|
|
goto loser;
|
|
}
|
|
|
|
loser:
|
|
if (newOpt != NULL) {
|
|
CRMF_DestroyPKIArchiveOptions(newOpt);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
SECItem*
|
|
CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl)
|
|
{
|
|
PORT_Assert(inControl != NULL);
|
|
if (inControl == NULL ||
|
|
CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) {
|
|
return NULL;
|
|
}
|
|
return crmf_copy_control_value(inControl);;
|
|
}
|
|
|
|
CRMFCertExtension*
|
|
CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
|
|
int index)
|
|
{
|
|
int numExtensions;
|
|
|
|
PORT_Assert(inCertReq != NULL);
|
|
numExtensions = CRMF_CertRequestGetNumberOfExtensions(inCertReq);
|
|
if (index >= numExtensions || index < 0) {
|
|
return NULL;
|
|
}
|
|
return
|
|
crmf_copy_cert_extension(NULL,
|
|
inCertReq->certTemplate.extensions[index]);
|
|
}
|
|
|