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: #include "crmf.h" michael@0: #include "crmfi.h" michael@0: #include "keyhi.h" michael@0: #include "secder.h" michael@0: michael@0: /* michael@0: * Macro that returns PR_TRUE if the pointer is not NULL. michael@0: * If the pointer is NULL, then the macro will return PR_FALSE. michael@0: */ michael@0: #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE michael@0: michael@0: const unsigned char hexTrue = 0xff; michael@0: const unsigned char hexFalse = 0x00; michael@0: michael@0: michael@0: SECStatus michael@0: crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value) michael@0: { michael@0: SECItem *dummy; michael@0: michael@0: dummy = SEC_ASN1EncodeInteger(poolp, dest, value); michael@0: PORT_Assert (dummy == dest); michael@0: if (dummy == NULL) { michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest, michael@0: unsigned long value) michael@0: { michael@0: SECItem *dummy; michael@0: michael@0: dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); michael@0: PORT_Assert (dummy == dest); michael@0: if (dummy != dest) { michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) michael@0: { michael@0: return SECITEM_CopyItem (poolp, dest, src); michael@0: } michael@0: michael@0: PRBool michael@0: CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq, michael@0: CRMFCertTemplateField inField) michael@0: { michael@0: michael@0: PORT_Assert(inCertReq != NULL); michael@0: if (inCertReq == NULL) { michael@0: return PR_FALSE; michael@0: } michael@0: switch (inField) { michael@0: case crmfVersion: michael@0: return inCertReq->certTemplate.version.data != NULL; michael@0: case crmfSerialNumber: michael@0: return inCertReq->certTemplate.serialNumber.data != NULL; michael@0: case crmfSigningAlg: michael@0: return inCertReq->certTemplate.signingAlg != NULL; michael@0: case crmfIssuer: michael@0: return inCertReq->certTemplate.issuer != NULL; michael@0: case crmfValidity: michael@0: return inCertReq->certTemplate.validity != NULL; michael@0: case crmfSubject: michael@0: return inCertReq->certTemplate.subject != NULL; michael@0: case crmfPublicKey: michael@0: return inCertReq->certTemplate.publicKey != NULL; michael@0: case crmfIssuerUID: michael@0: return inCertReq->certTemplate.issuerUID.data != NULL; michael@0: case crmfSubjectUID: michael@0: return inCertReq->certTemplate.subjectUID.data != NULL; michael@0: case crmfExtension: michael@0: return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0; michael@0: } michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: CRMFCertRequest * michael@0: CRMF_CreateCertRequest (PRUint32 inRequestID) michael@0: { michael@0: PLArenaPool *poolp; michael@0: CRMFCertRequest *certReq; michael@0: SECStatus rv; michael@0: michael@0: poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); michael@0: if (poolp == NULL) { michael@0: goto loser; michael@0: } michael@0: michael@0: certReq=PORT_ArenaZNew(poolp,CRMFCertRequest); michael@0: if (certReq == NULL) { michael@0: goto loser; michael@0: } michael@0: michael@0: certReq->poolp = poolp; michael@0: certReq->requestID = inRequestID; michael@0: michael@0: rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), michael@0: inRequestID); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: michael@0: return certReq; michael@0: loser: michael@0: if (poolp) { michael@0: PORT_FreeArena(poolp, PR_FALSE); michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq) michael@0: { michael@0: PORT_Assert(inCertReq != NULL); michael@0: if (inCertReq != NULL) { michael@0: if (inCertReq->certTemplate.extensions) { michael@0: PORT_Free(inCertReq->certTemplate.extensions); michael@0: } michael@0: if (inCertReq->controls) { michael@0: /* Right now we don't support EnveloppedData option, michael@0: * so we won't go through and delete each occurrence of michael@0: * an EnveloppedData in the control. michael@0: */ michael@0: PORT_Free(inCertReq->controls); michael@0: } michael@0: if (inCertReq->poolp) { michael@0: PORT_FreeArena(inCertReq->poolp, PR_TRUE); michael@0: } michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version) michael@0: { michael@0: return (crmf_encode_integer(poolp, dest, version)); michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial) michael@0: { michael@0: return (crmf_encode_integer(poolp, dest, serial)); michael@0: } michael@0: michael@0: SECStatus michael@0: crmf_template_copy_secalg (PLArenaPool *poolp, SECAlgorithmID **dest, michael@0: SECAlgorithmID* src) michael@0: { michael@0: SECStatus rv; michael@0: void *mark = NULL; michael@0: SECAlgorithmID *mySecAlg; michael@0: michael@0: if (!poolp) { michael@0: PORT_SetError(SEC_ERROR_INVALID_ARGS); michael@0: return SECFailure; michael@0: } michael@0: michael@0: mark = PORT_ArenaMark(poolp); michael@0: *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); michael@0: if (mySecAlg == NULL) { michael@0: goto loser; michael@0: } michael@0: rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: if (mark) { michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: } michael@0: return SECSuccess; michael@0: michael@0: loser: michael@0: *dest = NULL; michael@0: if (mark) { michael@0: PORT_ArenaRelease(poolp, mark); michael@0: } michael@0: return SECFailure; michael@0: } michael@0: michael@0: SECStatus michael@0: crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest, michael@0: CERTName *src) michael@0: { michael@0: CERTName *newName; michael@0: SECStatus rv; michael@0: void *mark; michael@0: michael@0: mark = PORT_ArenaMark(poolp); michael@0: *dest = newName = PORT_ArenaZNew(poolp, CERTName); michael@0: if (newName == NULL) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv = CERT_CopyName(poolp, newName, src); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: return SECSuccess; michael@0: loser: michael@0: PORT_ArenaRelease(poolp, mark); michael@0: *dest = NULL; michael@0: return SECFailure; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_issuer (PLArenaPool *poolp, CERTName **dest, michael@0: CERTName* issuerName) michael@0: { michael@0: return crmf_copy_cert_name(poolp, dest, issuerName); michael@0: } michael@0: michael@0: michael@0: static SECStatus michael@0: crmf_template_add_validity (PLArenaPool *poolp, CRMFOptionalValidity **dest, michael@0: CRMFValidityCreationInfo *info) michael@0: { michael@0: SECStatus rv; michael@0: void *mark; michael@0: CRMFOptionalValidity *myValidity; michael@0: michael@0: /*First off, let's make sure at least one of the two fields is present*/ michael@0: if (!info || (!info->notBefore && !info->notAfter)) { michael@0: return SECFailure; michael@0: } michael@0: mark = PORT_ArenaMark (poolp); michael@0: *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity); michael@0: if (myValidity == NULL) { michael@0: goto loser; michael@0: } michael@0: michael@0: if (info->notBefore) { michael@0: rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore, michael@0: *info->notBefore); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: } michael@0: if (info->notAfter) { michael@0: rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter, michael@0: *info->notAfter); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: } michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: return SECSuccess; michael@0: loser: michael@0: PORT_ArenaRelease(poolp, mark); michael@0: *dest = NULL; michael@0: return SECFailure; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_subject (PLArenaPool *poolp, CERTName **dest, michael@0: CERTName *subject) michael@0: { michael@0: return crmf_copy_cert_name(poolp, dest, subject); michael@0: } michael@0: michael@0: SECStatus michael@0: crmf_template_add_public_key(PLArenaPool *poolp, michael@0: CERTSubjectPublicKeyInfo **dest, michael@0: CERTSubjectPublicKeyInfo *pubKey) michael@0: { michael@0: CERTSubjectPublicKeyInfo *spki; michael@0: SECStatus rv; michael@0: michael@0: *dest = spki = (poolp == NULL) ? michael@0: PORT_ZNew(CERTSubjectPublicKeyInfo) : michael@0: PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo); michael@0: if (spki == NULL) { michael@0: goto loser; michael@0: } michael@0: rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: return SECSuccess; michael@0: loser: michael@0: if (poolp == NULL && spki != NULL) { michael@0: SECKEY_DestroySubjectPublicKeyInfo(spki); michael@0: } michael@0: *dest = NULL; michael@0: return SECFailure; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_copy_bitstring (PLArenaPool *poolp, SECItem *dest, const SECItem *src) michael@0: { michael@0: SECStatus rv; michael@0: SECItem byteSrc; michael@0: michael@0: byteSrc = *src; michael@0: byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len); michael@0: rv = crmf_copy_secitem(poolp, dest, &byteSrc); michael@0: dest->len = src->len; michael@0: return rv; michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest, michael@0: const SECItem *issuerUID) michael@0: { michael@0: return crmf_copy_bitstring (poolp, dest, issuerUID); michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest, michael@0: const SECItem *subjectUID) michael@0: { michael@0: return crmf_copy_bitstring (poolp, dest, subjectUID); michael@0: } michael@0: michael@0: static void michael@0: crmf_zeroize_new_extensions (CRMFCertExtension **extensions, michael@0: int numToZeroize) michael@0: { michael@0: PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize); michael@0: } michael@0: michael@0: /* michael@0: * The strategy for adding templates will differ from all the other michael@0: * attributes in the template. First, we want to allow the client michael@0: * of this API to set extensions more than just once. So we will michael@0: * need the ability grow the array of extensions. Since arenas don't michael@0: * give us the realloc function, we'll use the generic PORT_* functions michael@0: * to allocate the array of pointers *ONLY*. Then we will allocate each michael@0: * individual extension from the arena that comes along with the certReq michael@0: * structure that owns this template. michael@0: */ michael@0: static SECStatus michael@0: crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate, michael@0: CRMFCertExtCreationInfo *extensions) michael@0: { michael@0: void *mark; michael@0: int newSize, oldSize, i; michael@0: SECStatus rv; michael@0: CRMFCertExtension **extArray; michael@0: CRMFCertExtension *newExt, *currExt; michael@0: michael@0: mark = PORT_ArenaMark(poolp); michael@0: if (inTemplate->extensions == NULL) { michael@0: newSize = extensions->numExtensions; michael@0: extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1); michael@0: } else { michael@0: newSize = inTemplate->numExtensions + extensions->numExtensions; michael@0: extArray = PORT_Realloc(inTemplate->extensions, michael@0: sizeof(CRMFCertExtension*)*(newSize+1)); michael@0: } michael@0: if (extArray == NULL) { michael@0: goto loser; michael@0: } michael@0: oldSize = inTemplate->numExtensions; michael@0: inTemplate->extensions = extArray; michael@0: inTemplate->numExtensions = newSize; michael@0: for (i=oldSize; i < newSize; i++) { michael@0: newExt = PORT_ArenaZNew(poolp, CRMFCertExtension); michael@0: if (newExt == NULL) { michael@0: goto loser2; michael@0: } michael@0: currExt = extensions->extensions[i-oldSize]; michael@0: rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id)); michael@0: if (rv != SECSuccess) { michael@0: goto loser2; michael@0: } michael@0: rv = crmf_copy_secitem(poolp, &(newExt->critical), michael@0: &(currExt->critical)); michael@0: if (rv != SECSuccess) { michael@0: goto loser2; michael@0: } michael@0: rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value)); michael@0: if (rv != SECSuccess) { michael@0: goto loser2; michael@0: } michael@0: extArray[i] = newExt; michael@0: } michael@0: extArray[newSize] = NULL; michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: return SECSuccess; michael@0: loser2: michael@0: crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]), michael@0: extensions->numExtensions); michael@0: inTemplate->numExtensions = oldSize; michael@0: loser: michael@0: PORT_ArenaRelease(poolp, mark); michael@0: return SECFailure; michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq, michael@0: CRMFCertTemplateField inTemplateField, michael@0: void *data) michael@0: { michael@0: CRMFCertTemplate *certTemplate; michael@0: PLArenaPool *poolp; michael@0: SECStatus rv = SECFailure; michael@0: void *mark; michael@0: michael@0: michael@0: if (inCertReq == NULL) { michael@0: return SECFailure; michael@0: } michael@0: michael@0: certTemplate = &(inCertReq->certTemplate); michael@0: michael@0: poolp = inCertReq->poolp; michael@0: mark = PORT_ArenaMark(poolp); michael@0: switch (inTemplateField) { michael@0: case crmfVersion: michael@0: rv = crmf_template_add_version(poolp,&(certTemplate->version), michael@0: *(long*)data); michael@0: break; michael@0: case crmfSerialNumber: michael@0: rv = crmf_template_add_serialnumber(poolp, michael@0: &(certTemplate->serialNumber), michael@0: *(long*)data); michael@0: break; michael@0: case crmfSigningAlg: michael@0: rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg), michael@0: (SECAlgorithmID*)data); michael@0: break; michael@0: case crmfIssuer: michael@0: rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer), michael@0: (CERTName*)data); michael@0: break; michael@0: case crmfValidity: michael@0: rv = crmf_template_add_validity (poolp, &(certTemplate->validity), michael@0: (CRMFValidityCreationInfo*)data); michael@0: break; michael@0: case crmfSubject: michael@0: rv = crmf_template_add_subject (poolp, &(certTemplate->subject), michael@0: (CERTName*)data); michael@0: break; michael@0: case crmfPublicKey: michael@0: rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey), michael@0: (CERTSubjectPublicKeyInfo*)data); michael@0: break; michael@0: case crmfIssuerUID: michael@0: rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID), michael@0: (SECItem*)data); michael@0: break; michael@0: case crmfSubjectUID: michael@0: rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID), michael@0: (SECItem*)data); michael@0: break; michael@0: case crmfExtension: michael@0: rv = crmf_template_add_extensions(poolp, certTemplate, michael@0: (CRMFCertExtCreationInfo*)data); michael@0: break; michael@0: } michael@0: if (rv != SECSuccess) { michael@0: PORT_ArenaRelease(poolp, mark); michael@0: } else { michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg *inCertReqMsg, michael@0: CRMFCertRequest *inCertReq) michael@0: { michael@0: PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL); michael@0: if (inCertReqMsg == NULL || inCertReq == NULL) { michael@0: return SECFailure; michael@0: } michael@0: inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp, michael@0: inCertReq); michael@0: return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess; michael@0: } michael@0: michael@0: CRMFCertReqMsg* michael@0: CRMF_CreateCertReqMsg(void) michael@0: { michael@0: PLArenaPool *poolp; michael@0: CRMFCertReqMsg *reqMsg; michael@0: michael@0: poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); michael@0: if (poolp == NULL) { michael@0: goto loser; michael@0: } michael@0: reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); michael@0: if (reqMsg == NULL) { michael@0: goto loser; michael@0: } michael@0: reqMsg->poolp = poolp; michael@0: return reqMsg; michael@0: michael@0: loser: michael@0: if (poolp) { michael@0: PORT_FreeArena(poolp, PR_FALSE); michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg) michael@0: { michael@0: PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL); michael@0: if (!inCertReqMsg->isDecoded) { michael@0: if (inCertReqMsg->certReq->certTemplate.extensions != NULL) { michael@0: PORT_Free(inCertReqMsg->certReq->certTemplate.extensions); michael@0: } michael@0: if (inCertReqMsg->certReq->controls != NULL) { michael@0: PORT_Free(inCertReqMsg->certReq->controls); michael@0: } michael@0: } michael@0: PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE); michael@0: return SECSuccess; michael@0: } michael@0: michael@0: CRMFCertExtension* michael@0: crmf_create_cert_extension(PLArenaPool *poolp, michael@0: SECOidTag id, michael@0: PRBool isCritical, michael@0: SECItem *data) michael@0: { michael@0: CRMFCertExtension *newExt; michael@0: SECOidData *oidData; michael@0: SECStatus rv; michael@0: michael@0: newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) : michael@0: PORT_ArenaZNew(poolp, CRMFCertExtension); michael@0: if (newExt == NULL) { michael@0: goto loser; michael@0: } michael@0: oidData = SECOID_FindOIDByTag(id); michael@0: if (oidData == NULL || michael@0: oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid)); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: michael@0: rv = SECITEM_CopyItem(poolp, &(newExt->value), data); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: michael@0: if (isCritical) { michael@0: newExt->critical.data = (poolp == NULL) ? michael@0: PORT_New(unsigned char) : michael@0: PORT_ArenaNew(poolp, unsigned char); michael@0: if (newExt->critical.data == NULL) { michael@0: goto loser; michael@0: } michael@0: newExt->critical.data[0] = hexTrue; michael@0: newExt->critical.len = 1; michael@0: } michael@0: return newExt; michael@0: loser: michael@0: if (newExt != NULL && poolp == NULL) { michael@0: CRMF_DestroyCertExtension(newExt); michael@0: } michael@0: return NULL; michael@0: } michael@0: michael@0: CRMFCertExtension * michael@0: CRMF_CreateCertExtension(SECOidTag id, michael@0: PRBool isCritical, michael@0: SECItem *data) michael@0: { michael@0: return crmf_create_cert_extension(NULL, id, isCritical, data); michael@0: } michael@0: michael@0: static SECStatus michael@0: crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit) michael@0: { michael@0: if (inExtension != NULL) { michael@0: SECITEM_FreeItem (&(inExtension->id), PR_FALSE); michael@0: SECITEM_FreeItem (&(inExtension->value), PR_FALSE); michael@0: SECITEM_FreeItem (&(inExtension->critical), PR_FALSE); michael@0: if (freeit) { michael@0: PORT_Free(inExtension); michael@0: } michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_DestroyCertExtension(CRMFCertExtension *inExtension) michael@0: { michael@0: return crmf_destroy_cert_extension(inExtension, PR_TRUE); michael@0: } michael@0: michael@0: SECStatus michael@0: CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) michael@0: { michael@0: PORT_Assert (inCertReqMsgs != NULL); michael@0: if (inCertReqMsgs != NULL) { michael@0: PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: static PRBool michael@0: crmf_item_has_data(SECItem *item) michael@0: { michael@0: if (item != NULL && item->data != NULL) { michael@0: return PR_TRUE; michael@0: } michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: PRBool michael@0: CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq, michael@0: CRMFCertTemplateField inTemplateField) michael@0: { michael@0: PRBool retVal; michael@0: CRMFCertTemplate *certTemplate; michael@0: michael@0: PORT_Assert(inCertReq != NULL); michael@0: if (inCertReq == NULL) { michael@0: /* This is probably some kind of error, but this is michael@0: * the safest return value for this function. michael@0: */ michael@0: return PR_FALSE; michael@0: } michael@0: certTemplate = &inCertReq->certTemplate; michael@0: switch (inTemplateField) { michael@0: case crmfVersion: michael@0: retVal = crmf_item_has_data(&certTemplate->version); michael@0: break; michael@0: case crmfSerialNumber: michael@0: retVal = crmf_item_has_data(&certTemplate->serialNumber); michael@0: break; michael@0: case crmfSigningAlg: michael@0: retVal = IS_NOT_NULL(certTemplate->signingAlg); michael@0: break; michael@0: case crmfIssuer: michael@0: retVal = IS_NOT_NULL(certTemplate->issuer); michael@0: break; michael@0: case crmfValidity: michael@0: retVal = IS_NOT_NULL(certTemplate->validity); michael@0: break; michael@0: case crmfSubject: michael@0: retVal = IS_NOT_NULL(certTemplate->subject); michael@0: break; michael@0: case crmfPublicKey: michael@0: retVal = IS_NOT_NULL(certTemplate->publicKey); michael@0: break; michael@0: case crmfIssuerUID: michael@0: retVal = crmf_item_has_data(&certTemplate->issuerUID); michael@0: break; michael@0: case crmfSubjectUID: michael@0: retVal = crmf_item_has_data(&certTemplate->subjectUID); michael@0: break; michael@0: case crmfExtension: michael@0: retVal = IS_NOT_NULL(certTemplate->extensions); michael@0: break; michael@0: default: michael@0: retVal = PR_FALSE; michael@0: } michael@0: return retVal; michael@0: }