comparison nss/lib/certdb/certv3.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 * Code for dealing with X509.V3 extensions.
7 */
8
9 #include "cert.h"
10 #include "secitem.h"
11 #include "secoid.h"
12 #include "secder.h"
13 #include "secasn1.h"
14 #include "certxutl.h"
15 #include "secerr.h"
16
17 SECStatus
18 CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid,
19 SECItem *value)
20 {
21 return (cert_FindExtensionByOID (cert->extensions, oid, value));
22 }
23
24
25 SECStatus
26 CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value)
27 {
28 return (cert_FindExtension (cert->extensions, tag, value));
29 }
30
31 static void
32 SetExts(void *object, CERTCertExtension **exts)
33 {
34 CERTCertificate *cert = (CERTCertificate *)object;
35
36 cert->extensions = exts;
37 DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
38 }
39
40 void *
41 CERT_StartCertExtensions(CERTCertificate *cert)
42 {
43 return (cert_StartExtensions ((void *)cert, cert->arena, SetExts));
44 }
45
46 /* find the given extension in the certificate of the Issuer of 'cert' */
47 SECStatus
48 CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value)
49 {
50 CERTCertificate *issuercert;
51 SECStatus rv;
52
53 issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer);
54 if ( issuercert ) {
55 rv = cert_FindExtension(issuercert->extensions, tag, value);
56 CERT_DestroyCertificate(issuercert);
57 } else {
58 rv = SECFailure;
59 }
60
61 return(rv);
62 }
63
64 /* find a URL extension in the cert or its CA
65 * apply the base URL string if it exists
66 */
67 char *
68 CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag)
69 {
70 SECStatus rv;
71 SECItem urlitem = {siBuffer,0};
72 SECItem baseitem = {siBuffer,0};
73 SECItem urlstringitem = {siBuffer,0};
74 SECItem basestringitem = {siBuffer,0};
75 PLArenaPool *arena = NULL;
76 PRBool hasbase;
77 char *urlstring;
78 char *str;
79 int len;
80 unsigned int i;
81
82 urlstring = NULL;
83
84 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
85 if ( ! arena ) {
86 goto loser;
87 }
88
89 hasbase = PR_FALSE;
90
91 rv = cert_FindExtension(cert->extensions, tag, &urlitem);
92 if ( rv == SECSuccess ) {
93 rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL,
94 &baseitem);
95 if ( rv == SECSuccess ) {
96 hasbase = PR_TRUE;
97 }
98
99 } else if ( catag ) {
100 /* if the cert doesn't have the extensions, see if the issuer does */
101 rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem);
102 if ( rv != SECSuccess ) {
103 goto loser;
104 }
105 rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL,
106 &baseitem);
107 if ( rv == SECSuccess ) {
108 hasbase = PR_TRUE;
109 }
110 } else {
111 goto loser;
112 }
113
114 rv = SEC_QuickDERDecodeItem(arena, &urlstringitem,
115 SEC_ASN1_GET(SEC_IA5StringTemplate), &urlitem);
116
117 if ( rv != SECSuccess ) {
118 goto loser;
119 }
120 if ( hasbase ) {
121 rv = SEC_QuickDERDecodeItem(arena, &basestringitem,
122 SEC_ASN1_GET(SEC_IA5StringTemplate),
123 &baseitem);
124
125 if ( rv != SECSuccess ) {
126 goto loser;
127 }
128 }
129
130 len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1;
131
132 str = urlstring = (char *)PORT_Alloc(len);
133 if ( urlstring == NULL ) {
134 goto loser;
135 }
136
137 /* copy the URL base first */
138 if ( hasbase ) {
139
140 /* if the urlstring has a : in it, then we assume it is an absolute
141 * URL, and will not get the base string pre-pended
142 */
143 for ( i = 0; i < urlstringitem.len; i++ ) {
144 if ( urlstringitem.data[i] == ':' ) {
145 goto nobase;
146 }
147 }
148
149 PORT_Memcpy(str, basestringitem.data, basestringitem.len);
150 str += basestringitem.len;
151
152 }
153
154 nobase:
155 /* copy the rest (or all) of the URL */
156 PORT_Memcpy(str, urlstringitem.data, urlstringitem.len);
157 str += urlstringitem.len;
158
159 *str = '\0';
160 goto done;
161
162 loser:
163 if ( urlstring ) {
164 PORT_Free(urlstring);
165 }
166
167 urlstring = NULL;
168 done:
169 if ( arena ) {
170 PORT_FreeArena(arena, PR_FALSE);
171 }
172 if ( baseitem.data ) {
173 PORT_Free(baseitem.data);
174 }
175 if ( urlitem.data ) {
176 PORT_Free(urlitem.data);
177 }
178
179 return(urlstring);
180 }
181
182 /*
183 * get the value of the Netscape Certificate Type Extension
184 */
185 SECStatus
186 CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
187 {
188
189 return (CERT_FindBitStringExtension
190 (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
191 }
192
193
194 /*
195 * get the value of a string type extension
196 */
197 char *
198 CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
199 {
200 SECItem wrapperItem, tmpItem = {siBuffer,0};
201 SECStatus rv;
202 PLArenaPool *arena = NULL;
203 char *retstring = NULL;
204
205 wrapperItem.data = NULL;
206 tmpItem.data = NULL;
207
208 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
209
210 if ( ! arena ) {
211 goto loser;
212 }
213
214 rv = cert_FindExtension(cert->extensions, oidtag,
215 &wrapperItem);
216 if ( rv != SECSuccess ) {
217 goto loser;
218 }
219
220 rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
221 SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
222
223 if ( rv != SECSuccess ) {
224 goto loser;
225 }
226
227 retstring = (char *)PORT_Alloc(tmpItem.len + 1 );
228 if ( retstring == NULL ) {
229 goto loser;
230 }
231
232 PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
233 retstring[tmpItem.len] = '\0';
234
235 loser:
236 if ( arena ) {
237 PORT_FreeArena(arena, PR_FALSE);
238 }
239
240 if ( wrapperItem.data ) {
241 PORT_Free(wrapperItem.data);
242 }
243
244 return(retstring);
245 }
246
247 /*
248 * get the value of the X.509 v3 Key Usage Extension
249 */
250 SECStatus
251 CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem)
252 {
253
254 return (CERT_FindBitStringExtension(cert->extensions,
255 SEC_OID_X509_KEY_USAGE, retItem));
256 }
257
258 /*
259 * get the value of the X.509 v3 Key Usage Extension
260 */
261 SECStatus
262 CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
263 {
264
265 SECStatus rv;
266 SECItem encodedValue = {siBuffer, NULL, 0 };
267 SECItem decodedValue = {siBuffer, NULL, 0 };
268
269 rv = cert_FindExtension
270 (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
271 if (rv == SECSuccess) {
272 PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
273 if (tmpArena) {
274 rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
275 SEC_ASN1_GET(SEC_OctetStringTemplate),
276 &encodedValue);
277 if (rv == SECSuccess) {
278 rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
279 }
280 PORT_FreeArena(tmpArena, PR_FALSE);
281 } else {
282 rv = SECFailure;
283 }
284 }
285 SECITEM_FreeItem(&encodedValue, PR_FALSE);
286 return rv;
287 }
288
289 SECStatus
290 CERT_FindBasicConstraintExten(CERTCertificate *cert,
291 CERTBasicConstraints *value)
292 {
293 SECItem encodedExtenValue;
294 SECStatus rv;
295
296 encodedExtenValue.data = NULL;
297 encodedExtenValue.len = 0;
298
299 rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
300 &encodedExtenValue);
301 if ( rv != SECSuccess ) {
302 return (rv);
303 }
304
305 rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue);
306
307 /* free the raw extension data */
308 PORT_Free(encodedExtenValue.data);
309 encodedExtenValue.data = NULL;
310
311 return(rv);
312 }
313
314 CERTAuthKeyID *
315 CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert)
316 {
317 SECItem encodedExtenValue;
318 SECStatus rv;
319 CERTAuthKeyID *ret;
320
321 encodedExtenValue.data = NULL;
322 encodedExtenValue.len = 0;
323
324 rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
325 &encodedExtenValue);
326 if ( rv != SECSuccess ) {
327 return (NULL);
328 }
329
330 ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
331
332 PORT_Free(encodedExtenValue.data);
333 encodedExtenValue.data = NULL;
334
335 return(ret);
336 }
337
338 SECStatus
339 CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
340 {
341 SECItem keyUsage;
342 SECStatus rv;
343
344 /* There is no extension, v1 or v2 certificate */
345 if (cert->extensions == NULL) {
346 return (SECSuccess);
347 }
348
349 keyUsage.data = NULL;
350
351 /* This code formerly ignored the Key Usage extension if it was
352 ** marked non-critical. That was wrong. Since we do understand it,
353 ** we are obligated to honor it, whether or not it is critical.
354 */
355 rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
356 if (rv == SECFailure) {
357 rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ?
358 SECSuccess : SECFailure;
359 } else if (!(keyUsage.data[0] & usage)) {
360 PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID);
361 rv = SECFailure;
362 }
363 PORT_Free (keyUsage.data);
364 return (rv);
365 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)