/* -*- 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]); }