summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/crmf/servget.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/crmf/servget.c')
-rw-r--r--security/nss/lib/crmf/servget.c974
1 files changed, 974 insertions, 0 deletions
diff --git a/security/nss/lib/crmf/servget.c b/security/nss/lib/crmf/servget.c
new file mode 100644
index 000000000..6d576f8f1
--- /dev/null
+++ b/security/nss/lib/crmf/servget.c
@@ -0,0 +1,974 @@
+/* -*- 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);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+ 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:
+ 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:
+ 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]);
+}