Back to index

lightning-sunbird  0.9+nobinonly
respcmn.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 "nssrenam.h"
00039 #include "cmmf.h"
00040 #include "cmmfi.h"
00041 #include "secitem.h"
00042 #include "secder.h"
00043 
00044 SECStatus 
00045 cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit)
00046 {
00047     if (info->status.data != NULL) {
00048         PORT_Free(info->status.data);
00049         info->status.data = NULL;
00050     }
00051     if (info->statusString.data != NULL) {
00052         PORT_Free(info->statusString.data);
00053         info->statusString.data = NULL;
00054     }
00055     if (info->failInfo.data != NULL) {
00056         PORT_Free(info->failInfo.data);
00057         info->failInfo.data = NULL;
00058     }
00059     if (freeit) {
00060         PORT_Free(info);
00061     }
00062     return SECSuccess;
00063 }
00064 
00065 SECStatus
00066 CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp)
00067 {
00068     PORT_Assert(inCertResp != NULL);
00069     if (inCertResp != NULL) {
00070         if (inCertResp->certReqId.data != NULL) {
00071            PORT_Free(inCertResp->certReqId.data);
00072        }
00073        cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
00074        if (inCertResp->certifiedKeyPair != NULL) {
00075            CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
00076        }
00077        PORT_Free(inCertResp);
00078     }
00079     return SECSuccess;
00080 }
00081 
00082 SECStatus
00083 CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
00084 {
00085     PORT_Assert(inCertRepContent != NULL);
00086     if (inCertRepContent != NULL) {
00087         CMMFCertResponse   **pResponse = inCertRepContent->response;
00088         if (pResponse != NULL) {
00089             for (; *pResponse != NULL; pResponse++) {
00090                CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair;
00091               /* XXX Why not call CMMF_DestroyCertifiedKeyPair or
00092               ** XXX cmmf_DestroyCertOrEncCert ?  
00093               */
00094                 if (certKeyPair != NULL                    &&
00095                     certKeyPair->certOrEncCert.choice == cmmfCertificate &&
00096                     certKeyPair->certOrEncCert.cert.certificate != NULL) {
00097                     CERT_DestroyCertificate
00098                                  (certKeyPair->certOrEncCert.cert.certificate);
00099                   certKeyPair->certOrEncCert.cert.certificate = NULL;
00100                 }
00101             }
00102         }
00103        if (inCertRepContent->caPubs) {
00104            CERTCertificate     **caPubs = inCertRepContent->caPubs;
00105            for (; *caPubs; ++caPubs) {
00106               CERT_DestroyCertificate(*caPubs);
00107               *caPubs = NULL;
00108            }
00109        }
00110        if (inCertRepContent->poolp != NULL) {
00111            PORT_FreeArena(inCertRepContent->poolp, PR_TRUE);
00112        }
00113     }
00114     return SECSuccess;
00115 }
00116 
00117 SECStatus
00118 CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
00119 {
00120     PORT_Assert(inDecKeyCont != NULL);
00121     if (inDecKeyCont != NULL && inDecKeyCont->poolp) {
00122         PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE);
00123     }
00124     return SECSuccess;
00125 }
00126 
00127 SECStatus
00128 crmf_create_prtime(SECItem *src, PRTime **dest)
00129 {
00130    *dest = PORT_ZNew(PRTime);
00131     return DER_DecodeTimeChoice(*dest, src);
00132 }
00133 
00134 CRMFCertExtension*
00135 crmf_copy_cert_extension(PRArenaPool *poolp, CRMFCertExtension *inExtension)
00136 {
00137     PRBool             isCritical;
00138     SECOidTag          id;
00139     SECItem           *data;
00140     CRMFCertExtension *newExt;
00141 
00142     PORT_Assert(inExtension != NULL);
00143     if (inExtension == NULL) {
00144         return NULL;
00145     }
00146     id         = CRMF_CertExtensionGetOidTag(inExtension);
00147     isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
00148     data       = CRMF_CertExtensionGetValue(inExtension);
00149     newExt = crmf_create_cert_extension(poolp, id, 
00150                                    isCritical,
00151                                    data);
00152     SECITEM_FreeItem(data, PR_TRUE);
00153     return newExt;    
00154 }
00155 
00156 static SECItem*
00157 cmmf_encode_certificate(CERTCertificate *inCert)
00158 {
00159     return SEC_ASN1EncodeItem(NULL, NULL, inCert, 
00160                            SEC_ASN1_GET(SEC_SignedCertificateTemplate));
00161 }
00162 
00163 CERTCertList*
00164 cmmf_MakeCertList(CERTCertificate **inCerts)
00165 {
00166     CERTCertList    *certList;
00167     CERTCertificate *currCert;
00168     SECItem         *derCert, *freeCert = NULL;
00169     SECStatus        rv;
00170     int              i;
00171 
00172     certList = CERT_NewCertList();
00173     if (certList == NULL) {
00174         return NULL;
00175     }
00176     for (i=0; inCerts[i] != NULL; i++) {
00177         derCert = &inCerts[i]->derCert;
00178        if (derCert->data == NULL) {
00179            derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
00180        }
00181        currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 
00182                                         derCert, NULL, PR_FALSE, PR_TRUE);
00183        if (freeCert != NULL) {
00184            SECITEM_FreeItem(freeCert, PR_TRUE);
00185            freeCert = NULL;
00186        }
00187        if (currCert == NULL) {
00188            goto loser;
00189        }
00190        rv = CERT_AddCertToListTail(certList, currCert);
00191        if (rv != SECSuccess) {
00192            goto loser;
00193        }
00194     }
00195     return certList;
00196  loser:
00197     CERT_DestroyCertList(certList);
00198     return NULL;
00199 }
00200 
00201 CMMFPKIStatus
00202 cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus)
00203 {
00204     long derVal;
00205 
00206     derVal = DER_GetInteger(&inStatus->status);
00207     if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) {
00208         return cmmfNoPKIStatus;
00209     }
00210     return (CMMFPKIStatus)derVal;
00211 }
00212 
00213 int
00214 CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
00215 {
00216     int numResponses = 0;
00217     PORT_Assert (inCertRepContent != NULL);
00218     if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
00219         while (inCertRepContent->response[numResponses] != NULL) {
00220            numResponses++;
00221        }
00222     }
00223     return numResponses;
00224 }
00225 
00226 
00227 SECStatus
00228 cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
00229 {
00230     switch (certOrEncCert->choice) {
00231     case cmmfCertificate:
00232         CERT_DestroyCertificate(certOrEncCert->cert.certificate);
00233        certOrEncCert->cert.certificate = NULL;
00234        break;
00235     case cmmfEncryptedCert:
00236         crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert,
00237                                  PR_TRUE);
00238         certOrEncCert->cert.encryptedCert = NULL;
00239        break;
00240     default:
00241         break;
00242     }
00243     if (freeit) {
00244         PORT_Free(certOrEncCert);
00245     }
00246     return SECSuccess;
00247 }
00248 
00249 SECStatus
00250 cmmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src)
00251 {
00252     SECStatus rv;
00253 
00254     if (src->data != NULL) {
00255         rv = SECITEM_CopyItem(poolp, dest, src);
00256     } else {
00257         dest->data = NULL;
00258        dest->len  = 0;
00259        rv = SECSuccess;
00260     }
00261     return rv;
00262 }
00263 
00264 SECStatus
00265 CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
00266 {
00267     PORT_Assert(inCertKeyPair != NULL);
00268     if (inCertKeyPair != NULL) {
00269         cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE);
00270         if (inCertKeyPair->privateKey) {
00271             crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE);
00272         }
00273         if (inCertKeyPair->derPublicationInfo.data) {
00274             PORT_Free(inCertKeyPair->derPublicationInfo.data);
00275         }
00276         PORT_Free(inCertKeyPair);
00277     }
00278     return SECSuccess;
00279 }
00280 
00281 SECStatus
00282 cmmf_CopyCertResponse(PRArenaPool      *poolp, 
00283                     CMMFCertResponse *dest,
00284                     CMMFCertResponse *src)
00285 {
00286     SECStatus rv;
00287 
00288     if (src->certReqId.data != NULL) {
00289         rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId);
00290        if (rv != SECSuccess) {
00291            return rv;
00292        }
00293     }
00294     rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status);
00295     if (rv != SECSuccess) {
00296         return rv;
00297     }
00298     if (src->certifiedKeyPair != NULL) {
00299        CMMFCertifiedKeyPair *destKeyPair;
00300 
00301        destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) :
00302                                PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
00303        if (!destKeyPair) {
00304            return SECFailure;
00305        }
00306        rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair,
00307                                    src->certifiedKeyPair);
00308        if (rv != SECSuccess) {
00309            if (!poolp) {
00310                CMMF_DestroyCertifiedKeyPair(destKeyPair);
00311            }
00312            return rv;
00313        }
00314        dest->certifiedKeyPair = destKeyPair;
00315     }
00316     return SECSuccess;
00317 }
00318 
00319 static SECStatus
00320 cmmf_CopyCertOrEncCert(PRArenaPool *poolp, CMMFCertOrEncCert *dest,
00321                      CMMFCertOrEncCert *src)
00322 {
00323     SECStatus           rv = SECSuccess;
00324     CRMFEncryptedValue *encVal;
00325 
00326     dest->choice = src->choice;
00327     rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue);
00328     switch (src->choice) {
00329     case cmmfCertificate:
00330         dest->cert.certificate = CERT_DupCertificate(src->cert.certificate);
00331        break;
00332     case cmmfEncryptedCert:
00333        encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
00334                                   PORT_ArenaZNew(poolp, CRMFEncryptedValue);
00335        if (encVal == NULL) {
00336            return SECFailure;
00337        }
00338         rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal);
00339        if (rv != SECSuccess) {
00340            if (!poolp) {
00341                crmf_destroy_encrypted_value(encVal, PR_TRUE);
00342            }
00343            return rv;
00344        }
00345        dest->cert.encryptedCert = encVal;        
00346        break;
00347     default:
00348         rv = SECFailure;
00349     }
00350     return rv;
00351 }
00352 
00353 SECStatus
00354 cmmf_CopyCertifiedKeyPair(PRArenaPool *poolp, CMMFCertifiedKeyPair *dest,
00355                        CMMFCertifiedKeyPair *src)
00356 {
00357     SECStatus rv;
00358 
00359     rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert, 
00360                             &src->certOrEncCert);
00361     if (rv != SECSuccess) {
00362         return rv;
00363     }
00364 
00365     if (src->privateKey != NULL) {
00366        CRMFEncryptedValue *encVal;
00367 
00368        encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
00369                                   PORT_ArenaZNew(poolp, CRMFEncryptedValue);
00370        if (encVal == NULL) {
00371            return SECFailure;
00372        }
00373        rv = crmf_copy_encryptedvalue(poolp, src->privateKey, 
00374                                   encVal);
00375        if (rv != SECSuccess) {
00376            if (!poolp) {
00377                crmf_destroy_encrypted_value(encVal, PR_TRUE);
00378            }
00379            return rv;
00380        }
00381        dest->privateKey = encVal;
00382     }
00383     rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, 
00384                         &src->derPublicationInfo);
00385     return rv;
00386 }
00387 
00388 SECStatus
00389 cmmf_CopyPKIStatusInfo(PRArenaPool *poolp, CMMFPKIStatusInfo *dest,
00390                      CMMFPKIStatusInfo *src)
00391 {
00392     SECStatus rv;
00393 
00394     rv = cmmf_copy_secitem (poolp, &dest->status, &src->status);
00395     if (rv != SECSuccess) {
00396         return rv;
00397     }
00398     rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString);
00399     if (rv != SECSuccess) {
00400         return rv;
00401     }
00402     rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo);
00403     return rv;
00404 }
00405 
00406 CERTCertificate*
00407 cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
00408                              CERTCertDBHandle  *certdb)
00409 {
00410     if (certOrEncCert->choice           != cmmfCertificate || 
00411        certOrEncCert->cert.certificate == NULL) {
00412         return NULL;
00413     }
00414     return CERT_NewTempCertificate(certdb,
00415                                &certOrEncCert->cert.certificate->derCert,
00416                                NULL, PR_FALSE, PR_TRUE);
00417 }
00418 
00419 SECStatus 
00420 cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo    *statusInfo,
00421                          PRArenaPool          *poolp,
00422                          CMMFPKIStatus         inStatus)
00423 {
00424     SECItem *dummy;
00425     
00426     if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) {
00427         return SECFailure;
00428     }
00429 
00430     dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus); 
00431     PORT_Assert(dummy == &statusInfo->status);
00432     if (dummy != &statusInfo->status) {
00433         SECITEM_FreeItem(dummy, PR_TRUE);
00434        return SECFailure;
00435     }
00436     return SECSuccess;
00437 }
00438 
00439