• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 #include <openssl/asn1t.h>
59 #include <openssl/digest.h>
60 #include <openssl/err.h>
61 #include <openssl/mem.h>
62 #include <openssl/obj.h>
63 #include <openssl/stack.h>
64 #include <openssl/x509.h>
65 #include <openssl/x509v3.h>
66 
67 #include "../asn1/asn1_locl.h"
68 
69 
70 static int X509_REVOKED_cmp(const X509_REVOKED **a,
71 				const X509_REVOKED **b);
72 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
73 
74 ASN1_SEQUENCE(X509_REVOKED) = {
75 	ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
76 	ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
77 	ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
78 } ASN1_SEQUENCE_END(X509_REVOKED)
79 
80 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
81 static int def_crl_lookup(X509_CRL *crl,
82 		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
83 
84 static X509_CRL_METHOD int_crl_meth =
85 	{
86 	0,
87 	0,0,
88 	def_crl_lookup,
89 	def_crl_verify
90 	};
91 
92 static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
93 
94 /* The X509_CRL_INFO structure needs a bit of customisation.
95  * Since we cache the original encoding the signature wont be affected by
96  * reordering of the revoked field.
97  */
crl_inf_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)98 static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
99 								void *exarg)
100 {
101 	X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
102 
103 	if(!a || !a->revoked) return 1;
104 	switch(operation) {
105 		/* Just set cmp function here. We don't sort because that
106 		 * would affect the output of X509_CRL_print().
107 		 */
108 		case ASN1_OP_D2I_POST:
109 		(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
110 		break;
111 	}
112 	return 1;
113 }
114 
115 
116 ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
117 	ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
118 	ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
119 	ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
120 	ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
121 	ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
122 	ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
123 	ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
124 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
125 
126 /* Set CRL entry issuer according to CRL certificate issuer extension.
127  * Check for unhandled critical CRL entry extensions.
128  */
129 
130 static int crl_set_issuers(X509_CRL *crl)
131 	{
132 
133 	size_t i, k;
134 	int j;
135 	GENERAL_NAMES *gens, *gtmp;
136 	STACK_OF(X509_REVOKED) *revoked;
137 
138 	revoked = X509_CRL_get_REVOKED(crl);
139 
140 	gens = NULL;
141 	for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
142 		{
143 		X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
144 		STACK_OF(X509_EXTENSION) *exts;
145 		ASN1_ENUMERATED *reason;
146 		X509_EXTENSION *ext;
147 		gtmp = X509_REVOKED_get_ext_d2i(rev,
148 						NID_certificate_issuer,
149 						&j, NULL);
150 		if (!gtmp && (j != -1))
151 			{
152 			crl->flags |= EXFLAG_INVALID;
153 			return 1;
154 			}
155 
156 		if (gtmp)
157 			{
158 			gens = gtmp;
159 			if (!crl->issuers)
160 				{
161 				crl->issuers = sk_GENERAL_NAMES_new_null();
162 				if (!crl->issuers)
163 					return 0;
164 				}
165 			if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
166 				return 0;
167 			}
168 		rev->issuer = gens;
169 
170 		reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
171 								&j, NULL);
172 		if (!reason && (j != -1))
173 			{
174 			crl->flags |= EXFLAG_INVALID;
175 			return 1;
176 			}
177 
178 		if (reason)
179 			{
180 			rev->reason = ASN1_ENUMERATED_get(reason);
181 			ASN1_ENUMERATED_free(reason);
182 			}
183 		else
184 			rev->reason = CRL_REASON_NONE;
185 
186 		/* Check for critical CRL entry extensions */
187 
188 		exts = rev->extensions;
189 
190 		for (k = 0; k < sk_X509_EXTENSION_num(exts); k++)
191 			{
192 			ext = sk_X509_EXTENSION_value(exts, k);
193 			if (ext->critical > 0)
194 				{
195 				if (OBJ_obj2nid(ext->object) ==
196 					NID_certificate_issuer)
197 					continue;
198 				crl->flags |= EXFLAG_CRITICAL;
199 				break;
200 				}
201 			}
202 
203 
204 		}
205 
206 	return 1;
207 
208 	}
209 
210 /* The X509_CRL structure needs a bit of customisation. Cache some extensions
211  * and hash of the whole CRL.
212  */
crl_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)213 static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
214 								void *exarg)
215 	{
216 	X509_CRL *crl = (X509_CRL *)*pval;
217 	STACK_OF(X509_EXTENSION) *exts;
218 	X509_EXTENSION *ext;
219 	size_t idx;
220 
221 	switch(operation)
222 		{
223 		case ASN1_OP_NEW_POST:
224 		crl->idp = NULL;
225 		crl->akid = NULL;
226 		crl->flags = 0;
227 		crl->idp_flags = 0;
228 		crl->idp_reasons = CRLDP_ALL_REASONS;
229 		crl->meth = default_crl_method;
230 		crl->meth_data = NULL;
231 		crl->issuers = NULL;
232 		crl->crl_number = NULL;
233 		crl->base_crl_number = NULL;
234 		break;
235 
236 		case ASN1_OP_D2I_POST:
237 		X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
238 		crl->idp = X509_CRL_get_ext_d2i(crl,
239 				NID_issuing_distribution_point, NULL, NULL);
240 		if (crl->idp)
241 			setup_idp(crl, crl->idp);
242 
243 		crl->akid = X509_CRL_get_ext_d2i(crl,
244 				NID_authority_key_identifier, NULL, NULL);
245 
246 		crl->crl_number = X509_CRL_get_ext_d2i(crl,
247 				NID_crl_number, NULL, NULL);
248 
249 		crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
250 				NID_delta_crl, NULL, NULL);
251 		/* Delta CRLs must have CRL number */
252 		if (crl->base_crl_number && !crl->crl_number)
253 			crl->flags |= EXFLAG_INVALID;
254 
255 		/* See if we have any unhandled critical CRL extensions and
256 		 * indicate this in a flag. We only currently handle IDP so
257 		 * anything else critical sets the flag.
258 		 *
259 		 * This code accesses the X509_CRL structure directly:
260 		 * applications shouldn't do this.
261 		 */
262 
263 		exts = crl->crl->extensions;
264 
265 		for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
266 			{
267 			int nid;
268 			ext = sk_X509_EXTENSION_value(exts, idx);
269 			nid = OBJ_obj2nid(ext->object);
270 			if (nid == NID_freshest_crl)
271 				crl->flags |= EXFLAG_FRESHEST;
272 			if (ext->critical > 0)
273 				{
274 				/* We handle IDP and deltas */
275 				if ((nid == NID_issuing_distribution_point)
276 					|| (nid == NID_authority_key_identifier)
277 					|| (nid == NID_delta_crl))
278 					break;;
279 				crl->flags |= EXFLAG_CRITICAL;
280 				break;
281 				}
282 			}
283 
284 
285 		if (!crl_set_issuers(crl))
286 			return 0;
287 
288 		if (crl->meth->crl_init)
289 			{
290 			if (crl->meth->crl_init(crl) == 0)
291 				return 0;
292 			}
293 		break;
294 
295 		case ASN1_OP_FREE_POST:
296 		if (crl->meth->crl_free)
297 			{
298 			if (!crl->meth->crl_free(crl))
299 				return 0;
300 			}
301 		if (crl->akid)
302 			AUTHORITY_KEYID_free(crl->akid);
303 		if (crl->idp)
304 			ISSUING_DIST_POINT_free(crl->idp);
305 		ASN1_INTEGER_free(crl->crl_number);
306 		ASN1_INTEGER_free(crl->base_crl_number);
307 		sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
308 		break;
309 		}
310 	return 1;
311 	}
312 
313 /* Convert IDP into a more convenient form */
314 
setup_idp(X509_CRL * crl,ISSUING_DIST_POINT * idp)315 static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
316 	{
317 	int idp_only = 0;
318 	/* Set various flags according to IDP */
319 	crl->idp_flags |= IDP_PRESENT;
320 	if (idp->onlyuser > 0)
321 		{
322 		idp_only++;
323 		crl->idp_flags |= IDP_ONLYUSER;
324 		}
325 	if (idp->onlyCA > 0)
326 		{
327 		idp_only++;
328 		crl->idp_flags |= IDP_ONLYCA;
329 		}
330 	if (idp->onlyattr > 0)
331 		{
332 		idp_only++;
333 		crl->idp_flags |= IDP_ONLYATTR;
334 		}
335 
336 	if (idp_only > 1)
337 		crl->idp_flags |= IDP_INVALID;
338 
339 	if (idp->indirectCRL > 0)
340 		crl->idp_flags |= IDP_INDIRECT;
341 
342 	if (idp->onlysomereasons)
343 		{
344 		crl->idp_flags |= IDP_REASONS;
345 		if (idp->onlysomereasons->length > 0)
346 			crl->idp_reasons = idp->onlysomereasons->data[0];
347 		if (idp->onlysomereasons->length > 1)
348 			crl->idp_reasons |=
349 				(idp->onlysomereasons->data[1] << 8);
350 		crl->idp_reasons &= CRLDP_ALL_REASONS;
351 		}
352 
353 	DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
354 	}
355 
356 ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
357 	ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
358 	ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
359 	ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
360 } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
361 
362 IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
363 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
364 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
365 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
366 IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
367 
368 static int X509_REVOKED_cmp(const X509_REVOKED **a,
369 			const X509_REVOKED **b)
370 	{
371 	return(ASN1_STRING_cmp(
372 		(ASN1_STRING *)(*a)->serialNumber,
373 		(ASN1_STRING *)(*b)->serialNumber));
374 	}
375 
X509_CRL_add0_revoked(X509_CRL * crl,X509_REVOKED * rev)376 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
377 {
378 	X509_CRL_INFO *inf;
379 	inf = crl->crl;
380 	if(!inf->revoked)
381 		inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
382 	if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
383 		OPENSSL_PUT_ERROR(X509, X509_CRL_add0_revoked, ERR_R_MALLOC_FAILURE);
384 		return 0;
385 	}
386 	inf->enc.modified = 1;
387 	return 1;
388 }
389 
X509_CRL_verify(X509_CRL * crl,EVP_PKEY * r)390 int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
391 	{
392 	if (crl->meth->crl_verify)
393 		return crl->meth->crl_verify(crl, r);
394 	return 0;
395 	}
396 
X509_CRL_get0_by_serial(X509_CRL * crl,X509_REVOKED ** ret,ASN1_INTEGER * serial)397 int X509_CRL_get0_by_serial(X509_CRL *crl,
398 		X509_REVOKED **ret, ASN1_INTEGER *serial)
399 	{
400 	if (crl->meth->crl_lookup)
401 		return crl->meth->crl_lookup(crl, ret, serial, NULL);
402 	return 0;
403 	}
404 
X509_CRL_get0_by_cert(X509_CRL * crl,X509_REVOKED ** ret,X509 * x)405 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
406 	{
407 	if (crl->meth->crl_lookup)
408 		return crl->meth->crl_lookup(crl, ret,
409 						X509_get_serialNumber(x),
410 						X509_get_issuer_name(x));
411 	return 0;
412 	}
413 
def_crl_verify(X509_CRL * crl,EVP_PKEY * r)414 static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
415 	{
416 	return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
417 		crl->sig_alg, crl->signature,crl->crl,r));
418 	}
419 
crl_revoked_issuer_match(X509_CRL * crl,X509_NAME * nm,X509_REVOKED * rev)420 static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
421 						X509_REVOKED *rev)
422 	{
423 	size_t i;
424 
425 	if (!rev->issuer)
426 		{
427 		if (!nm)
428 			return 1;
429 		if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
430 			return 1;
431 		return 0;
432 		}
433 
434 	if (!nm)
435 		nm = X509_CRL_get_issuer(crl);
436 
437 	for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
438 		{
439 		GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
440 		if (gen->type != GEN_DIRNAME)
441 			continue;
442 		if (!X509_NAME_cmp(nm, gen->d.directoryName))
443 			return 1;
444 		}
445 	return 0;
446 
447 	}
448 
def_crl_lookup(X509_CRL * crl,X509_REVOKED ** ret,ASN1_INTEGER * serial,X509_NAME * issuer)449 static int def_crl_lookup(X509_CRL *crl,
450 		X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
451 	{
452 	X509_REVOKED rtmp, *rev;
453 	size_t idx;
454 	rtmp.serialNumber = serial;
455 	/* Sort revoked into serial number order if not already sorted.
456 	 * Do this under a lock to avoid race condition.
457  	 */
458 	if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
459 		{
460 		CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
461 		sk_X509_REVOKED_sort(crl->crl->revoked);
462 		CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
463 		}
464 	if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp))
465 		return 0;
466 	/* Need to look for matching name */
467 	for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
468 		{
469 		rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
470 		if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
471 			return 0;
472 		if (crl_revoked_issuer_match(crl, issuer, rev))
473 			{
474 			if (ret)
475 				*ret = rev;
476 			if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
477 				return 2;
478 			return 1;
479 			}
480 		}
481 	return 0;
482 	}
483 
X509_CRL_set_default_method(const X509_CRL_METHOD * meth)484 void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
485 	{
486 	if (meth == NULL)
487 		default_crl_method = &int_crl_meth;
488 	else
489 		default_crl_method = meth;
490 	}
491 
X509_CRL_METHOD_new(int (* crl_init)(X509_CRL * crl),int (* crl_free)(X509_CRL * crl),int (* crl_lookup)(X509_CRL * crl,X509_REVOKED ** ret,ASN1_INTEGER * ser,X509_NAME * issuer),int (* crl_verify)(X509_CRL * crl,EVP_PKEY * pk))492 X509_CRL_METHOD *X509_CRL_METHOD_new(
493 	int (*crl_init)(X509_CRL *crl),
494 	int (*crl_free)(X509_CRL *crl),
495 	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
496 				ASN1_INTEGER *ser, X509_NAME *issuer),
497 	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
498 	{
499 	X509_CRL_METHOD *m;
500 	m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
501 	if (!m)
502 		return NULL;
503 	m->crl_init = crl_init;
504 	m->crl_free = crl_free;
505 	m->crl_lookup = crl_lookup;
506 	m->crl_verify = crl_verify;
507 	m->flags = X509_CRL_METHOD_DYNAMIC;
508 	return m;
509 	}
510 
X509_CRL_METHOD_free(X509_CRL_METHOD * m)511 void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
512 	{
513 	if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
514 		return;
515 	OPENSSL_free(m);
516 	}
517 
X509_CRL_set_meth_data(X509_CRL * crl,void * dat)518 void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
519 	{
520 	crl->meth_data = dat;
521 	}
522 
X509_CRL_get_meth_data(X509_CRL * crl)523 void *X509_CRL_get_meth_data(X509_CRL *crl)
524 	{
525 	return crl->meth_data;
526 	}
527 
528 IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
529 IMPLEMENT_ASN1_SET_OF(X509_CRL)
530