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