security/nss/lib/certdb/xconst.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * X.509 Extension Encoding  
     7  */
     9 #include "prtypes.h"
    10 #include "seccomon.h"
    11 #include "secdert.h"
    12 #include "secoidt.h"
    13 #include "secasn1t.h"
    14 #include "secasn1.h"
    15 #include "cert.h"
    16 #include "secder.h"
    17 #include "prprf.h"
    18 #include "xconst.h"
    19 #include "genname.h"
    20 #include "secasn1.h"
    21 #include "secerr.h"
    24 static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
    25     { SEC_ASN1_OCTET_STRING }
    26 };
    29 static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
    30     { SEC_ASN1_IA5_STRING }
    31 };
    33 SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
    35 static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
    36     { SEC_ASN1_SEQUENCE,
    37       0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
    38     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC  | SEC_ASN1_XTRN | 0,
    39 	  offsetof(CERTPrivKeyUsagePeriod, notBefore), 
    40 	  SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
    41     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC  | SEC_ASN1_XTRN | 1,
    42 	  offsetof(CERTPrivKeyUsagePeriod, notAfter), 
    43 	  SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)},
    44     { 0, } 
    45 };
    48 const SEC_ASN1Template CERTAltNameTemplate[] = {
    49     { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName), 
    50       CERT_GeneralNamesTemplate}
    51 };
    53 const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
    54     { SEC_ASN1_SEQUENCE,
    55       0, NULL, sizeof(CERTAuthInfoAccess) },
    56     { SEC_ASN1_OBJECT_ID,
    57       offsetof(CERTAuthInfoAccess, method) },
    58     { SEC_ASN1_ANY,
    59       offsetof(CERTAuthInfoAccess, derLocation) },
    60     { 0, }
    61 };
    63 const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
    64     { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
    65 };
    68 SECStatus 
    69 CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
    70                         SECItem *encodedValue)
    71 {
    72     SECStatus rv = SECSuccess;
    74     if (!srcString) {
    75         PORT_SetError(SEC_ERROR_INVALID_ARGS);
    76         return SECFailure;
    77     }
    78     if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
    79 			    CERTSubjectKeyIDTemplate) == NULL) {
    80 	rv = SECFailure;
    81     }
    83     return(rv);
    84 }
    87 SECStatus
    88 CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
    89                                 CERTPrivKeyUsagePeriod *pkup, 
    90 				SECItem *encodedValue)
    91 {
    92     SECStatus rv = SECSuccess;
    94     if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
    95 			    CERTPrivateKeyUsagePeriodTemplate) == NULL) {
    96 	rv = SECFailure;
    97     }
    98     return(rv);
    99 }
   101 CERTPrivKeyUsagePeriod *
   102 CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
   103 {
   104     SECStatus rv;
   105     CERTPrivKeyUsagePeriod *pPeriod;
   106     SECItem newExtnValue;
   108     /* allocate the certificate policies structure */
   109     pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
   110     if ( pPeriod == NULL ) {
   111 	goto loser;
   112     }
   114     pPeriod->arena = arena;
   116     /* copy the DER into the arena, since Quick DER returns data that points
   117        into the DER input, which may get freed by the caller */
   118     rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
   119     if ( rv != SECSuccess ) {
   120 	goto loser;
   121     }
   123     rv = SEC_QuickDERDecodeItem(arena, pPeriod, 
   124                                 CERTPrivateKeyUsagePeriodTemplate,
   125 			        &newExtnValue);
   126     if ( rv != SECSuccess ) {
   127 	goto loser;
   128     }
   129     return pPeriod;
   131 loser:
   132     return NULL;
   133 }
   136 SECStatus 
   137 CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue)
   138 {
   139     SECItem encodeContext;
   140     SECStatus rv = SECSuccess;
   143     PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
   145     if (value != NULL) {
   146 	encodeContext.data = (unsigned char *)value;
   147 	encodeContext.len = strlen(value);
   148     }
   149     if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
   150 			    CERTIA5TypeTemplate) == NULL) {
   151 	rv = SECFailure;
   152     }
   154     return(rv);
   155 }
   157 SECStatus
   158 CERT_EncodeAltNameExtension(PLArenaPool *arena,  CERTGeneralName  *value, SECItem *encodedValue)
   159 {
   160     SECItem                **encodedGenName;
   161     SECStatus              rv = SECSuccess;
   163     encodedGenName = cert_EncodeGeneralNames(arena, value);
   164     if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
   165 			    CERT_GeneralNamesTemplate) == NULL) {
   166 	rv = SECFailure;
   167     }
   169     return rv;
   170 }
   172 CERTGeneralName *
   173 CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
   174 {
   175     SECStatus                  rv = SECSuccess;
   176     CERTAltNameEncodedContext  encodedContext;
   177     SECItem*                   newEncodedAltName;
   179     if (!reqArena) {
   180         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   181         return NULL;
   182     }
   184     newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
   185     if (!newEncodedAltName) {
   186         return NULL;
   187     }
   189     encodedContext.encodedGenName = NULL;
   190     PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
   191     rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext,
   192                                  CERT_GeneralNamesTemplate, newEncodedAltName);
   193     if (rv == SECFailure) {
   194 	goto loser;
   195     }
   196     if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
   197 	return cert_DecodeGeneralNames(reqArena,
   198                                        encodedContext.encodedGenName);
   199     /* Extension contained an empty GeneralNames sequence */
   200     /* Treat as extension not found */
   201     PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
   202 loser:
   203     return NULL;
   204 }
   207 SECStatus
   208 CERT_EncodeNameConstraintsExtension(PLArenaPool          *arena, 
   209 				    CERTNameConstraints  *value,
   210 				    SECItem              *encodedValue)
   211 {
   212     SECStatus     rv = SECSuccess;
   214     rv = cert_EncodeNameConstraints(value, arena, encodedValue);
   215     return rv;
   216 }
   219 CERTNameConstraints *
   220 CERT_DecodeNameConstraintsExtension(PLArenaPool          *arena,
   221 				    const SECItem        *encodedConstraints)
   222 {
   223     return cert_DecodeNameConstraints(arena, encodedConstraints);
   224 }
   227 CERTAuthInfoAccess **
   228 CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
   229 				   SECItem     *encodedExtension)
   230 {
   231     CERTAuthInfoAccess **info = NULL;
   232     SECStatus rv;
   233     int i;
   234     SECItem* newEncodedExtension;
   236     if (!reqArena) {
   237         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   238         return NULL;
   239     }
   241     newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
   242     if (!newEncodedExtension) {
   243         return NULL;
   244     }
   246     rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate, 
   247 			    newEncodedExtension);
   248     if (rv != SECSuccess || info == NULL) {
   249 	return NULL;
   250     }
   252     for (i = 0; info[i] != NULL; i++) {
   253 	info[i]->location = CERT_DecodeGeneralName(reqArena,
   254 						   &(info[i]->derLocation),
   255 						   NULL);
   256     }
   257     return info;
   258 }
   260 SECStatus
   261 CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
   262 				   CERTAuthInfoAccess **info,
   263 				   SECItem *dest)
   264 {
   265     SECItem *dummy;
   266     int i;
   268     PORT_Assert(info != NULL);
   269     PORT_Assert(dest != NULL);
   270     if (info == NULL || dest == NULL) {
   271 	return SECFailure;
   272     }
   274     for (i = 0; info[i] != NULL; i++) {
   275 	if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
   276 				   arena) == NULL)
   277 	    /* Note that this may leave some of the locations filled in. */
   278 	    return SECFailure;
   279     }
   280     dummy = SEC_ASN1EncodeItem(arena, dest, &info,
   281 			       CERTAuthInfoAccessTemplate);
   282     if (dummy == NULL) {
   283 	return SECFailure;
   284     }
   285     return SECSuccess;
   286 }

mercurial