Back to index

lightning-sunbird  0.9+nobinonly
xconst.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038  * X.509 Extension Encoding  
00039  */
00040 
00041 #include "prtypes.h"
00042 #include "mcom_db.h"
00043 #include "seccomon.h"
00044 #include "secdert.h"
00045 #include "secoidt.h"
00046 #include "secasn1t.h"
00047 #include "secasn1.h"
00048 #include "cert.h"
00049 #include "secder.h"
00050 #include "prprf.h"
00051 #include "xconst.h"
00052 #include "genname.h"
00053 #include "secasn1.h"
00054 #include "secerr.h"
00055 
00056 
00057 static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
00058     { SEC_ASN1_OCTET_STRING }
00059 };
00060 
00061 
00062 static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
00063     { SEC_ASN1_IA5_STRING }
00064 };
00065 
00066 
00067 static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
00068     { SEC_ASN1_SEQUENCE,
00069       0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
00070     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC  | 0,      
00071          offsetof(CERTPrivKeyUsagePeriod, notBefore), 
00072          SEC_GeneralizedTimeTemplate},
00073     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC  | 1,
00074          offsetof(CERTPrivKeyUsagePeriod, notAfter), 
00075          SEC_GeneralizedTimeTemplate},
00076     { 0, } 
00077 };
00078 
00079 
00080 const SEC_ASN1Template CERTAltNameTemplate[] = {
00081     { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName), 
00082       CERT_GeneralNamesTemplate}
00083 };
00084 
00085 const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
00086     { SEC_ASN1_SEQUENCE,
00087       0, NULL, sizeof(CERTAuthInfoAccess) },
00088     { SEC_ASN1_OBJECT_ID,
00089       offsetof(CERTAuthInfoAccess, method) },
00090     { SEC_ASN1_ANY,
00091       offsetof(CERTAuthInfoAccess, derLocation) },
00092     { 0, }
00093 };
00094 
00095 const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
00096     { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
00097 };
00098 
00099 
00100 SECStatus 
00101 CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue)
00102 {
00103     SECItem encodeContext;
00104     SECStatus rv = SECSuccess;
00105 
00106 
00107     PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
00108     
00109     if (value != NULL) {
00110        encodeContext.data = (unsigned char *)value;
00111        encodeContext.len = len;
00112     }
00113     if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
00114                          CERTSubjectKeyIDTemplate) == NULL) {
00115        rv = SECFailure;
00116     }
00117     
00118     return(rv);
00119 }
00120 
00121 
00122 SECStatus
00123 CERT_EncodePrivateKeyUsagePeriod(PRArenaPool *arena, 
00124                                 CERTPrivKeyUsagePeriod *pkup, 
00125                             SECItem *encodedValue)
00126 {
00127     SECStatus rv = SECSuccess;
00128 
00129     if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
00130                          CERTPrivateKeyUsagePeriodTemplate) == NULL) {
00131        rv = SECFailure;
00132     }
00133     return(rv);
00134 }
00135 
00136 CERTPrivKeyUsagePeriod *
00137 CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
00138 {
00139     SECStatus rv;
00140     CERTPrivKeyUsagePeriod *pPeriod;
00141     SECItem newExtnValue;
00142 
00143     /* allocate the certificate policies structure */
00144     pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
00145     if ( pPeriod == NULL ) {
00146        goto loser;
00147     }
00148     
00149     pPeriod->arena = arena;
00150 
00151     /* copy the DER into the arena, since Quick DER returns data that points
00152        into the DER input, which may get freed by the caller */
00153     rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
00154     if ( rv != SECSuccess ) {
00155        goto loser;
00156     }
00157 
00158     rv = SEC_QuickDERDecodeItem(arena, pPeriod, 
00159                                 CERTPrivateKeyUsagePeriodTemplate,
00160                              &newExtnValue);
00161     if ( rv != SECSuccess ) {
00162        goto loser;
00163     }
00164     return pPeriod;
00165     
00166 loser:
00167     return NULL;
00168 }
00169 
00170 
00171 SECStatus 
00172 CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue)
00173 {
00174     SECItem encodeContext;
00175     SECStatus rv = SECSuccess;
00176 
00177 
00178     PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
00179     
00180     if (value != NULL) {
00181        encodeContext.data = (unsigned char *)value;
00182        encodeContext.len = strlen(value);
00183     }
00184     if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
00185                          CERTIA5TypeTemplate) == NULL) {
00186        rv = SECFailure;
00187     }
00188     
00189     return(rv);
00190 }
00191 
00192 SECStatus
00193 CERT_EncodeAltNameExtension(PRArenaPool *arena,  CERTGeneralName  *value, SECItem *encodedValue)
00194 {
00195     SECItem                **encodedGenName;
00196     SECStatus              rv = SECSuccess;
00197 
00198     encodedGenName = cert_EncodeGeneralNames(arena, value);
00199     if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
00200                          CERT_GeneralNamesTemplate) == NULL) {
00201        rv = SECFailure;
00202     }
00203 
00204     return rv;
00205 }
00206 
00207 CERTGeneralName *
00208 CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName)
00209 {
00210     SECStatus              rv = SECSuccess;
00211     CERTAltNameEncodedContext  encodedContext;
00212 
00213     encodedContext.encodedGenName = NULL;
00214     PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
00215     rv = SEC_ASN1DecodeItem (arena, &encodedContext, CERT_GeneralNamesTemplate,
00216                           EncodedAltName);
00217     if (rv == SECFailure) {
00218        goto loser;
00219     }
00220     if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
00221        return cert_DecodeGeneralNames(arena, encodedContext.encodedGenName);
00222     /* Extension contained an empty GeneralNames sequence */
00223     /* Treat as extension not found */
00224     PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
00225 loser:
00226     return NULL;
00227 }
00228 
00229 
00230 SECStatus
00231 CERT_EncodeNameConstraintsExtension(PRArenaPool          *arena, 
00232                                 CERTNameConstraints  *value,
00233                                 SECItem              *encodedValue)
00234 {
00235     SECStatus     rv = SECSuccess;
00236     
00237     rv = cert_EncodeNameConstraints(value, arena, encodedValue);
00238     return rv;
00239 }
00240 
00241 
00242 CERTNameConstraints *
00243 CERT_DecodeNameConstraintsExtension(PRArenaPool          *arena,
00244                                 SECItem              *encodedConstraints)
00245 {
00246     return cert_DecodeNameConstraints(arena, encodedConstraints);
00247 }
00248 
00249 
00250 CERTAuthInfoAccess **
00251 CERT_DecodeAuthInfoAccessExtension(PRArenaPool *arena,
00252                                SECItem     *encodedExtension)
00253 {
00254     CERTAuthInfoAccess **info = NULL;
00255     SECStatus rv;
00256     int i;
00257 
00258     rv = SEC_ASN1DecodeItem(arena, &info, CERTAuthInfoAccessTemplate, 
00259                          encodedExtension);
00260     if (rv != SECSuccess || info == NULL) {
00261        return NULL;
00262     }
00263 
00264     for (i = 0; info[i] != NULL; i++) {
00265        info[i]->location = CERT_DecodeGeneralName(arena,
00266                                              &(info[i]->derLocation),
00267                                              NULL);
00268     }
00269     return info;
00270 }
00271 
00272 SECStatus
00273 cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena,
00274                                CERTAuthInfoAccess **info,
00275                                SECItem *dest)
00276 {
00277     SECItem *dummy;
00278     int i;
00279 
00280     PORT_Assert(info != NULL);
00281     PORT_Assert(dest != NULL);
00282     if (info == NULL || dest == NULL) {
00283        return SECFailure;
00284     }
00285 
00286     for (i = 0; info[i] != NULL; i++) {
00287        if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
00288                                arena) == NULL)
00289            /* Note that this may leave some of the locations filled in. */
00290            return SECFailure;
00291     }
00292     dummy = SEC_ASN1EncodeItem(arena, dest, &info,
00293                             CERTAuthInfoAccessTemplate);
00294     if (dummy == NULL) {
00295        return SECFailure;
00296     }
00297     return SECSuccess;
00298 }