Back to index

lightning-sunbird  0.9+nobinonly
crmfget.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 CRMFPOPChoice
00045 CRMF_CertReqMsgGetPOPType(CRMFCertReqMsg *inCertReqMsg)
00046 {
00047     PORT_Assert(inCertReqMsg != NULL);
00048     if (inCertReqMsg != NULL && inCertReqMsg->pop != NULL) {
00049         return inCertReqMsg->pop->popUsed;
00050     }
00051     return crmfNoPOPChoice;
00052 }
00053 
00054 static SECStatus
00055 crmf_destroy_validity(CRMFOptionalValidity *inValidity, PRBool freeit)
00056 {
00057     if (inValidity != NULL){
00058         if (inValidity->notBefore.data != NULL) {
00059            PORT_Free(inValidity->notBefore.data);
00060        }
00061        if (inValidity->notAfter.data != NULL) {
00062            PORT_Free(inValidity->notAfter.data);
00063        }
00064        if (freeit) {
00065            PORT_Free(inValidity);
00066        }
00067     }
00068     return SECSuccess;
00069 }
00070 
00071 static SECStatus 
00072 crmf_copy_cert_request_validity(PRArenaPool           *poolp,
00073                             CRMFOptionalValidity **destValidity,
00074                             CRMFOptionalValidity  *srcValidity)
00075 {
00076     CRMFOptionalValidity *myValidity = NULL;
00077     SECStatus             rv;
00078 
00079     *destValidity = myValidity = (poolp == NULL) ?
00080                                   PORT_ZNew(CRMFOptionalValidity) :
00081                                   PORT_ArenaZNew(poolp, CRMFOptionalValidity);
00082     if (myValidity == NULL) {
00083         goto loser;
00084     }
00085     if (srcValidity->notBefore.data != NULL) {
00086         rv = SECITEM_CopyItem(poolp, &myValidity->notBefore, 
00087                            &srcValidity->notBefore);
00088        if (rv != SECSuccess) {
00089            goto loser;
00090        }
00091     }
00092     if (srcValidity->notAfter.data != NULL) {
00093         rv = SECITEM_CopyItem(poolp, &myValidity->notAfter, 
00094                            &srcValidity->notAfter);
00095        if (rv != SECSuccess) {
00096            goto loser;
00097        }
00098     }
00099     return SECSuccess;
00100  loser:
00101     if (myValidity != NULL && poolp == NULL) {
00102         crmf_destroy_validity(myValidity, PR_TRUE);
00103     }
00104     return SECFailure;
00105 }
00106 
00107 static SECStatus
00108 crmf_copy_extensions(PRArenaPool        *poolp, 
00109                    CRMFCertTemplate   *destTemplate,
00110                    CRMFCertExtension **srcExt)
00111 {
00112     int       numExt = 0, i;
00113     CRMFCertExtension **myExtArray = NULL;
00114 
00115     while (srcExt[numExt] != NULL) {
00116         numExt++;
00117     }
00118     if (numExt == 0) {
00119         /*No extensions to copy.*/
00120         destTemplate->extensions = NULL;
00121        destTemplate->numExtensions = 0;
00122         return SECSuccess;
00123     }
00124     destTemplate->extensions = myExtArray = 
00125                            PORT_NewArray(CRMFCertExtension*, numExt+1);
00126     if (myExtArray == NULL) {
00127         goto loser;
00128     }
00129      
00130     for (i=0; i<numExt; i++) {
00131         myExtArray[i] = crmf_copy_cert_extension(poolp, srcExt[i]);
00132        if (myExtArray[i] == NULL) {
00133            goto loser;
00134        }
00135     }
00136     destTemplate->numExtensions = numExt;
00137     myExtArray[numExt] = NULL;
00138     return SECSuccess;
00139  loser:
00140     if (myExtArray != NULL) {
00141         if (poolp == NULL) {
00142            for (i=0; myExtArray[i] != NULL; i++) {
00143                CRMF_DestroyCertExtension(myExtArray[i]);
00144            }
00145        }
00146        PORT_Free(myExtArray);
00147     }
00148     destTemplate->extensions = NULL;
00149     destTemplate->numExtensions = 0;
00150     return SECFailure;
00151 }
00152 
00153 static SECStatus
00154 crmf_copy_cert_request_template(PRArenaPool      *poolp, 
00155                             CRMFCertTemplate *destTemplate,
00156                             CRMFCertTemplate *srcTemplate)
00157 {
00158     SECStatus rv;
00159 
00160     if (srcTemplate->version.data != NULL) {
00161         rv = SECITEM_CopyItem(poolp, &destTemplate->version, 
00162                            &srcTemplate->version);
00163        if (rv != SECSuccess) {
00164            goto loser;
00165        }
00166     }
00167     if (srcTemplate->serialNumber.data != NULL) {
00168         rv = SECITEM_CopyItem(poolp, &destTemplate->serialNumber,
00169                            &srcTemplate->serialNumber);
00170        if (rv != SECSuccess) {
00171            goto loser;
00172        }
00173     }
00174     if (srcTemplate->signingAlg != NULL) {
00175         rv = crmf_template_copy_secalg(poolp, &destTemplate->signingAlg,
00176                                    srcTemplate->signingAlg);
00177        if (rv != SECSuccess) {
00178            goto loser;
00179        }
00180     }
00181     if (srcTemplate->issuer != NULL) {
00182         rv = crmf_copy_cert_name(poolp, &destTemplate->issuer,
00183                              srcTemplate->issuer);
00184        if (rv != SECSuccess) {
00185            goto loser;
00186        }
00187     }
00188     if (srcTemplate->validity != NULL) {
00189         rv = crmf_copy_cert_request_validity(poolp, &destTemplate->validity,
00190                                         srcTemplate->validity);
00191        if (rv != SECSuccess) {
00192            goto loser;
00193        }
00194     }
00195     if (srcTemplate->subject != NULL) {
00196         rv = crmf_copy_cert_name(poolp, &destTemplate->subject, 
00197                              srcTemplate->subject);
00198        if (rv != SECSuccess) {
00199            goto loser;
00200        }
00201     }
00202     if (srcTemplate->publicKey != NULL) {
00203         rv = crmf_template_add_public_key(poolp, &destTemplate->publicKey,
00204                                      srcTemplate->publicKey);
00205        if (rv != SECSuccess) {
00206            goto loser;
00207        }
00208     }
00209     if (srcTemplate->issuerUID.data != NULL) {
00210         rv = crmf_make_bitstring_copy(poolp, &destTemplate->issuerUID,
00211                                   &srcTemplate->issuerUID);
00212        if (rv != SECSuccess) {
00213            goto loser;
00214        }
00215     }
00216     if (srcTemplate->subjectUID.data != NULL) {
00217         rv = crmf_make_bitstring_copy(poolp, &destTemplate->subjectUID,
00218                                   &srcTemplate->subjectUID);
00219        if (rv != SECSuccess) {
00220            goto loser;
00221        }
00222     }
00223     if (srcTemplate->extensions != NULL) {
00224         rv = crmf_copy_extensions(poolp, destTemplate,
00225                               srcTemplate->extensions);
00226        if (rv != SECSuccess) {
00227            goto loser;
00228        }
00229     }
00230     return SECSuccess;
00231  loser:
00232     return SECFailure;
00233 }
00234 
00235 static CRMFControl*
00236 crmf_copy_control(PRArenaPool *poolp, CRMFControl *srcControl)
00237 {
00238     CRMFControl *newControl;
00239     SECStatus    rv;
00240 
00241     newControl = (poolp == NULL) ? PORT_ZNew(CRMFControl) :
00242                                    PORT_ArenaZNew(poolp, CRMFControl);
00243     if (newControl == NULL) {
00244         goto loser;
00245     }
00246     newControl->tag = srcControl->tag;
00247     rv = SECITEM_CopyItem(poolp, &newControl->derTag, &srcControl->derTag);
00248     if (rv != SECSuccess) {
00249         goto loser;
00250     }
00251     rv = SECITEM_CopyItem(poolp, &newControl->derValue, &srcControl->derValue);
00252     if (rv != SECSuccess) {
00253         goto loser;
00254     }
00255     /* We only handle PKIArchiveOptions Control right now.  But if in
00256      * the future, more controls that are part of the union are added,
00257      * then they need to be handled here as well.
00258      */
00259     switch (newControl->tag) {
00260     case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
00261         rv = crmf_copy_pkiarchiveoptions(poolp, 
00262                                     &newControl->value.archiveOptions,
00263                                     &srcControl->value.archiveOptions);
00264       break;
00265     default:
00266         rv = SECSuccess;
00267     }
00268     if (rv != SECSuccess) {
00269         goto loser;
00270     }
00271     return newControl;
00272 
00273  loser:
00274     if (poolp == NULL && newControl != NULL) {
00275         CRMF_DestroyControl(newControl);
00276     }
00277     return NULL;
00278 }
00279 
00280 static SECStatus
00281 crmf_copy_cert_request_controls(PRArenaPool     *poolp, 
00282                             CRMFCertRequest *destReq, 
00283                             CRMFCertRequest *srcReq)
00284 {
00285     int           numControls, i;
00286     CRMFControl **myControls = NULL;
00287 
00288     numControls = CRMF_CertRequestGetNumControls(srcReq);
00289     if (numControls == 0) {
00290         /* No Controls To Copy*/
00291         return SECSuccess;
00292     }
00293     myControls = destReq->controls = PORT_NewArray(CRMFControl*, 
00294                                              numControls+1);
00295     if (myControls == NULL) {
00296         goto loser;
00297     }
00298     for (i=0; i<numControls; i++) {
00299         myControls[i] = crmf_copy_control(poolp, srcReq->controls[i]);
00300        if (myControls[i] == NULL) {
00301            goto loser;
00302        }
00303     }
00304     myControls[numControls] = NULL;
00305     return SECSuccess;
00306  loser:
00307     if (myControls != NULL) {
00308         if (poolp == NULL) {
00309            for (i=0; myControls[i] != NULL; i++) {
00310                CRMF_DestroyControl(myControls[i]);
00311            }
00312        }
00313        PORT_Free(myControls);
00314     }
00315     return SECFailure;
00316 }
00317 
00318 
00319 CRMFCertRequest*
00320 crmf_copy_cert_request(PRArenaPool *poolp, CRMFCertRequest *srcReq)
00321 {
00322     CRMFCertRequest *newReq = NULL;
00323     SECStatus        rv;
00324 
00325     if (srcReq == NULL) {
00326         return NULL;
00327     }
00328     newReq = (poolp == NULL) ? PORT_ZNew(CRMFCertRequest) :
00329                                PORT_ArenaZNew(poolp, CRMFCertRequest);
00330     if (newReq == NULL) {
00331         goto loser;
00332     }
00333     rv = SECITEM_CopyItem(poolp, &newReq->certReqId, &srcReq->certReqId);
00334     if (rv != SECSuccess) {
00335         goto loser;
00336     }
00337     rv = crmf_copy_cert_request_template(poolp, &newReq->certTemplate, 
00338                                     &srcReq->certTemplate);
00339     if (rv != SECSuccess) {
00340         goto loser;
00341     }
00342     rv = crmf_copy_cert_request_controls(poolp, newReq, srcReq);
00343     if (rv != SECSuccess) {
00344         goto loser;
00345     }
00346     return newReq;
00347  loser:
00348     if (newReq != NULL && poolp == NULL) {
00349         CRMF_DestroyCertRequest(newReq);
00350     }
00351     return NULL;
00352 }
00353 
00354 SECStatus 
00355 CRMF_DestroyGetValidity(CRMFGetValidity *inValidity)
00356 {
00357     PORT_Assert(inValidity != NULL);
00358     if (inValidity != NULL) {
00359         if (inValidity->notAfter) {
00360            PORT_Free(inValidity->notAfter);
00361            inValidity->notAfter = NULL;
00362        }
00363        if (inValidity->notBefore) {
00364            PORT_Free(inValidity->notBefore);
00365            inValidity->notBefore = NULL;
00366        }
00367     }
00368     return SECSuccess;
00369 }
00370 
00371 SECStatus
00372 crmf_make_bitstring_copy(PRArenaPool *arena, SECItem *dest, SECItem *src)
00373 {
00374     int origLenBits;
00375     int bytesToCopy;
00376     SECStatus rv;
00377 
00378     origLenBits = src->len;
00379     bytesToCopy = CRMF_BITS_TO_BYTES(origLenBits);
00380     src->len = bytesToCopy;         
00381     rv = SECITEM_CopyItem(arena, dest, src);
00382     src->len = origLenBits;
00383     if (rv != SECSuccess) {
00384         return rv;
00385     }
00386     dest->len = origLenBits;
00387     return SECSuccess;
00388 }
00389 
00390 int
00391 CRMF_CertRequestGetNumberOfExtensions(CRMFCertRequest *inCertReq)
00392 {
00393     CRMFCertTemplate *certTemplate;
00394     int count = 0;
00395     
00396     certTemplate = &inCertReq->certTemplate;
00397     if (certTemplate->extensions) {
00398         while (certTemplate->extensions[count] != NULL)
00399            count++;
00400     }
00401     return count;
00402 }
00403 
00404 SECOidTag
00405 CRMF_CertExtensionGetOidTag(CRMFCertExtension *inExtension)
00406 {
00407     PORT_Assert(inExtension != NULL);
00408     if (inExtension == NULL) {
00409         return SEC_OID_UNKNOWN;
00410     }
00411     return SECOID_FindOIDTag(&inExtension->id);
00412 }
00413 
00414 PRBool
00415 CRMF_CertExtensionGetIsCritical(CRMFCertExtension *inExt)
00416 {
00417     PORT_Assert(inExt != NULL);
00418     if (inExt == NULL) {
00419         return PR_FALSE;
00420     }
00421     return inExt->critical.data != NULL;
00422 }
00423 
00424 SECItem*
00425 CRMF_CertExtensionGetValue(CRMFCertExtension *inExtension)
00426 {
00427     PORT_Assert(inExtension != NULL);
00428     if (inExtension == NULL) {
00429         return NULL;
00430     }
00431     
00432     return SECITEM_DupItem(&inExtension->value);
00433 }
00434                        
00435 
00436 SECStatus
00437 CRMF_DestroyPOPOSigningKey(CRMFPOPOSigningKey *inKey)
00438 {
00439     PORT_Assert(inKey != NULL);
00440     if (inKey != NULL) {
00441         if (inKey->derInput.data != NULL) {
00442            SECITEM_FreeItem(&inKey->derInput, PR_FALSE);
00443        }
00444        if (inKey->algorithmIdentifier != NULL) {
00445            SECOID_DestroyAlgorithmID(inKey->algorithmIdentifier, PR_TRUE);
00446        }
00447        if (inKey->signature.data != NULL) {
00448            SECITEM_FreeItem(&inKey->signature, PR_FALSE);
00449        }
00450        PORT_Free(inKey);
00451     }
00452     return SECSuccess;
00453 }
00454 
00455 SECStatus
00456 CRMF_DestroyPOPOPrivKey(CRMFPOPOPrivKey *inPrivKey)
00457 {
00458     PORT_Assert(inPrivKey != NULL);
00459     if (inPrivKey != NULL) {
00460         SECITEM_FreeItem(&inPrivKey->message.thisMessage, PR_FALSE);
00461        PORT_Free(inPrivKey);
00462     }
00463     return SECSuccess;
00464 }
00465 
00466 int
00467 CRMF_CertRequestGetNumControls(CRMFCertRequest *inCertReq)
00468 {
00469     int              count = 0;
00470 
00471     PORT_Assert(inCertReq != NULL);
00472     if (inCertReq == NULL) {
00473         return 0;
00474     }
00475     if (inCertReq->controls) {
00476         while (inCertReq->controls[count] != NULL)
00477            count++;
00478     }
00479     return count;
00480 }
00481