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 |