crmfreq.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:19k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* -*- Mode: C; tab-width: 8 -*-*/
  2. /*
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  * 
  13.  * The Original Code is the Netscape security libraries.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are 
  17.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  18.  * Rights Reserved.
  19.  * 
  20.  * Contributor(s):
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34. #include "crmf.h"
  35. #include "crmfi.h"
  36. #include "keyhi.h"
  37. #include "secder.h"
  38. /*
  39.  * Macro that returns PR_TRUE if the pointer is not NULL.
  40.  * If the pointer is NULL, then the macro will return PR_FALSE.
  41.  */
  42. #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
  43. const unsigned char hexTrue  = 0xff;
  44. const unsigned char hexFalse = 0x00;
  45. SECStatus
  46. crmf_encode_integer(PRArenaPool *poolp, SECItem *dest, long value) 
  47. {
  48.     SECItem *dummy;
  49.     dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
  50.     PORT_Assert (dummy == dest);
  51.     if (dummy == NULL) {
  52.         return SECFailure;
  53.     }
  54.     return SECSuccess;
  55. }
  56. static SECStatus
  57. crmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src)
  58. {
  59.     return  SECITEM_CopyItem (poolp, dest, src); 
  60. }
  61. PRBool
  62. CRMF_DoesRequestHaveField (CRMFCertRequest       *inCertReq, 
  63.    CRMFCertTemplateField  inField)
  64. {
  65.   
  66.     PORT_Assert(inCertReq != NULL);
  67.     if (inCertReq == NULL) {
  68.         return PR_FALSE;
  69.     }
  70.     switch (inField) {
  71.     case crmfVersion:
  72.         return inCertReq->certTemplate.version.data != NULL;
  73.     case crmfSerialNumber:
  74.         return inCertReq->certTemplate.serialNumber.data != NULL;
  75.     case crmfSigningAlg:
  76.         return inCertReq->certTemplate.signingAlg != NULL;
  77.     case crmfIssuer:
  78.         return inCertReq->certTemplate.issuer != NULL;
  79.     case crmfValidity:
  80.         return inCertReq->certTemplate.validity != NULL;
  81.     case crmfSubject:
  82.         return inCertReq->certTemplate.subject != NULL;
  83.     case crmfPublicKey:
  84.         return inCertReq->certTemplate.publicKey != NULL;
  85.     case crmfIssuerUID:
  86.         return inCertReq->certTemplate.issuerUID.data != NULL;
  87.     case crmfSubjectUID:
  88.         return inCertReq->certTemplate.subjectUID.data != NULL;
  89.     case crmfExtension:
  90.         return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
  91.     }
  92.     return PR_FALSE;
  93. }
  94. CRMFCertRequest *
  95. CRMF_CreateCertRequest (long inRequestID) {
  96.     PRArenaPool     *poolp;
  97.     CRMFCertRequest *certReq;
  98.     SECStatus        rv;
  99.     
  100.     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
  101.     if (poolp == NULL) {
  102.         goto loser;
  103.     }
  104.     
  105.     certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
  106.     if (certReq == NULL) {
  107.         goto loser;
  108.     }
  109.     certReq->poolp = poolp;
  110.     certReq->requestID = inRequestID;
  111.     
  112.     rv = crmf_encode_integer(poolp, &(certReq->certReqId), inRequestID);
  113.     if (rv != SECSuccess) {
  114.         goto loser;
  115.     }
  116.     return certReq;
  117.  loser:
  118.     if (poolp) {
  119.         PORT_FreeArena(poolp, PR_FALSE);
  120.     }
  121.     return NULL;
  122. }
  123. SECStatus
  124. CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
  125. {
  126.     PORT_Assert(inCertReq != NULL);
  127.     if (inCertReq != NULL) {
  128.         if (inCertReq->certTemplate.extensions) {
  129.     PORT_Free(inCertReq->certTemplate.extensions);
  130. }
  131. if (inCertReq->controls) {
  132.     /* Right now we don't support EnveloppedData option,
  133.      * so we won't go through and delete each occurrence of 
  134.      * an EnveloppedData in the control.
  135.      */
  136.     PORT_Free(inCertReq->controls);
  137. }
  138. if (inCertReq->poolp) {
  139.     PORT_FreeArena(inCertReq->poolp, PR_TRUE);
  140. }
  141.     }
  142.     return SECSuccess;
  143. }
  144. static SECStatus
  145. crmf_template_add_version(PRArenaPool *poolp, SECItem *dest, long version)
  146. {
  147.     return (crmf_encode_integer(poolp, dest, version));
  148. }
  149. static SECStatus
  150. crmf_template_add_serialnumber(PRArenaPool *poolp, SECItem *dest, long serial)
  151. {
  152.     return (crmf_encode_integer(poolp, dest, serial));
  153. }
  154. SECStatus
  155. crmf_template_copy_secalg (PRArenaPool *poolp, SECAlgorithmID **dest, 
  156.    SECAlgorithmID* src)
  157. {
  158.     SECStatus         rv;
  159.     void             *mark;
  160.     SECAlgorithmID   *mySecAlg;
  161.     if (poolp != NULL) {
  162.         mark = PORT_ArenaMark(poolp);
  163.     }
  164.     *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
  165.     if (mySecAlg == NULL) {
  166.         goto loser;
  167.     }
  168.     rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
  169.     if (rv != SECSuccess) {
  170.         goto loser;
  171.     }
  172.     if (poolp != NULL) {
  173.         PORT_ArenaUnmark(poolp, mark);
  174.     }
  175.     return SECSuccess;
  176.  loser:
  177.     *dest = NULL;
  178.     if (poolp != NULL) {
  179.         PORT_ArenaRelease(poolp, mark);
  180.     }
  181.     return SECFailure;
  182. }
  183. SECStatus
  184. crmf_copy_cert_name(PRArenaPool *poolp, CERTName **dest, 
  185.     CERTName *src)
  186. {
  187.     CERTName *newName;
  188.     SECStatus rv;
  189.     void     *mark;
  190.     mark = PORT_ArenaMark(poolp);
  191.     *dest = newName = PORT_ArenaZNew(poolp, CERTName);
  192.     if (newName == NULL) {
  193.         goto loser;
  194.     }
  195.     rv = CERT_CopyName(poolp, newName, src);
  196.     if (rv != SECSuccess) {
  197.       goto loser;
  198.     }
  199.     PORT_ArenaUnmark(poolp, mark);
  200.     return SECSuccess;
  201.  loser:
  202.     PORT_ArenaRelease(poolp, mark);
  203.     *dest = NULL;
  204.     return SECFailure;
  205. }
  206. static SECStatus
  207. crmf_template_add_issuer (PRArenaPool *poolp, CERTName **dest, 
  208.   CERTName* issuerName)
  209. {
  210.     return crmf_copy_cert_name(poolp, dest, issuerName);
  211. }
  212. static SECStatus
  213. crmf_encode_utctime(PRArenaPool *poolp, SECItem *destTime, PRTime time)
  214. {
  215.     SECItem   tmpItem;
  216.     SECStatus rv;
  217.     rv = DER_TimeToUTCTime (&tmpItem, time);
  218.     if (rv != SECSuccess) {
  219.         return rv;
  220.     }
  221.     rv = SECITEM_CopyItem(poolp, destTime, &tmpItem);
  222.     PORT_Free(tmpItem.data);
  223.     return rv;
  224. }
  225. static SECStatus
  226. crmf_template_add_validity (PRArenaPool *poolp, CRMFOptionalValidity **dest,
  227.     CRMFValidityCreationInfo *info)
  228. {
  229.     SECStatus             rv;
  230.     void                 *mark; 
  231.     CRMFOptionalValidity *myValidity;
  232.     /*First off, let's make sure at least one of the two fields is present*/
  233.     if (!info  || (!info->notBefore && !info->notAfter)) {
  234.         return SECFailure;
  235.     }
  236.     mark = PORT_ArenaMark (poolp);
  237.     *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
  238.     if (myValidity == NULL) {
  239.         goto loser;
  240.     }
  241.     if (info->notBefore) {
  242.         rv = crmf_encode_utctime (poolp, &myValidity->notBefore, 
  243.   *info->notBefore);
  244. if (rv != SECSuccess) {
  245.     goto loser;
  246. }
  247.     }
  248.     if (info->notAfter) {
  249.         rv = crmf_encode_utctime (poolp, &myValidity->notAfter,
  250.   *info->notAfter);
  251. if (rv != SECSuccess) {
  252.     goto loser;
  253. }
  254.     }
  255.     PORT_ArenaUnmark(poolp, mark);
  256.     return SECSuccess;
  257.  loser:
  258.     PORT_ArenaRelease(poolp, mark);
  259.     *dest = NULL;
  260.     return SECFailure;
  261. }
  262. static SECStatus
  263. crmf_template_add_subject (PRArenaPool *poolp, CERTName **dest,
  264.    CERTName *subject)
  265. {
  266.     return crmf_copy_cert_name(poolp, dest, subject);
  267. }
  268. SECStatus
  269. crmf_template_add_public_key(PRArenaPool *poolp, 
  270.      CERTSubjectPublicKeyInfo **dest,
  271.      CERTSubjectPublicKeyInfo  *pubKey)
  272. {
  273.     CERTSubjectPublicKeyInfo *spki;
  274.     SECStatus rv;
  275.     *dest = spki = (poolp == NULL) ?
  276.                               PORT_ZNew(CERTSubjectPublicKeyInfo) :
  277.                               PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
  278.     if (spki == NULL) {
  279.         goto loser;
  280.     }
  281.     rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
  282.     if (rv != SECSuccess) {
  283.         goto loser;
  284.     }
  285.     return SECSuccess;
  286.  loser:
  287.     if (poolp == NULL && spki != NULL) {
  288.         SECKEY_DestroySubjectPublicKeyInfo(spki);
  289.     }
  290.     *dest = NULL;
  291.     return SECFailure;
  292. }
  293. static SECStatus
  294. crmf_copy_bitstring (PRArenaPool *poolp, SECItem *dest, SECItem *src)
  295. {
  296.     SECStatus rv;
  297.     int origLenBits, numBytesToCopy;
  298.     
  299.     origLenBits = src->len;
  300.     numBytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
  301.     rv = crmf_copy_secitem(poolp, dest, src);
  302.     src->len = origLenBits;
  303.     dest->len = origLenBits;
  304.     return rv;
  305. }
  306. static SECStatus
  307. crmf_template_add_issuer_uid(PRArenaPool *poolp, SECItem *dest,
  308.      SECItem *issuerUID)
  309. {
  310.     return crmf_copy_bitstring (poolp, dest, issuerUID);
  311. }
  312. static SECStatus
  313. crmf_template_add_subject_uid(PRArenaPool *poolp, SECItem *dest, 
  314.       SECItem *subjectUID)
  315. {
  316.     return crmf_copy_bitstring (poolp, dest, subjectUID);
  317. }
  318. static void
  319. crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
  320.      int numToZeroize) 
  321. {
  322.     PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
  323. }
  324. /*
  325.  * The strategy for adding templates will differ from all the other
  326.  * attributes in the template.  First, we want to allow the client
  327.  * of this API to set extensions more than just once.  So we will
  328.  * need the ability grow the array of extensions.  Since arenas don't
  329.  * give us the realloc function, we'll use the generic PORT_* functions
  330.  * to allocate the array of pointers *ONLY*.  Then we will allocate each
  331.  * individual extension from the arena that comes along with the certReq
  332.  * structure that owns this template.
  333.  */
  334. static SECStatus
  335. crmf_template_add_extensions(PRArenaPool *poolp, CRMFCertTemplate *inTemplate,
  336.      CRMFCertExtCreationInfo *extensions)
  337. {
  338.     void               *mark;
  339.     int                 newSize, oldSize, i;
  340.     SECStatus           rv;
  341.     CRMFCertExtension **extArray;
  342.     CRMFCertExtension  *newExt, *currExt;
  343.     mark = PORT_ArenaMark(poolp);
  344.     if (inTemplate->extensions == NULL) {
  345.         newSize = extensions->numExtensions;
  346.         extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
  347.     } else {
  348.         newSize = inTemplate->numExtensions + extensions->numExtensions;
  349.         extArray = PORT_Realloc(inTemplate->extensions, 
  350. sizeof(CRMFCertExtension*)*(newSize+1));
  351.     }
  352.     if (extArray == NULL) {
  353.         goto loser;
  354.     }
  355.     oldSize                   = inTemplate->numExtensions;
  356.     inTemplate->extensions    = extArray;
  357.     inTemplate->numExtensions = newSize;
  358.     for (i=oldSize; i < newSize; i++) {
  359.         newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
  360. if (newExt == NULL) {
  361.     goto loser2;
  362. }
  363. currExt = extensions->extensions[i-oldSize];
  364. rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
  365. if (rv != SECSuccess) {
  366.     goto loser2;
  367. }
  368. rv = crmf_copy_secitem(poolp, &(newExt->critical),
  369.        &(currExt->critical));
  370. if (rv != SECSuccess) {
  371.     goto loser2;
  372. }
  373. rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
  374. if (rv != SECSuccess) {
  375.     goto loser2;
  376. }
  377. extArray[i] = newExt;
  378.     }
  379.     extArray[newSize] = NULL;
  380.     PORT_ArenaUnmark(poolp, mark);
  381.     return SECSuccess;
  382.  loser2:
  383.     crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]),
  384.  extensions->numExtensions);
  385.     inTemplate->numExtensions = oldSize;
  386.  loser:
  387.     PORT_ArenaRelease(poolp, mark);
  388.     return SECFailure;
  389. }
  390. SECStatus
  391. CRMF_CertRequestSetTemplateField(CRMFCertRequest       *inCertReq, 
  392.  CRMFCertTemplateField  inTemplateField,
  393.  void                  *data)
  394. {
  395.     CRMFCertTemplate *certTemplate;
  396.     PRArenaPool      *poolp;
  397.     SECStatus         rv = SECFailure;
  398.     void             *mark;
  399.     
  400.     if (inCertReq == NULL) {
  401.         return SECFailure;
  402.     }
  403.     certTemplate = &(inCertReq->certTemplate);
  404.     poolp = inCertReq->poolp;
  405.     mark = PORT_ArenaMark(poolp);
  406.     switch (inTemplateField) {
  407.     case crmfVersion:
  408.       rv = crmf_template_add_version(poolp,&(certTemplate->version), 
  409.      *(long*)data);
  410.       break;
  411.     case crmfSerialNumber:
  412.       rv = crmf_template_add_serialnumber(poolp, 
  413.   &(certTemplate->serialNumber),
  414.   *(long*)data);
  415.       break;
  416.     case crmfSigningAlg:
  417.       rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg),
  418.       (SECAlgorithmID*)data);
  419.       break;
  420.     case crmfIssuer:
  421.       rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer), 
  422.      (CERTName*)data);
  423.       break;
  424.     case crmfValidity:
  425.       rv = crmf_template_add_validity (poolp, &(certTemplate->validity),
  426.        (CRMFValidityCreationInfo*)data);
  427.       break;
  428.     case crmfSubject:
  429.       rv = crmf_template_add_subject (poolp, &(certTemplate->subject),
  430.       (CERTName*)data);
  431.       break;
  432.     case crmfPublicKey:
  433.       rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
  434. (CERTSubjectPublicKeyInfo*)data);
  435.       break;
  436.     case crmfIssuerUID:
  437.       rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
  438. (SECItem*)data);
  439.       break;
  440.     case crmfSubjectUID:
  441.       rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
  442.  (SECItem*)data);
  443.       break;
  444.     case crmfExtension:
  445.       rv = crmf_template_add_extensions(poolp, certTemplate, 
  446. (CRMFCertExtCreationInfo*)data);
  447.       break;
  448.     }
  449.     if (rv != SECSuccess) {
  450.         PORT_ArenaRelease(poolp, mark);
  451.     } else {
  452.         PORT_ArenaUnmark(poolp, mark);
  453.     }
  454.     return rv;
  455. }
  456. SECStatus
  457. CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg  *inCertReqMsg, 
  458.        CRMFCertRequest *inCertReq)
  459. {
  460.     PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
  461.     if (inCertReqMsg == NULL || inCertReq == NULL) {
  462.         return SECFailure;
  463.     }
  464.     inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
  465.    inCertReq);
  466.     return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
  467. }
  468. CRMFCertReqMsg*
  469. CRMF_CreateCertReqMsg(void)
  470. {
  471.     PRArenaPool    *poolp;
  472.     CRMFCertReqMsg *reqMsg;
  473.     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
  474.     if (poolp == NULL) {
  475.         goto loser;
  476.     }
  477.     reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
  478.     if (reqMsg == NULL) {
  479.         goto loser;
  480.     }
  481.     reqMsg->poolp = poolp;
  482.     return reqMsg;
  483.     
  484.  loser:
  485.     if (poolp) {
  486.         PORT_FreeArena(poolp, PR_FALSE);
  487.     }
  488.     return NULL;
  489. }
  490. SECStatus 
  491. CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
  492. {
  493.     PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
  494.     if (!inCertReqMsg->isDecoded) {
  495.         if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
  496.     PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
  497. }
  498. if (inCertReqMsg->certReq->controls != NULL) {
  499.     PORT_Free(inCertReqMsg->certReq->controls);
  500. }
  501.     }
  502.     PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
  503.     return SECSuccess;
  504. }
  505. CRMFCertExtension*
  506. crmf_create_cert_extension(PRArenaPool *poolp, 
  507.    SECOidTag    id,
  508.    PRBool       isCritical,
  509.    SECItem     *data)
  510. {
  511.     CRMFCertExtension *newExt;
  512.     SECOidData        *oidData;
  513.     SECStatus          rv;
  514.     newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
  515.                                PORT_ArenaZNew(poolp, CRMFCertExtension);
  516.     if (newExt == NULL) {
  517.         goto loser;
  518.     }
  519.     oidData = SECOID_FindOIDByTag(id);
  520.     if (oidData == NULL || 
  521. oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
  522.        goto loser;
  523.     }
  524.     rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
  525.     if (rv != SECSuccess) {
  526.         goto loser;
  527.     }
  528.     rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
  529.     if (rv != SECSuccess) {
  530.         goto loser;
  531.     }
  532.     if (isCritical) {
  533.         newExt->critical.data = (poolp == NULL) ? 
  534.                                 PORT_New(unsigned char) :
  535.                                 PORT_ArenaNew(poolp, unsigned char);
  536. if (newExt->critical.data == NULL) {
  537.     goto loser;
  538. }
  539. newExt->critical.data[0] = hexTrue;
  540. newExt->critical.len = 1;
  541.     }
  542.     return newExt;
  543.  loser:
  544.     if (newExt != NULL && poolp == NULL) {
  545.         CRMF_DestroyCertExtension(newExt);
  546.     }
  547.     return NULL;
  548. }
  549. CRMFCertExtension *
  550. CRMF_CreateCertExtension(SECOidTag id,
  551.  PRBool    isCritical,
  552.  SECItem  *data) 
  553. {
  554.     return crmf_create_cert_extension(NULL, id, isCritical, data);
  555. }
  556. SECStatus
  557. crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
  558. {
  559.     if (inExtension != NULL) {
  560.         SECITEM_FreeItem (&(inExtension->id), PR_FALSE);
  561. SECITEM_FreeItem (&(inExtension->value), PR_FALSE);
  562. SECITEM_FreeItem (&(inExtension->critical), PR_FALSE);
  563. if (freeit) {
  564.     PORT_Free(inExtension);
  565. }
  566.     }
  567.     return SECSuccess;
  568. }
  569. SECStatus
  570. CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
  571. {
  572.     return crmf_destroy_cert_extension(inExtension, PR_TRUE);
  573. }
  574. SECStatus
  575. CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) 
  576. {
  577.     PORT_Assert (inCertReqMsgs != NULL);
  578.     if (inCertReqMsgs != NULL) {
  579.         PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
  580.     }
  581.     return SECSuccess;
  582. }
  583. static PRBool
  584. crmf_item_has_data(SECItem *item)
  585. {
  586.     if (item != NULL && item->data != NULL) {
  587.         return PR_TRUE;
  588.     }
  589.     return PR_FALSE;
  590. }
  591. PRBool
  592. CRMF_CertRequestIsFieldPresent(CRMFCertRequest       *inCertReq,
  593.        CRMFCertTemplateField  inTemplateField)
  594. {
  595.     PRBool             retVal;
  596.     CRMFCertTemplate *certTemplate;
  597.     PORT_Assert(inCertReq != NULL);
  598.     if (inCertReq == NULL) {
  599.         /* This is probably some kind of error, but this is 
  600.  * the safest return value for this function.
  601.  */
  602.         return PR_FALSE;
  603.     }
  604.     certTemplate = &inCertReq->certTemplate;
  605.     switch (inTemplateField) {
  606.     case crmfVersion:
  607.       retVal = crmf_item_has_data(&certTemplate->version);
  608.       break;
  609.     case crmfSerialNumber:
  610.       retVal = crmf_item_has_data(&certTemplate->serialNumber);
  611.       break;
  612.     case crmfSigningAlg:
  613.       retVal = IS_NOT_NULL(certTemplate->signingAlg);
  614.       break;
  615.     case crmfIssuer:
  616.       retVal = IS_NOT_NULL(certTemplate->issuer);
  617.       break;
  618.     case crmfValidity:
  619.       retVal = IS_NOT_NULL(certTemplate->validity);
  620.       break;
  621.     case crmfSubject:
  622.       retVal = IS_NOT_NULL(certTemplate->subject);
  623.       break;
  624.     case crmfPublicKey:
  625.       retVal = IS_NOT_NULL(certTemplate->publicKey);
  626.       break;
  627.     case crmfIssuerUID:
  628.       retVal = crmf_item_has_data(&certTemplate->issuerUID);
  629.       break;
  630.     case crmfSubjectUID:
  631.       retVal = crmf_item_has_data(&certTemplate->subjectUID);
  632.       break;
  633.     case crmfExtension:
  634.       retVal = IS_NOT_NULL(certTemplate->extensions);
  635.       break;
  636.     default:
  637.       retVal = PR_FALSE;
  638.     }
  639.     return retVal;
  640. }