| OLD | NEW |
| (Empty) |
| 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/. */ | |
| 4 | |
| 5 /* | |
| 6 * X.509 Extension Encoding | |
| 7 */ | |
| 8 | |
| 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" | |
| 22 | |
| 23 | |
| 24 static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = { | |
| 25 { SEC_ASN1_OCTET_STRING } | |
| 26 }; | |
| 27 | |
| 28 | |
| 29 static const SEC_ASN1Template CERTIA5TypeTemplate[] = { | |
| 30 { SEC_ASN1_IA5_STRING } | |
| 31 }; | |
| 32 | |
| 33 SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate) | |
| 34 | |
| 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 }; | |
| 46 | |
| 47 | |
| 48 const SEC_ASN1Template CERTAltNameTemplate[] = { | |
| 49 { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
| |
| 50 CERT_GeneralNamesTemplate} | |
| 51 }; | |
| 52 | |
| 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 }; | |
| 62 | |
| 63 const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = { | |
| 64 { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate } | |
| 65 }; | |
| 66 | |
| 67 | |
| 68 SECStatus | |
| 69 CERT_EncodeSubjectKeyID(PRArenaPool *arena, const SECItem* srcString, | |
| 70 SECItem *encodedValue) | |
| 71 { | |
| 72 SECStatus rv = SECSuccess; | |
| 73 | |
| 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 } | |
| 82 | |
| 83 return(rv); | |
| 84 } | |
| 85 | |
| 86 | |
| 87 SECStatus | |
| 88 CERT_EncodePrivateKeyUsagePeriod(PRArenaPool *arena, | |
| 89 CERTPrivKeyUsagePeriod *pkup, | |
| 90 SECItem *encodedValue) | |
| 91 { | |
| 92 SECStatus rv = SECSuccess; | |
| 93 | |
| 94 if (SEC_ASN1EncodeItem (arena, encodedValue, pkup, | |
| 95 CERTPrivateKeyUsagePeriodTemplate) == NULL) { | |
| 96 rv = SECFailure; | |
| 97 } | |
| 98 return(rv); | |
| 99 } | |
| 100 | |
| 101 CERTPrivKeyUsagePeriod * | |
| 102 CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue) | |
| 103 { | |
| 104 SECStatus rv; | |
| 105 CERTPrivKeyUsagePeriod *pPeriod; | |
| 106 SECItem newExtnValue; | |
| 107 | |
| 108 /* allocate the certificate policies structure */ | |
| 109 pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod); | |
| 110 if ( pPeriod == NULL ) { | |
| 111 goto loser; | |
| 112 } | |
| 113 | |
| 114 pPeriod->arena = arena; | |
| 115 | |
| 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 } | |
| 122 | |
| 123 rv = SEC_QuickDERDecodeItem(arena, pPeriod, | |
| 124 CERTPrivateKeyUsagePeriodTemplate, | |
| 125 &newExtnValue); | |
| 126 if ( rv != SECSuccess ) { | |
| 127 goto loser; | |
| 128 } | |
| 129 return pPeriod; | |
| 130 | |
| 131 loser: | |
| 132 return NULL; | |
| 133 } | |
| 134 | |
| 135 | |
| 136 SECStatus | |
| 137 CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedVal
ue) | |
| 138 { | |
| 139 SECItem encodeContext; | |
| 140 SECStatus rv = SECSuccess; | |
| 141 | |
| 142 | |
| 143 PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); | |
| 144 | |
| 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 } | |
| 153 | |
| 154 return(rv); | |
| 155 } | |
| 156 | |
| 157 SECStatus | |
| 158 CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECIte
m *encodedValue) | |
| 159 { | |
| 160 SECItem **encodedGenName; | |
| 161 SECStatus rv = SECSuccess; | |
| 162 | |
| 163 encodedGenName = cert_EncodeGeneralNames(arena, value); | |
| 164 if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName, | |
| 165 CERT_GeneralNamesTemplate) == NULL) { | |
| 166 rv = SECFailure; | |
| 167 } | |
| 168 | |
| 169 return rv; | |
| 170 } | |
| 171 | |
| 172 CERTGeneralName * | |
| 173 CERT_DecodeAltNameExtension(PRArenaPool *reqArena, SECItem *EncodedAltName) | |
| 174 { | |
| 175 SECStatus rv = SECSuccess; | |
| 176 CERTAltNameEncodedContext encodedContext; | |
| 177 SECItem* newEncodedAltName; | |
| 178 | |
| 179 if (!reqArena) { | |
| 180 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 181 return NULL; | |
| 182 } | |
| 183 | |
| 184 newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName); | |
| 185 if (!newEncodedAltName) { | |
| 186 return NULL; | |
| 187 } | |
| 188 | |
| 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 } | |
| 205 | |
| 206 | |
| 207 SECStatus | |
| 208 CERT_EncodeNameConstraintsExtension(PRArenaPool *arena, | |
| 209 CERTNameConstraints *value, | |
| 210 SECItem *encodedValue) | |
| 211 { | |
| 212 SECStatus rv = SECSuccess; | |
| 213 | |
| 214 rv = cert_EncodeNameConstraints(value, arena, encodedValue); | |
| 215 return rv; | |
| 216 } | |
| 217 | |
| 218 | |
| 219 CERTNameConstraints * | |
| 220 CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, | |
| 221 SECItem *encodedConstraints) | |
| 222 { | |
| 223 return cert_DecodeNameConstraints(arena, encodedConstraints); | |
| 224 } | |
| 225 | |
| 226 | |
| 227 CERTAuthInfoAccess ** | |
| 228 CERT_DecodeAuthInfoAccessExtension(PRArenaPool *reqArena, | |
| 229 SECItem *encodedExtension) | |
| 230 { | |
| 231 CERTAuthInfoAccess **info = NULL; | |
| 232 SECStatus rv; | |
| 233 int i; | |
| 234 SECItem* newEncodedExtension; | |
| 235 | |
| 236 if (!reqArena) { | |
| 237 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 238 return NULL; | |
| 239 } | |
| 240 | |
| 241 newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension); | |
| 242 if (!newEncodedExtension) { | |
| 243 return NULL; | |
| 244 } | |
| 245 | |
| 246 rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate, | |
| 247 newEncodedExtension); | |
| 248 if (rv != SECSuccess || info == NULL) { | |
| 249 return NULL; | |
| 250 } | |
| 251 | |
| 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 } | |
| 259 | |
| 260 SECStatus | |
| 261 CERT_EncodeInfoAccessExtension(PRArenaPool *arena, | |
| 262 CERTAuthInfoAccess **info, | |
| 263 SECItem *dest) | |
| 264 { | |
| 265 SECItem *dummy; | |
| 266 int i; | |
| 267 | |
| 268 PORT_Assert(info != NULL); | |
| 269 PORT_Assert(dest != NULL); | |
| 270 if (info == NULL || dest == NULL) { | |
| 271 return SECFailure; | |
| 272 } | |
| 273 | |
| 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 } | |
| OLD | NEW |