1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/certdb/xconst.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,286 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * X.509 Extension Encoding 1.10 + */ 1.11 + 1.12 +#include "prtypes.h" 1.13 +#include "seccomon.h" 1.14 +#include "secdert.h" 1.15 +#include "secoidt.h" 1.16 +#include "secasn1t.h" 1.17 +#include "secasn1.h" 1.18 +#include "cert.h" 1.19 +#include "secder.h" 1.20 +#include "prprf.h" 1.21 +#include "xconst.h" 1.22 +#include "genname.h" 1.23 +#include "secasn1.h" 1.24 +#include "secerr.h" 1.25 + 1.26 + 1.27 +static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = { 1.28 + { SEC_ASN1_OCTET_STRING } 1.29 +}; 1.30 + 1.31 + 1.32 +static const SEC_ASN1Template CERTIA5TypeTemplate[] = { 1.33 + { SEC_ASN1_IA5_STRING } 1.34 +}; 1.35 + 1.36 +SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate) 1.37 + 1.38 +static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = { 1.39 + { SEC_ASN1_SEQUENCE, 1.40 + 0, NULL, sizeof(CERTPrivKeyUsagePeriod) }, 1.41 + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 1.42 + offsetof(CERTPrivKeyUsagePeriod, notBefore), 1.43 + SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) }, 1.44 + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1, 1.45 + offsetof(CERTPrivKeyUsagePeriod, notAfter), 1.46 + SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)}, 1.47 + { 0, } 1.48 +}; 1.49 + 1.50 + 1.51 +const SEC_ASN1Template CERTAltNameTemplate[] = { 1.52 + { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName), 1.53 + CERT_GeneralNamesTemplate} 1.54 +}; 1.55 + 1.56 +const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = { 1.57 + { SEC_ASN1_SEQUENCE, 1.58 + 0, NULL, sizeof(CERTAuthInfoAccess) }, 1.59 + { SEC_ASN1_OBJECT_ID, 1.60 + offsetof(CERTAuthInfoAccess, method) }, 1.61 + { SEC_ASN1_ANY, 1.62 + offsetof(CERTAuthInfoAccess, derLocation) }, 1.63 + { 0, } 1.64 +}; 1.65 + 1.66 +const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = { 1.67 + { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate } 1.68 +}; 1.69 + 1.70 + 1.71 +SECStatus 1.72 +CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString, 1.73 + SECItem *encodedValue) 1.74 +{ 1.75 + SECStatus rv = SECSuccess; 1.76 + 1.77 + if (!srcString) { 1.78 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.79 + return SECFailure; 1.80 + } 1.81 + if (SEC_ASN1EncodeItem (arena, encodedValue, srcString, 1.82 + CERTSubjectKeyIDTemplate) == NULL) { 1.83 + rv = SECFailure; 1.84 + } 1.85 + 1.86 + return(rv); 1.87 +} 1.88 + 1.89 + 1.90 +SECStatus 1.91 +CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena, 1.92 + CERTPrivKeyUsagePeriod *pkup, 1.93 + SECItem *encodedValue) 1.94 +{ 1.95 + SECStatus rv = SECSuccess; 1.96 + 1.97 + if (SEC_ASN1EncodeItem (arena, encodedValue, pkup, 1.98 + CERTPrivateKeyUsagePeriodTemplate) == NULL) { 1.99 + rv = SECFailure; 1.100 + } 1.101 + return(rv); 1.102 +} 1.103 + 1.104 +CERTPrivKeyUsagePeriod * 1.105 +CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue) 1.106 +{ 1.107 + SECStatus rv; 1.108 + CERTPrivKeyUsagePeriod *pPeriod; 1.109 + SECItem newExtnValue; 1.110 + 1.111 + /* allocate the certificate policies structure */ 1.112 + pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod); 1.113 + if ( pPeriod == NULL ) { 1.114 + goto loser; 1.115 + } 1.116 + 1.117 + pPeriod->arena = arena; 1.118 + 1.119 + /* copy the DER into the arena, since Quick DER returns data that points 1.120 + into the DER input, which may get freed by the caller */ 1.121 + rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); 1.122 + if ( rv != SECSuccess ) { 1.123 + goto loser; 1.124 + } 1.125 + 1.126 + rv = SEC_QuickDERDecodeItem(arena, pPeriod, 1.127 + CERTPrivateKeyUsagePeriodTemplate, 1.128 + &newExtnValue); 1.129 + if ( rv != SECSuccess ) { 1.130 + goto loser; 1.131 + } 1.132 + return pPeriod; 1.133 + 1.134 +loser: 1.135 + return NULL; 1.136 +} 1.137 + 1.138 + 1.139 +SECStatus 1.140 +CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue) 1.141 +{ 1.142 + SECItem encodeContext; 1.143 + SECStatus rv = SECSuccess; 1.144 + 1.145 + 1.146 + PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); 1.147 + 1.148 + if (value != NULL) { 1.149 + encodeContext.data = (unsigned char *)value; 1.150 + encodeContext.len = strlen(value); 1.151 + } 1.152 + if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, 1.153 + CERTIA5TypeTemplate) == NULL) { 1.154 + rv = SECFailure; 1.155 + } 1.156 + 1.157 + return(rv); 1.158 +} 1.159 + 1.160 +SECStatus 1.161 +CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue) 1.162 +{ 1.163 + SECItem **encodedGenName; 1.164 + SECStatus rv = SECSuccess; 1.165 + 1.166 + encodedGenName = cert_EncodeGeneralNames(arena, value); 1.167 + if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName, 1.168 + CERT_GeneralNamesTemplate) == NULL) { 1.169 + rv = SECFailure; 1.170 + } 1.171 + 1.172 + return rv; 1.173 +} 1.174 + 1.175 +CERTGeneralName * 1.176 +CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName) 1.177 +{ 1.178 + SECStatus rv = SECSuccess; 1.179 + CERTAltNameEncodedContext encodedContext; 1.180 + SECItem* newEncodedAltName; 1.181 + 1.182 + if (!reqArena) { 1.183 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.184 + return NULL; 1.185 + } 1.186 + 1.187 + newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName); 1.188 + if (!newEncodedAltName) { 1.189 + return NULL; 1.190 + } 1.191 + 1.192 + encodedContext.encodedGenName = NULL; 1.193 + PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext)); 1.194 + rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext, 1.195 + CERT_GeneralNamesTemplate, newEncodedAltName); 1.196 + if (rv == SECFailure) { 1.197 + goto loser; 1.198 + } 1.199 + if (encodedContext.encodedGenName && encodedContext.encodedGenName[0]) 1.200 + return cert_DecodeGeneralNames(reqArena, 1.201 + encodedContext.encodedGenName); 1.202 + /* Extension contained an empty GeneralNames sequence */ 1.203 + /* Treat as extension not found */ 1.204 + PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); 1.205 +loser: 1.206 + return NULL; 1.207 +} 1.208 + 1.209 + 1.210 +SECStatus 1.211 +CERT_EncodeNameConstraintsExtension(PLArenaPool *arena, 1.212 + CERTNameConstraints *value, 1.213 + SECItem *encodedValue) 1.214 +{ 1.215 + SECStatus rv = SECSuccess; 1.216 + 1.217 + rv = cert_EncodeNameConstraints(value, arena, encodedValue); 1.218 + return rv; 1.219 +} 1.220 + 1.221 + 1.222 +CERTNameConstraints * 1.223 +CERT_DecodeNameConstraintsExtension(PLArenaPool *arena, 1.224 + const SECItem *encodedConstraints) 1.225 +{ 1.226 + return cert_DecodeNameConstraints(arena, encodedConstraints); 1.227 +} 1.228 + 1.229 + 1.230 +CERTAuthInfoAccess ** 1.231 +CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena, 1.232 + SECItem *encodedExtension) 1.233 +{ 1.234 + CERTAuthInfoAccess **info = NULL; 1.235 + SECStatus rv; 1.236 + int i; 1.237 + SECItem* newEncodedExtension; 1.238 + 1.239 + if (!reqArena) { 1.240 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.241 + return NULL; 1.242 + } 1.243 + 1.244 + newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension); 1.245 + if (!newEncodedExtension) { 1.246 + return NULL; 1.247 + } 1.248 + 1.249 + rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate, 1.250 + newEncodedExtension); 1.251 + if (rv != SECSuccess || info == NULL) { 1.252 + return NULL; 1.253 + } 1.254 + 1.255 + for (i = 0; info[i] != NULL; i++) { 1.256 + info[i]->location = CERT_DecodeGeneralName(reqArena, 1.257 + &(info[i]->derLocation), 1.258 + NULL); 1.259 + } 1.260 + return info; 1.261 +} 1.262 + 1.263 +SECStatus 1.264 +CERT_EncodeInfoAccessExtension(PLArenaPool *arena, 1.265 + CERTAuthInfoAccess **info, 1.266 + SECItem *dest) 1.267 +{ 1.268 + SECItem *dummy; 1.269 + int i; 1.270 + 1.271 + PORT_Assert(info != NULL); 1.272 + PORT_Assert(dest != NULL); 1.273 + if (info == NULL || dest == NULL) { 1.274 + return SECFailure; 1.275 + } 1.276 + 1.277 + for (i = 0; info[i] != NULL; i++) { 1.278 + if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation), 1.279 + arena) == NULL) 1.280 + /* Note that this may leave some of the locations filled in. */ 1.281 + return SECFailure; 1.282 + } 1.283 + dummy = SEC_ASN1EncodeItem(arena, dest, &info, 1.284 + CERTAuthInfoAccessTemplate); 1.285 + if (dummy == NULL) { 1.286 + return SECFailure; 1.287 + } 1.288 + return SECSuccess; 1.289 +}