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