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/. */
6 * X.509 Extension Encoding
24 static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
25 { SEC_ASN1_OCTET_STRING }
29 static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
30 { SEC_ASN1_IA5_STRING }
33 SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
35 static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
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)},
48 const SEC_ASN1Template CERTAltNameTemplate[] = {
49 { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
50 CERT_GeneralNamesTemplate}
53 const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
55 0, NULL, sizeof(CERTAuthInfoAccess) },
57 offsetof(CERTAuthInfoAccess, method) },
59 offsetof(CERTAuthInfoAccess, derLocation) },
63 const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
64 { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
69 CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
70 SECItem *encodedValue)
72 SECStatus rv = SECSuccess;
75 PORT_SetError(SEC_ERROR_INVALID_ARGS);
78 if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
79 CERTSubjectKeyIDTemplate) == NULL) {
88 CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
89 CERTPrivKeyUsagePeriod *pkup,
90 SECItem *encodedValue)
92 SECStatus rv = SECSuccess;
94 if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
95 CERTPrivateKeyUsagePeriodTemplate) == NULL) {
101 CERTPrivKeyUsagePeriod *
102 CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
105 CERTPrivKeyUsagePeriod *pPeriod;
106 SECItem newExtnValue;
108 /* allocate the certificate policies structure */
109 pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
110 if ( pPeriod == NULL ) {
114 pPeriod->arena = arena;
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 ) {
123 rv = SEC_QuickDERDecodeItem(arena, pPeriod,
124 CERTPrivateKeyUsagePeriodTemplate,
126 if ( rv != SECSuccess ) {
137 CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue)
139 SECItem encodeContext;
140 SECStatus rv = SECSuccess;
143 PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
146 encodeContext.data = (unsigned char *)value;
147 encodeContext.len = strlen(value);
149 if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
150 CERTIA5TypeTemplate) == NULL) {
158 CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue)
160 SECItem **encodedGenName;
161 SECStatus rv = SECSuccess;
163 encodedGenName = cert_EncodeGeneralNames(arena, value);
164 if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
165 CERT_GeneralNamesTemplate) == NULL) {
173 CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
175 SECStatus rv = SECSuccess;
176 CERTAltNameEncodedContext encodedContext;
177 SECItem* newEncodedAltName;
180 PORT_SetError(SEC_ERROR_INVALID_ARGS);
184 newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
185 if (!newEncodedAltName) {
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) {
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);
208 CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
209 CERTNameConstraints *value,
210 SECItem *encodedValue)
212 SECStatus rv = SECSuccess;
214 rv = cert_EncodeNameConstraints(value, arena, encodedValue);
219 CERTNameConstraints *
220 CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
221 const SECItem *encodedConstraints)
223 return cert_DecodeNameConstraints(arena, encodedConstraints);
227 CERTAuthInfoAccess **
228 CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
229 SECItem *encodedExtension)
231 CERTAuthInfoAccess **info = NULL;
234 SECItem* newEncodedExtension;
237 PORT_SetError(SEC_ERROR_INVALID_ARGS);
241 newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
242 if (!newEncodedExtension) {
246 rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
247 newEncodedExtension);
248 if (rv != SECSuccess || info == NULL) {
252 for (i = 0; info[i] != NULL; i++) {
253 info[i]->location = CERT_DecodeGeneralName(reqArena,
254 &(info[i]->derLocation),
261 CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
262 CERTAuthInfoAccess **info,
268 PORT_Assert(info != NULL);
269 PORT_Assert(dest != NULL);
270 if (info == NULL || dest == NULL) {
274 for (i = 0; info[i] != NULL; i++) {
275 if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
277 /* Note that this may leave some of the locations filled in. */
280 dummy = SEC_ASN1EncodeItem(arena, dest, &info,
281 CERTAuthInfoAccessTemplate);