1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
38 * X.509 Extension Encoding
57 static const SEC_ASN1Template CERTSubjectKeyIDTemplate
[] = {
58 { SEC_ASN1_OCTET_STRING
}
62 static const SEC_ASN1Template CERTIA5TypeTemplate
[] = {
63 { SEC_ASN1_IA5_STRING
}
67 static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate
[] = {
69 0, NULL
, sizeof(CERTPrivKeyUsagePeriod
) },
70 { SEC_ASN1_OPTIONAL
| SEC_ASN1_CONTEXT_SPECIFIC
| 0,
71 offsetof(CERTPrivKeyUsagePeriod
, notBefore
),
72 SEC_GeneralizedTimeTemplate
},
73 { SEC_ASN1_OPTIONAL
| SEC_ASN1_CONTEXT_SPECIFIC
| 1,
74 offsetof(CERTPrivKeyUsagePeriod
, notAfter
),
75 SEC_GeneralizedTimeTemplate
},
80 const SEC_ASN1Template CERTAltNameTemplate
[] = {
81 { SEC_ASN1_CONSTRUCTED
, offsetof(CERTAltNameEncodedContext
, encodedGenName
),
82 CERT_GeneralNamesTemplate
}
85 const SEC_ASN1Template CERTAuthInfoAccessItemTemplate
[] = {
87 0, NULL
, sizeof(CERTAuthInfoAccess
) },
89 offsetof(CERTAuthInfoAccess
, method
) },
91 offsetof(CERTAuthInfoAccess
, derLocation
) },
95 const SEC_ASN1Template CERTAuthInfoAccessTemplate
[] = {
96 { SEC_ASN1_SEQUENCE_OF
, 0, CERTAuthInfoAccessItemTemplate
}
101 CERT_EncodeSubjectKeyID(PRArenaPool
*arena
, char *value
, int len
, SECItem
*encodedValue
)
103 SECItem encodeContext
;
104 SECStatus rv
= SECSuccess
;
107 PORT_Memset (&encodeContext
, 0, sizeof (encodeContext
));
110 encodeContext
.data
= (unsigned char *)value
;
111 encodeContext
.len
= len
;
113 if (SEC_ASN1EncodeItem (arena
, encodedValue
, &encodeContext
,
114 CERTSubjectKeyIDTemplate
) == NULL
) {
123 CERT_EncodePrivateKeyUsagePeriod(PRArenaPool
*arena
,
124 CERTPrivKeyUsagePeriod
*pkup
,
125 SECItem
*encodedValue
)
127 SECStatus rv
= SECSuccess
;
129 if (SEC_ASN1EncodeItem (arena
, encodedValue
, pkup
,
130 CERTPrivateKeyUsagePeriodTemplate
) == NULL
) {
136 CERTPrivKeyUsagePeriod
*
137 CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool
*arena
, SECItem
*extnValue
)
140 CERTPrivKeyUsagePeriod
*pPeriod
;
141 SECItem newExtnValue
;
143 /* allocate the certificate policies structure */
144 pPeriod
= PORT_ArenaZNew(arena
, CERTPrivKeyUsagePeriod
);
145 if ( pPeriod
== NULL
) {
149 pPeriod
->arena
= arena
;
151 /* copy the DER into the arena, since Quick DER returns data that points
152 into the DER input, which may get freed by the caller */
153 rv
= SECITEM_CopyItem(arena
, &newExtnValue
, extnValue
);
154 if ( rv
!= SECSuccess
) {
158 rv
= SEC_QuickDERDecodeItem(arena
, pPeriod
,
159 CERTPrivateKeyUsagePeriodTemplate
,
161 if ( rv
!= SECSuccess
) {
172 CERT_EncodeIA5TypeExtension(PRArenaPool
*arena
, char *value
, SECItem
*encodedValue
)
174 SECItem encodeContext
;
175 SECStatus rv
= SECSuccess
;
178 PORT_Memset (&encodeContext
, 0, sizeof (encodeContext
));
181 encodeContext
.data
= (unsigned char *)value
;
182 encodeContext
.len
= strlen(value
);
184 if (SEC_ASN1EncodeItem (arena
, encodedValue
, &encodeContext
,
185 CERTIA5TypeTemplate
) == NULL
) {
193 CERT_EncodeAltNameExtension(PRArenaPool
*arena
, CERTGeneralName
*value
, SECItem
*encodedValue
)
195 SECItem
**encodedGenName
;
196 SECStatus rv
= SECSuccess
;
198 encodedGenName
= cert_EncodeGeneralNames(arena
, value
);
199 if (SEC_ASN1EncodeItem (arena
, encodedValue
, &encodedGenName
,
200 CERT_GeneralNamesTemplate
) == NULL
) {
208 CERT_DecodeAltNameExtension(PRArenaPool
*reqArena
, SECItem
*EncodedAltName
)
210 SECStatus rv
= SECSuccess
;
211 CERTAltNameEncodedContext encodedContext
;
212 SECItem
* newEncodedAltName
;
215 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
219 newEncodedAltName
= SECITEM_ArenaDupItem(reqArena
, EncodedAltName
);
220 if (!newEncodedAltName
) {
224 encodedContext
.encodedGenName
= NULL
;
225 PORT_Memset(&encodedContext
, 0, sizeof(CERTAltNameEncodedContext
));
226 rv
= SEC_QuickDERDecodeItem (reqArena
, &encodedContext
,
227 CERT_GeneralNamesTemplate
, newEncodedAltName
);
228 if (rv
== SECFailure
) {
231 if (encodedContext
.encodedGenName
&& encodedContext
.encodedGenName
[0])
232 return cert_DecodeGeneralNames(reqArena
,
233 encodedContext
.encodedGenName
);
234 /* Extension contained an empty GeneralNames sequence */
235 /* Treat as extension not found */
236 PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND
);
243 CERT_EncodeNameConstraintsExtension(PRArenaPool
*arena
,
244 CERTNameConstraints
*value
,
245 SECItem
*encodedValue
)
247 SECStatus rv
= SECSuccess
;
249 rv
= cert_EncodeNameConstraints(value
, arena
, encodedValue
);
254 CERTNameConstraints
*
255 CERT_DecodeNameConstraintsExtension(PRArenaPool
*arena
,
256 SECItem
*encodedConstraints
)
258 return cert_DecodeNameConstraints(arena
, encodedConstraints
);
262 CERTAuthInfoAccess
**
263 CERT_DecodeAuthInfoAccessExtension(PRArenaPool
*reqArena
,
264 SECItem
*encodedExtension
)
266 CERTAuthInfoAccess
**info
= NULL
;
269 SECItem
* newEncodedExtension
;
272 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
276 newEncodedExtension
= SECITEM_ArenaDupItem(reqArena
, encodedExtension
);
277 if (!newEncodedExtension
) {
281 rv
= SEC_QuickDERDecodeItem(reqArena
, &info
, CERTAuthInfoAccessTemplate
,
282 newEncodedExtension
);
283 if (rv
!= SECSuccess
|| info
== NULL
) {
287 for (i
= 0; info
[i
] != NULL
; i
++) {
288 info
[i
]->location
= CERT_DecodeGeneralName(reqArena
,
289 &(info
[i
]->derLocation
),
296 cert_EncodeAuthInfoAccessExtension(PRArenaPool
*arena
,
297 CERTAuthInfoAccess
**info
,
303 PORT_Assert(info
!= NULL
);
304 PORT_Assert(dest
!= NULL
);
305 if (info
== NULL
|| dest
== NULL
) {
309 for (i
= 0; info
[i
] != NULL
; i
++) {
310 if (CERT_EncodeGeneralName(info
[i
]->location
, &(info
[i
]->derLocation
),
312 /* Note that this may leave some of the locations filled in. */
315 dummy
= SEC_ASN1EncodeItem(arena
, dest
, &info
,
316 CERTAuthInfoAccessTemplate
);