Back to index

lightning-sunbird  0.9+nobinonly
crmfreq.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8 -*-*/
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape security libraries.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "crmf.h"
00039 #include "crmfi.h"
00040 #include "keyhi.h"
00041 #include "secder.h"
00042 
00043 /*
00044  * Macro that returns PR_TRUE if the pointer is not NULL.
00045  * If the pointer is NULL, then the macro will return PR_FALSE.
00046  */
00047 #define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE
00048 
00049 const unsigned char hexTrue  = 0xff;
00050 const unsigned char hexFalse = 0x00;
00051 
00052 
00053 SECStatus
00054 crmf_encode_integer(PRArenaPool *poolp, SECItem *dest, long value) 
00055 {
00056     SECItem *dummy;
00057 
00058     dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
00059     PORT_Assert (dummy == dest);
00060     if (dummy == NULL) {
00061         return SECFailure;
00062     }
00063     return SECSuccess;
00064 }
00065 
00066 SECStatus
00067 crmf_encode_unsigned_integer(PRArenaPool *poolp, SECItem *dest, 
00068                              unsigned long value) 
00069 {
00070     SECItem *dummy;
00071 
00072     dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
00073     PORT_Assert (dummy == dest);
00074     if (dummy != dest) {
00075         return SECFailure;
00076     }
00077     return SECSuccess;
00078 }
00079 
00080 static SECStatus
00081 crmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src)
00082 {
00083     return  SECITEM_CopyItem (poolp, dest, src); 
00084 }
00085 
00086 PRBool
00087 CRMF_DoesRequestHaveField (CRMFCertRequest       *inCertReq, 
00088                         CRMFCertTemplateField  inField)
00089 {
00090   
00091     PORT_Assert(inCertReq != NULL);
00092     if (inCertReq == NULL) {
00093         return PR_FALSE;
00094     }
00095     switch (inField) {
00096     case crmfVersion:
00097         return inCertReq->certTemplate.version.data != NULL;
00098     case crmfSerialNumber:
00099         return inCertReq->certTemplate.serialNumber.data != NULL;
00100     case crmfSigningAlg:
00101         return inCertReq->certTemplate.signingAlg != NULL;
00102     case crmfIssuer:
00103         return inCertReq->certTemplate.issuer != NULL;
00104     case crmfValidity:
00105         return inCertReq->certTemplate.validity != NULL;
00106     case crmfSubject:
00107         return inCertReq->certTemplate.subject != NULL;
00108     case crmfPublicKey:
00109         return inCertReq->certTemplate.publicKey != NULL;
00110     case crmfIssuerUID:
00111         return inCertReq->certTemplate.issuerUID.data != NULL;
00112     case crmfSubjectUID:
00113         return inCertReq->certTemplate.subjectUID.data != NULL;
00114     case crmfExtension:
00115         return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
00116     }
00117     return PR_FALSE;
00118 }
00119 
00120 CRMFCertRequest *
00121 CRMF_CreateCertRequest (PRUint32 inRequestID)
00122 {
00123     PRArenaPool     *poolp;
00124     CRMFCertRequest *certReq;
00125     SECStatus        rv;
00126     
00127     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
00128     if (poolp == NULL) {
00129         goto loser;
00130     }
00131     
00132     certReq=PORT_ArenaZNew(poolp,CRMFCertRequest);
00133     if (certReq == NULL) {
00134         goto loser;
00135     }
00136 
00137     certReq->poolp = poolp;
00138     certReq->requestID = inRequestID;
00139     
00140     rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), 
00141                                       inRequestID);
00142     if (rv != SECSuccess) {
00143         goto loser;
00144     }
00145 
00146     return certReq;
00147  loser:
00148     if (poolp) {
00149         PORT_FreeArena(poolp, PR_FALSE);
00150     }
00151     return NULL;
00152 }
00153 
00154 SECStatus
00155 CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
00156 {
00157     PORT_Assert(inCertReq != NULL);
00158     if (inCertReq != NULL) {
00159         if (inCertReq->certTemplate.extensions) {
00160            PORT_Free(inCertReq->certTemplate.extensions);
00161        }
00162        if (inCertReq->controls) {
00163            /* Right now we don't support EnveloppedData option,
00164             * so we won't go through and delete each occurrence of 
00165             * an EnveloppedData in the control.
00166             */
00167            PORT_Free(inCertReq->controls);
00168        }
00169        if (inCertReq->poolp) {
00170            PORT_FreeArena(inCertReq->poolp, PR_TRUE);
00171        }
00172     }
00173     return SECSuccess;
00174 }
00175 
00176 static SECStatus
00177 crmf_template_add_version(PRArenaPool *poolp, SECItem *dest, long version)
00178 {
00179     return (crmf_encode_integer(poolp, dest, version));
00180 }
00181 
00182 static SECStatus
00183 crmf_template_add_serialnumber(PRArenaPool *poolp, SECItem *dest, long serial)
00184 {
00185     return (crmf_encode_integer(poolp, dest, serial));
00186 }
00187 
00188 SECStatus
00189 crmf_template_copy_secalg (PRArenaPool *poolp, SECAlgorithmID **dest, 
00190                         SECAlgorithmID* src)
00191 {
00192     SECStatus         rv;
00193     void             *mark = NULL;
00194     SECAlgorithmID   *mySecAlg;
00195 
00196     if (!poolp) {
00197         PORT_SetError(SEC_ERROR_INVALID_ARGS);
00198         return SECFailure;
00199     }
00200 
00201     mark = PORT_ArenaMark(poolp);
00202     *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
00203     if (mySecAlg == NULL) {
00204         goto loser;
00205     }
00206     rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
00207     if (rv != SECSuccess) {
00208         goto loser;
00209     }
00210     if (mark) {
00211         PORT_ArenaUnmark(poolp, mark);
00212     }
00213     return SECSuccess;
00214 
00215  loser:
00216     *dest = NULL;
00217     if (mark) {
00218         PORT_ArenaRelease(poolp, mark);
00219     }
00220     return SECFailure;
00221 }
00222 
00223 SECStatus
00224 crmf_copy_cert_name(PRArenaPool *poolp, CERTName **dest, 
00225                   CERTName *src)
00226 {
00227     CERTName *newName;
00228     SECStatus rv;
00229     void     *mark;
00230 
00231     mark = PORT_ArenaMark(poolp);
00232     *dest = newName = PORT_ArenaZNew(poolp, CERTName);
00233     if (newName == NULL) {
00234         goto loser;
00235     }
00236 
00237     rv = CERT_CopyName(poolp, newName, src);
00238     if (rv != SECSuccess) {
00239       goto loser;
00240     }
00241     PORT_ArenaUnmark(poolp, mark);
00242     return SECSuccess;
00243  loser:
00244     PORT_ArenaRelease(poolp, mark);
00245     *dest = NULL;
00246     return SECFailure;
00247 }
00248 
00249 static SECStatus
00250 crmf_template_add_issuer (PRArenaPool *poolp, CERTName **dest, 
00251                        CERTName* issuerName)
00252 {
00253     return crmf_copy_cert_name(poolp, dest, issuerName);
00254 }
00255 
00256 
00257 static SECStatus
00258 crmf_template_add_validity (PRArenaPool *poolp, CRMFOptionalValidity **dest,
00259                          CRMFValidityCreationInfo *info)
00260 {
00261     SECStatus             rv;
00262     void                 *mark; 
00263     CRMFOptionalValidity *myValidity;
00264 
00265     /*First off, let's make sure at least one of the two fields is present*/
00266     if (!info  || (!info->notBefore && !info->notAfter)) {
00267         return SECFailure;
00268     }
00269     mark = PORT_ArenaMark (poolp);
00270     *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
00271     if (myValidity == NULL) {
00272         goto loser;
00273     }
00274 
00275     if (info->notBefore) {
00276         rv = DER_EncodeTimeChoice (poolp, &myValidity->notBefore, 
00277                               *info->notBefore);
00278        if (rv != SECSuccess) {
00279            goto loser;
00280        }
00281     }
00282     if (info->notAfter) {
00283         rv = DER_EncodeTimeChoice (poolp, &myValidity->notAfter,
00284                               *info->notAfter);
00285        if (rv != SECSuccess) {
00286            goto loser;
00287        }
00288     }
00289     PORT_ArenaUnmark(poolp, mark);
00290     return SECSuccess;
00291  loser:
00292     PORT_ArenaRelease(poolp, mark);
00293     *dest = NULL;
00294     return SECFailure;
00295 }
00296 
00297 static SECStatus
00298 crmf_template_add_subject (PRArenaPool *poolp, CERTName **dest,
00299                         CERTName *subject)
00300 {
00301     return crmf_copy_cert_name(poolp, dest, subject);
00302 }
00303 
00304 SECStatus
00305 crmf_template_add_public_key(PRArenaPool *poolp, 
00306                           CERTSubjectPublicKeyInfo **dest,
00307                           CERTSubjectPublicKeyInfo  *pubKey)
00308 {
00309     CERTSubjectPublicKeyInfo *spki;
00310     SECStatus rv;
00311 
00312     *dest = spki = (poolp == NULL) ?
00313                               PORT_ZNew(CERTSubjectPublicKeyInfo) :
00314                               PORT_ArenaZNew (poolp, CERTSubjectPublicKeyInfo);
00315     if (spki == NULL) {
00316         goto loser;
00317     }
00318     rv = SECKEY_CopySubjectPublicKeyInfo (poolp, spki, pubKey);
00319     if (rv != SECSuccess) {
00320         goto loser;
00321     }
00322     return SECSuccess;
00323  loser:
00324     if (poolp == NULL && spki != NULL) {
00325         SECKEY_DestroySubjectPublicKeyInfo(spki);
00326     }
00327     *dest = NULL;
00328     return SECFailure;
00329 }
00330 
00331 static SECStatus
00332 crmf_copy_bitstring (PRArenaPool *poolp, SECItem *dest, SECItem *src)
00333 {
00334     SECStatus rv;
00335     int origLenBits, numBytesToCopy;
00336     
00337     origLenBits = src->len;
00338     numBytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
00339     rv = crmf_copy_secitem(poolp, dest, src);
00340     src->len = origLenBits;
00341     dest->len = origLenBits;
00342     return rv;
00343 }
00344 
00345 static SECStatus
00346 crmf_template_add_issuer_uid(PRArenaPool *poolp, SECItem *dest,
00347                           SECItem *issuerUID)
00348 {
00349     return crmf_copy_bitstring (poolp, dest, issuerUID);
00350 }
00351 
00352 static SECStatus
00353 crmf_template_add_subject_uid(PRArenaPool *poolp, SECItem *dest, 
00354                            SECItem *subjectUID)
00355 {
00356     return crmf_copy_bitstring (poolp, dest, subjectUID);
00357 }
00358 
00359 static void
00360 crmf_zeroize_new_extensions (CRMFCertExtension **extensions,
00361                           int numToZeroize) 
00362 {
00363     PORT_Memset((void*)extensions, 0, sizeof(CERTCertExtension*)*numToZeroize);
00364 }
00365 
00366 /*
00367  * The strategy for adding templates will differ from all the other
00368  * attributes in the template.  First, we want to allow the client
00369  * of this API to set extensions more than just once.  So we will
00370  * need the ability grow the array of extensions.  Since arenas don't
00371  * give us the realloc function, we'll use the generic PORT_* functions
00372  * to allocate the array of pointers *ONLY*.  Then we will allocate each
00373  * individual extension from the arena that comes along with the certReq
00374  * structure that owns this template.
00375  */
00376 static SECStatus
00377 crmf_template_add_extensions(PRArenaPool *poolp, CRMFCertTemplate *inTemplate,
00378                           CRMFCertExtCreationInfo *extensions)
00379 {
00380     void               *mark;
00381     int                 newSize, oldSize, i;
00382     SECStatus           rv;
00383     CRMFCertExtension **extArray;
00384     CRMFCertExtension  *newExt, *currExt;
00385 
00386     mark = PORT_ArenaMark(poolp);
00387     if (inTemplate->extensions == NULL) {
00388         newSize = extensions->numExtensions;
00389         extArray = PORT_ZNewArray(CRMFCertExtension*,newSize+1);
00390     } else {
00391         newSize = inTemplate->numExtensions + extensions->numExtensions;
00392         extArray = PORT_Realloc(inTemplate->extensions, 
00393                             sizeof(CRMFCertExtension*)*(newSize+1));
00394     }
00395     if (extArray == NULL) {
00396         goto loser;
00397     }
00398     oldSize                   = inTemplate->numExtensions;
00399     inTemplate->extensions    = extArray;
00400     inTemplate->numExtensions = newSize;
00401     for (i=oldSize; i < newSize; i++) {
00402         newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
00403        if (newExt == NULL) {
00404            goto loser2;
00405        }
00406        currExt = extensions->extensions[i-oldSize];
00407        rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
00408        if (rv != SECSuccess) {
00409            goto loser2;
00410        }
00411        rv = crmf_copy_secitem(poolp, &(newExt->critical),
00412                             &(currExt->critical));
00413        if (rv != SECSuccess) {
00414            goto loser2;
00415        }
00416        rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
00417        if (rv != SECSuccess) {
00418            goto loser2;
00419        }
00420        extArray[i] = newExt;
00421     }
00422     extArray[newSize] = NULL;
00423     PORT_ArenaUnmark(poolp, mark);
00424     return SECSuccess;
00425  loser2:
00426     crmf_zeroize_new_extensions (&(inTemplate->extensions[oldSize]),
00427                              extensions->numExtensions);
00428     inTemplate->numExtensions = oldSize;
00429  loser:
00430     PORT_ArenaRelease(poolp, mark);
00431     return SECFailure;
00432 }
00433 
00434 SECStatus
00435 CRMF_CertRequestSetTemplateField(CRMFCertRequest       *inCertReq, 
00436                              CRMFCertTemplateField  inTemplateField,
00437                              void                  *data)
00438 {
00439     CRMFCertTemplate *certTemplate;
00440     PRArenaPool      *poolp;
00441     SECStatus         rv = SECFailure;
00442     void             *mark;
00443     
00444 
00445     if (inCertReq == NULL) {
00446         return SECFailure;
00447     }
00448 
00449     certTemplate = &(inCertReq->certTemplate);
00450 
00451     poolp = inCertReq->poolp;
00452     mark = PORT_ArenaMark(poolp);
00453     switch (inTemplateField) {
00454     case crmfVersion:
00455       rv = crmf_template_add_version(poolp,&(certTemplate->version), 
00456                                  *(long*)data);
00457       break;
00458     case crmfSerialNumber:
00459       rv = crmf_template_add_serialnumber(poolp, 
00460                                      &(certTemplate->serialNumber),
00461                                      *(long*)data);
00462       break;
00463     case crmfSigningAlg:
00464       rv = crmf_template_copy_secalg (poolp, &(certTemplate->signingAlg),
00465                                   (SECAlgorithmID*)data);
00466       break;
00467     case crmfIssuer:
00468       rv = crmf_template_add_issuer (poolp, &(certTemplate->issuer), 
00469                                  (CERTName*)data);
00470       break;
00471     case crmfValidity:
00472       rv = crmf_template_add_validity (poolp, &(certTemplate->validity),
00473                                    (CRMFValidityCreationInfo*)data);
00474       break;
00475     case crmfSubject:
00476       rv = crmf_template_add_subject (poolp, &(certTemplate->subject),
00477                                   (CERTName*)data);
00478       break;
00479     case crmfPublicKey:
00480       rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
00481                                    (CERTSubjectPublicKeyInfo*)data);
00482       break;
00483     case crmfIssuerUID:
00484       rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
00485                                    (SECItem*)data);
00486       break;
00487     case crmfSubjectUID:
00488       rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
00489                                     (SECItem*)data);
00490       break;
00491     case crmfExtension:
00492       rv = crmf_template_add_extensions(poolp, certTemplate, 
00493                                    (CRMFCertExtCreationInfo*)data);
00494       break;
00495     }
00496     if (rv != SECSuccess) {
00497         PORT_ArenaRelease(poolp, mark);
00498     } else {
00499         PORT_ArenaUnmark(poolp, mark);
00500     }
00501     return rv;
00502 }
00503 
00504 SECStatus
00505 CRMF_CertReqMsgSetCertRequest (CRMFCertReqMsg  *inCertReqMsg, 
00506                             CRMFCertRequest *inCertReq)
00507 {
00508     PORT_Assert (inCertReqMsg != NULL && inCertReq != NULL);
00509     if (inCertReqMsg == NULL || inCertReq == NULL) {
00510         return SECFailure;
00511     }
00512     inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
00513                                              inCertReq);
00514     return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
00515 }
00516 
00517 CRMFCertReqMsg*
00518 CRMF_CreateCertReqMsg(void)
00519 {
00520     PRArenaPool    *poolp;
00521     CRMFCertReqMsg *reqMsg;
00522 
00523     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
00524     if (poolp == NULL) {
00525         goto loser;
00526     }
00527     reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
00528     if (reqMsg == NULL) {
00529         goto loser;
00530     }
00531     reqMsg->poolp = poolp;
00532     return reqMsg;
00533     
00534  loser:
00535     if (poolp) {
00536         PORT_FreeArena(poolp, PR_FALSE);
00537     }
00538     return NULL;
00539 }
00540 
00541 SECStatus 
00542 CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
00543 {
00544     PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
00545     if (!inCertReqMsg->isDecoded) {
00546         if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
00547            PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
00548        }
00549        if (inCertReqMsg->certReq->controls != NULL) {
00550            PORT_Free(inCertReqMsg->certReq->controls);
00551        }
00552     }
00553     PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
00554     return SECSuccess;
00555 }
00556 
00557 CRMFCertExtension*
00558 crmf_create_cert_extension(PRArenaPool *poolp, 
00559                         SECOidTag    id,
00560                         PRBool       isCritical,
00561                         SECItem     *data)
00562 {
00563     CRMFCertExtension *newExt;
00564     SECOidData        *oidData;
00565     SECStatus          rv;
00566 
00567     newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) :
00568                                PORT_ArenaZNew(poolp, CRMFCertExtension);
00569     if (newExt == NULL) {
00570         goto loser;
00571     }
00572     oidData = SECOID_FindOIDByTag(id);
00573     if (oidData == NULL || 
00574        oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
00575        goto loser;
00576     }
00577 
00578     rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
00579     if (rv != SECSuccess) {
00580         goto loser;
00581     }
00582 
00583     rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
00584     if (rv != SECSuccess) {
00585         goto loser;
00586     }
00587 
00588     if (isCritical) {
00589         newExt->critical.data = (poolp == NULL) ? 
00590                                        PORT_New(unsigned char) :
00591                                        PORT_ArenaNew(poolp, unsigned char);
00592        if (newExt->critical.data == NULL) {
00593            goto loser;
00594        }
00595        newExt->critical.data[0] = hexTrue;
00596        newExt->critical.len = 1;
00597     }
00598     return newExt;
00599  loser:
00600     if (newExt != NULL && poolp == NULL) {
00601         CRMF_DestroyCertExtension(newExt);
00602     }
00603     return NULL;
00604 }
00605 
00606 CRMFCertExtension *
00607 CRMF_CreateCertExtension(SECOidTag id,
00608                       PRBool    isCritical,
00609                       SECItem  *data) 
00610 {
00611     return crmf_create_cert_extension(NULL, id, isCritical, data);
00612 }
00613 
00614 SECStatus
00615 crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
00616 {
00617     if (inExtension != NULL) {
00618         SECITEM_FreeItem (&(inExtension->id), PR_FALSE);
00619        SECITEM_FreeItem (&(inExtension->value), PR_FALSE);
00620        SECITEM_FreeItem (&(inExtension->critical), PR_FALSE);
00621        if (freeit) {
00622            PORT_Free(inExtension);
00623        }
00624     }
00625     return SECSuccess;
00626 }
00627 
00628 SECStatus
00629 CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
00630 {
00631     return crmf_destroy_cert_extension(inExtension, PR_TRUE);
00632 }
00633 
00634 SECStatus
00635 CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs) 
00636 {
00637     PORT_Assert (inCertReqMsgs != NULL);
00638     if (inCertReqMsgs != NULL) {
00639         PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
00640     }
00641     return SECSuccess;
00642 }
00643 
00644 static PRBool
00645 crmf_item_has_data(SECItem *item)
00646 {
00647     if (item != NULL && item->data != NULL) {
00648         return PR_TRUE;
00649     }
00650     return PR_FALSE;
00651 }
00652 
00653 PRBool
00654 CRMF_CertRequestIsFieldPresent(CRMFCertRequest       *inCertReq,
00655                             CRMFCertTemplateField  inTemplateField)
00656 {
00657     PRBool             retVal;
00658     CRMFCertTemplate *certTemplate;
00659 
00660     PORT_Assert(inCertReq != NULL);
00661     if (inCertReq == NULL) {
00662         /* This is probably some kind of error, but this is 
00663         * the safest return value for this function.
00664         */
00665         return PR_FALSE;
00666     }
00667     certTemplate = &inCertReq->certTemplate;
00668     switch (inTemplateField) {
00669     case crmfVersion:
00670       retVal = crmf_item_has_data(&certTemplate->version);
00671       break;
00672     case crmfSerialNumber:
00673       retVal = crmf_item_has_data(&certTemplate->serialNumber);
00674       break;
00675     case crmfSigningAlg:
00676       retVal = IS_NOT_NULL(certTemplate->signingAlg);
00677       break;
00678     case crmfIssuer:
00679       retVal = IS_NOT_NULL(certTemplate->issuer);
00680       break;
00681     case crmfValidity:
00682       retVal = IS_NOT_NULL(certTemplate->validity);
00683       break;
00684     case crmfSubject:
00685       retVal = IS_NOT_NULL(certTemplate->subject);
00686       break;
00687     case crmfPublicKey:
00688       retVal = IS_NOT_NULL(certTemplate->publicKey);
00689       break;
00690     case crmfIssuerUID:
00691       retVal = crmf_item_has_data(&certTemplate->issuerUID);
00692       break;
00693     case crmfSubjectUID:
00694       retVal = crmf_item_has_data(&certTemplate->subjectUID);
00695       break;
00696     case crmfExtension:
00697       retVal = IS_NOT_NULL(certTemplate->extensions);
00698       break;
00699     default:
00700       retVal = PR_FALSE;
00701     }
00702     return retVal;
00703 }