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

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

mercurial