1/* $OpenBSD: x509.c,v 1.126 2024/04/28 16:43:42 florian Exp $	 */
2/* $EOM: x509.c,v 1.54 2001/01/16 18:42:16 ho Exp $	 */
3
4/*
5 * Copyright (c) 1998, 1999 Niels Provos.  All rights reserved.
6 * Copyright (c) 1999, 2000, 2001 Niklas Hallqvist.  All rights reserved.
7 * Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * This code was written under funding by Ericsson Radio Systems.
32 */
33
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <dirent.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43#include <limits.h>
44
45#include <regex.h>
46#include <keynote.h>
47
48#include "cert.h"
49#include "conf.h"
50#include "exchange.h"
51#include "hash.h"
52#include "ike_auth.h"
53#include "ipsec.h"
54#include "log.h"
55#include "dh.h"
56#include "monitor.h"
57#include "policy.h"
58#include "sa.h"
59#include "util.h"
60#include "x509.h"
61
62static u_int16_t x509_hash(u_int8_t *, size_t);
63static void	 x509_hash_init(void);
64static X509	*x509_hash_find(u_int8_t *, size_t);
65static int	 x509_hash_enter(X509 *);
66
67/*
68 * X509_STOREs do not support subjectAltNames, so we have to build
69 * our own hash table.
70 */
71
72/*
73 * XXX Actually this store is not really useful, we never use it as we have
74 * our own hash table.  It also gets collisions if we have several certificates
75 * only differing in subjectAltName.
76 */
77static X509_STORE *x509_certs = 0;
78static X509_STORE *x509_cas = 0;
79
80static int n_x509_cas = 0;
81
82/* Initial number of bits used as hash.  */
83#define INITIAL_BUCKET_BITS 6
84
85struct x509_hash {
86	LIST_ENTRY(x509_hash) link;
87
88	X509		*cert;
89};
90
91static LIST_HEAD(x509_list, x509_hash) *x509_tab = 0;
92
93/* Works both as a maximum index and a mask.  */
94static int	bucket_mask;
95
96/*
97 * Given an X509 certificate, create a KeyNote assertion where
98 * Issuer/Subject -> Authorizer/Licensees.
99 * XXX RSA-specific.
100 */
101int
102x509_generate_kn(int id, X509 *cert)
103{
104	static const char fmt[] = "Authorizer: \"rsa-hex:%s\"\nLicensees: \"rsa-hex:%s"
105		    "\"\nConditions: %s >= \"%s\" && %s <= \"%s\";\n";
106	char	*ikey = NULL, *skey = NULL, *buf = NULL;
107	char	isname[256], subname[256];
108	static const char fmt2[] = "Authorizer: \"DN:%s\"\nLicensees: \"DN:%s\"\n"
109		    "Conditions: %s >= \"%s\" && %s <= \"%s\";\n";
110	X509_NAME *issuer, *subject;
111	struct keynote_deckey dc;
112	X509_STORE_CTX *csc = NULL;
113	X509_OBJECT *obj = NULL;
114	X509	*icert;
115	RSA	*key = NULL;
116	time_t	tt;
117	char	before[15], after[15], *timecomp, *timecomp2;
118	ASN1_TIME *tm;
119	int	i;
120
121	LOG_DBG((LOG_POLICY, 90,
122	    "x509_generate_kn: generating KeyNote policy for certificate %p",
123	    cert));
124
125	issuer = X509_get_issuer_name(cert);
126	subject = X509_get_subject_name(cert);
127
128	/* Missing or self-signed, ignore cert but don't report failure.  */
129	if (!issuer || !subject || !X509_NAME_cmp(issuer, subject))
130		return 1;
131
132	if (!x509_cert_get_key(cert, &key)) {
133		LOG_DBG((LOG_POLICY, 30,
134		    "x509_generate_kn: failed to get public key from cert"));
135		return 0;
136	}
137	dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
138	dc.dec_key = key;
139	ikey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
140	    KEYNOTE_PUBLIC_KEY);
141	if (keynote_errno == ERROR_MEMORY) {
142		log_print("x509_generate_kn: failed to get memory for "
143		    "public key");
144		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get "
145		    "subject key"));
146		goto fail;
147	}
148	if (!ikey) {
149		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get "
150		    "subject key"));
151		goto fail;
152	}
153
154	RSA_free(key);
155	key = NULL;
156
157	csc = X509_STORE_CTX_new();
158	if (csc == NULL) {
159		log_print("x509_generate_kn: failed to get memory for "
160		    "certificate store");
161		goto fail;
162	}
163	obj = X509_OBJECT_new();
164	if (obj == NULL) {
165		log_print("x509_generate_kn: failed to get memory for "
166		    "certificate object");
167		goto fail;
168	}
169
170	/* Now find issuer's certificate so we can get the public key.  */
171	X509_STORE_CTX_init(csc, x509_cas, cert, NULL);
172	if (X509_STORE_get_by_subject(csc, X509_LU_X509, issuer, obj) !=
173	    X509_LU_X509) {
174		X509_STORE_CTX_cleanup(csc);
175		X509_STORE_CTX_init(csc, x509_certs, cert, NULL);
176		if (X509_STORE_get_by_subject(csc, X509_LU_X509, issuer, obj)
177		    != X509_LU_X509) {
178			X509_STORE_CTX_cleanup(csc);
179			LOG_DBG((LOG_POLICY, 30,
180			    "x509_generate_kn: no certificate found for "
181			    "issuer"));
182			goto fail;
183		}
184	}
185	X509_STORE_CTX_free(csc);
186	csc = NULL;
187
188	icert = X509_OBJECT_get0_X509(obj);
189	if (icert == NULL) {
190		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: "
191		    "missing certificates, cannot construct X509 chain"));
192		goto fail;
193	}
194	if (!x509_cert_get_key(icert, &key)) {
195		LOG_DBG((LOG_POLICY, 30,
196		    "x509_generate_kn: failed to get public key from cert"));
197		goto fail;
198	}
199	X509_OBJECT_free(obj);
200	obj = NULL;
201
202	dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
203	dc.dec_key = key;
204	skey = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
205	    KEYNOTE_PUBLIC_KEY);
206	if (keynote_errno == ERROR_MEMORY) {
207		log_error("x509_generate_kn: failed to get memory for public "
208		    "key");
209		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer "
210		    "key"));
211		goto fail;
212	}
213	if (!skey) {
214		LOG_DBG((LOG_POLICY, 30, "x509_generate_kn: cannot get issuer "
215		    "key"));
216		goto fail;
217	}
218
219	RSA_free(key);
220	key = NULL;
221
222	if (((tm = X509_get_notBefore(cert)) == NULL) ||
223	    (tm->type != V_ASN1_UTCTIME &&
224		tm->type != V_ASN1_GENERALIZEDTIME)) {
225		struct tm *ltm;
226
227		tt = time(NULL);
228		if ((ltm = localtime(&tt)) == NULL) {
229			LOG_DBG((LOG_POLICY, 30,
230			    "x509_generate_kn: invalid local time"));
231			goto fail;
232		}
233		strftime(before, 14, "%Y%m%d%H%M%S", ltm);
234		timecomp = "LocalTimeOfDay";
235	} else {
236		if (tm->data[tm->length - 1] == 'Z') {
237			timecomp = "GMTTimeOfDay";
238			i = tm->length - 2;
239		} else {
240			timecomp = "LocalTimeOfDay";
241			i = tm->length - 1;
242		}
243
244		for (; i >= 0; i--) {
245			if (tm->data[i] < '0' || tm->data[i] > '9') {
246				LOG_DBG((LOG_POLICY, 30,
247				    "x509_generate_kn: invalid data in "
248				    "NotValidBefore time field"));
249				goto fail;
250			}
251		}
252
253		if (tm->type == V_ASN1_UTCTIME) {
254			if ((tm->length < 10) || (tm->length > 13)) {
255				LOG_DBG((LOG_POLICY, 30,
256				    "x509_generate_kn: invalid length "
257				    "of NotValidBefore time field (%d)",
258				    tm->length));
259				goto fail;
260			}
261			/* Validity checks.  */
262			if ((tm->data[2] != '0' && tm->data[2] != '1') ||
263			    (tm->data[2] == '0' && tm->data[3] == '0') ||
264			    (tm->data[2] == '1' && tm->data[3] > '2') ||
265			    (tm->data[4] > '3') ||
266			    (tm->data[4] == '0' && tm->data[5] == '0') ||
267			    (tm->data[4] == '3' && tm->data[5] > '1') ||
268			    (tm->data[6] > '2') ||
269			    (tm->data[6] == '2' && tm->data[7] > '3') ||
270			    (tm->data[8] > '5')) {
271				LOG_DBG((LOG_POLICY, 30,
272				    "x509_generate_kn: invalid value in "
273				    "NotValidBefore time field"));
274				goto fail;
275			}
276			/* Stupid UTC tricks.  */
277			if (tm->data[0] < '5')
278				snprintf(before, sizeof before, "20%s",
279				    tm->data);
280			else
281				snprintf(before, sizeof before, "19%s",
282				    tm->data);
283		} else {	/* V_ASN1_GENERICTIME */
284			if ((tm->length < 12) || (tm->length > 15)) {
285				LOG_DBG((LOG_POLICY, 30,
286				    "x509_generate_kn: invalid length of "
287				    "NotValidBefore time field (%d)",
288				    tm->length));
289				goto fail;
290			}
291			/* Validity checks.  */
292			if ((tm->data[4] != '0' && tm->data[4] != '1') ||
293			    (tm->data[4] == '0' && tm->data[5] == '0') ||
294			    (tm->data[4] == '1' && tm->data[5] > '2') ||
295			    (tm->data[6] > '3') ||
296			    (tm->data[6] == '0' && tm->data[7] == '0') ||
297			    (tm->data[6] == '3' && tm->data[7] > '1') ||
298			    (tm->data[8] > '2') ||
299			    (tm->data[8] == '2' && tm->data[9] > '3') ||
300			    (tm->data[10] > '5')) {
301				LOG_DBG((LOG_POLICY, 30,
302				    "x509_generate_kn: invalid value in "
303				    "NotValidBefore time field"));
304				goto fail;
305			}
306			snprintf(before, sizeof before, "%s", tm->data);
307		}
308
309		/* Fix missing seconds.  */
310		if (tm->length < 12) {
311			before[12] = '0';
312			before[13] = '0';
313		}
314		/* This will overwrite trailing 'Z'.  */
315		before[14] = '\0';
316	}
317
318	tm = X509_get_notAfter(cert);
319	if (tm == NULL ||
320	    (tm->type != V_ASN1_UTCTIME &&
321		tm->type != V_ASN1_GENERALIZEDTIME)) {
322		struct tm *ltm;
323
324		tt = time(0);
325		if ((ltm = localtime(&tt)) == NULL) {
326			LOG_DBG((LOG_POLICY, 30,
327			    "x509_generate_kn: invalid local time"));
328			goto fail;
329		}
330		strftime(after, 14, "%Y%m%d%H%M%S", ltm);
331		timecomp2 = "LocalTimeOfDay";
332	} else {
333		if (tm->data[tm->length - 1] == 'Z') {
334			timecomp2 = "GMTTimeOfDay";
335			i = tm->length - 2;
336		} else {
337			timecomp2 = "LocalTimeOfDay";
338			i = tm->length - 1;
339		}
340
341		for (; i >= 0; i--) {
342			if (tm->data[i] < '0' || tm->data[i] > '9') {
343				LOG_DBG((LOG_POLICY, 30,
344				    "x509_generate_kn: invalid data in "
345				    "NotValidAfter time field"));
346				goto fail;
347			}
348		}
349
350		if (tm->type == V_ASN1_UTCTIME) {
351			if ((tm->length < 10) || (tm->length > 13)) {
352				LOG_DBG((LOG_POLICY, 30,
353				    "x509_generate_kn: invalid length of "
354				    "NotValidAfter time field (%d)",
355				    tm->length));
356				goto fail;
357			}
358			/* Validity checks. */
359			if ((tm->data[2] != '0' && tm->data[2] != '1') ||
360			    (tm->data[2] == '0' && tm->data[3] == '0') ||
361			    (tm->data[2] == '1' && tm->data[3] > '2') ||
362			    (tm->data[4] > '3') ||
363			    (tm->data[4] == '0' && tm->data[5] == '0') ||
364			    (tm->data[4] == '3' && tm->data[5] > '1') ||
365			    (tm->data[6] > '2') ||
366			    (tm->data[6] == '2' && tm->data[7] > '3') ||
367			    (tm->data[8] > '5')) {
368				LOG_DBG((LOG_POLICY, 30,
369				    "x509_generate_kn: invalid value in "
370				    "NotValidAfter time field"));
371				goto fail;
372			}
373			/* Stupid UTC tricks.  */
374			if (tm->data[0] < '5')
375				snprintf(after, sizeof after, "20%s",
376				    tm->data);
377			else
378				snprintf(after, sizeof after, "19%s",
379				    tm->data);
380		} else {	/* V_ASN1_GENERICTIME */
381			if ((tm->length < 12) || (tm->length > 15)) {
382				LOG_DBG((LOG_POLICY, 30,
383				    "x509_generate_kn: invalid length of "
384				    "NotValidAfter time field (%d)",
385				    tm->length));
386				goto fail;
387			}
388			/* Validity checks.  */
389			if ((tm->data[4] != '0' && tm->data[4] != '1') ||
390			    (tm->data[4] == '0' && tm->data[5] == '0') ||
391			    (tm->data[4] == '1' && tm->data[5] > '2') ||
392			    (tm->data[6] > '3') ||
393			    (tm->data[6] == '0' && tm->data[7] == '0') ||
394			    (tm->data[6] == '3' && tm->data[7] > '1') ||
395			    (tm->data[8] > '2') ||
396			    (tm->data[8] == '2' && tm->data[9] > '3') ||
397			    (tm->data[10] > '5')) {
398				LOG_DBG((LOG_POLICY, 30,
399				    "x509_generate_kn: invalid value in "
400				    "NotValidAfter time field"));
401				goto fail;
402			}
403			snprintf(after, sizeof after, "%s", tm->data);
404		}
405
406		/* Fix missing seconds.  */
407		if (tm->length < 12) {
408			after[12] = '0';
409			after[13] = '0';
410		}
411		after[14] = '\0';	/* This will overwrite trailing 'Z' */
412	}
413
414	if (asprintf(&buf, fmt, skey, ikey, timecomp, before, timecomp2,
415	    after) == -1) {
416		log_error("x509_generate_kn: "
417		    "failed to allocate memory for KeyNote credential");
418		goto fail;
419	}
420
421	free(ikey);
422	ikey = NULL;
423	free(skey);
424	skey = NULL;
425
426	if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
427		LOG_DBG((LOG_POLICY, 30,
428		    "x509_generate_kn: failed to add new KeyNote credential"));
429		goto fail;
430	}
431	/* We could print the assertion here, but log_print() truncates...  */
432	LOG_DBG((LOG_POLICY, 60, "x509_generate_kn: added credential"));
433
434	free(buf);
435	buf = NULL;
436
437	if (!X509_NAME_oneline(issuer, isname, 256)) {
438		LOG_DBG((LOG_POLICY, 50,
439		    "x509_generate_kn: "
440		    "X509_NAME_oneline (issuer, ...) failed"));
441		goto fail;
442	}
443	if (!X509_NAME_oneline(subject, subname, 256)) {
444		LOG_DBG((LOG_POLICY, 50,
445		    "x509_generate_kn: "
446		    "X509_NAME_oneline (subject, ...) failed"));
447		goto fail;
448	}
449	if (asprintf(&buf, fmt2, isname, subname, timecomp, before,
450	    timecomp2, after) == -1) {
451		log_error("x509_generate_kn: malloc failed");
452		return 0;
453	}
454
455	if (kn_add_assertion(id, buf, strlen(buf), ASSERT_FLAG_LOCAL) == -1) {
456		LOG_DBG((LOG_POLICY, 30,
457		    "x509_generate_kn: failed to add new KeyNote credential"));
458		goto fail;
459	}
460	LOG_DBG((LOG_POLICY, 80, "x509_generate_kn: added credential:\n%s",
461	    buf));
462
463	free(buf);
464	return 1;
465
466fail:
467	X509_STORE_CTX_free(csc);
468	X509_OBJECT_free(obj);
469	free(buf);
470	free(skey);
471	free(ikey);
472	if (key)
473		RSA_free(key);
474
475	return 0;
476}
477
478static u_int16_t
479x509_hash(u_int8_t *id, size_t len)
480{
481	u_int16_t bucket = 0;
482	size_t	i;
483
484	/* XXX We might resize if we are crossing a certain threshold.  */
485	for (i = 4; i < (len & ~1); i += 2) {
486		/* Doing it this way avoids alignment problems.  */
487		bucket ^= (id[i] + 1) * (id[i + 1] + 257);
488	}
489	/* Hash in the last character of odd length IDs too.  */
490	if (i < len)
491		bucket ^= (id[i] + 1) * (id[i] + 257);
492
493	bucket &= bucket_mask;
494	return bucket;
495}
496
497static void
498x509_hash_init(void)
499{
500	struct x509_hash *certh;
501	int	i;
502
503	bucket_mask = (1 << INITIAL_BUCKET_BITS) - 1;
504
505	/* If reinitializing, free existing entries.  */
506	if (x509_tab) {
507		for (i = 0; i <= bucket_mask; i++)
508			for (certh = LIST_FIRST(&x509_tab[i]); certh;
509			    certh = LIST_FIRST(&x509_tab[i])) {
510				LIST_REMOVE(certh, link);
511				free(certh);
512			}
513		free(x509_tab);
514	}
515	x509_tab = calloc(bucket_mask + 1, sizeof(struct x509_list));
516	if (!x509_tab)
517		log_fatal("x509_hash_init: malloc (%lu) failed",
518		    (bucket_mask + 1) *
519		    (unsigned long)sizeof(struct x509_list));
520	for (i = 0; i <= bucket_mask; i++) {
521		LIST_INIT(&x509_tab[i]);
522	}
523}
524
525/* Lookup a certificate by an ID blob.  */
526static X509 *
527x509_hash_find(u_int8_t *id, size_t len)
528{
529	struct x509_hash *cert;
530	u_int8_t	**cid;
531	u_int32_t	*clen;
532	int	n, i, id_found;
533
534	for (cert = LIST_FIRST(&x509_tab[x509_hash(id, len)]); cert;
535	    cert = LIST_NEXT(cert, link)) {
536		if (!x509_cert_get_subjects(cert->cert, &n, &cid, &clen))
537			continue;
538
539		id_found = 0;
540		for (i = 0; i < n; i++) {
541			LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", id, len));
542			LOG_DBG_BUF((LOG_CRYPTO, 70, "cert_cmp", cid[i],
543			    clen[i]));
544			/*
545			 * XXX This identity predicate needs to be
546			 * understood.
547			 */
548			if (clen[i] == len && id[0] == cid[i][0] &&
549			    memcmp(id + 4, cid[i] + 4, len - 4) == 0) {
550				id_found++;
551				break;
552			}
553		}
554		cert_free_subjects(n, cid, clen);
555		if (!id_found)
556			continue;
557
558		LOG_DBG((LOG_CRYPTO, 70, "x509_hash_find: return X509 %p",
559		    cert->cert));
560		return cert->cert;
561	}
562
563	LOG_DBG((LOG_CRYPTO, 70,
564	    "x509_hash_find: no certificate matched query"));
565	return 0;
566}
567
568static int
569x509_hash_enter(X509 *cert)
570{
571	u_int16_t	bucket = 0;
572	u_int8_t	**id;
573	u_int32_t	*len;
574	struct x509_hash *certh;
575	int	n, i;
576
577	if (!x509_cert_get_subjects(cert, &n, &id, &len)) {
578		log_print("x509_hash_enter: cannot retrieve subjects");
579		return 0;
580	}
581	for (i = 0; i < n; i++) {
582		certh = calloc(1, sizeof *certh);
583		if (!certh) {
584			cert_free_subjects(n, id, len);
585			log_error("x509_hash_enter: calloc (1, %lu) failed",
586			    (unsigned long)sizeof *certh);
587			return 0;
588		}
589		certh->cert = cert;
590
591		bucket = x509_hash(id[i], len[i]);
592
593		LIST_INSERT_HEAD(&x509_tab[bucket], certh, link);
594		LOG_DBG((LOG_CRYPTO, 70,
595		    "x509_hash_enter: cert %p added to bucket %d",
596		    cert, bucket));
597	}
598	cert_free_subjects(n, id, len);
599
600	return 1;
601}
602
603/* X509 Certificate Handling functions.  */
604
605int
606x509_read_from_dir(X509_STORE *ctx, char *name, int hash, int *pcount)
607{
608	FILE		*certfp;
609	X509		*cert;
610	struct stat	sb;
611	char		fullname[PATH_MAX];
612	char		file[PATH_MAX];
613	int		fd;
614
615	if (strlen(name) >= sizeof fullname - 1) {
616		log_print("x509_read_from_dir: directory name too long");
617		return 0;
618	}
619	LOG_DBG((LOG_CRYPTO, 40, "x509_read_from_dir: reading certs from %s",
620	    name));
621
622	if (monitor_req_readdir(name) == -1) {
623		LOG_DBG((LOG_CRYPTO, 10,
624		    "x509_read_from_dir: opendir (\"%s\") failed: %s",
625		    name, strerror(errno)));
626		return 0;
627	}
628
629	while ((fd = monitor_readdir(file, sizeof file)) != -1) {
630		LOG_DBG((LOG_CRYPTO, 60,
631		    "x509_read_from_dir: reading certificate %s",
632		    file));
633
634		if (fstat(fd, &sb) == -1) {
635			log_error("x509_read_from_dir: fstat failed");
636			close(fd);
637			continue;
638		}
639
640		if (!S_ISREG(sb.st_mode)) {
641			close(fd);
642			continue;
643		}
644
645		if ((certfp = fdopen(fd, "r")) == NULL) {
646			log_error("x509_read_from_dir: fdopen failed");
647			close(fd);
648			continue;
649		}
650
651#if SSLEAY_VERSION_NUMBER >= 0x00904100L
652		cert = PEM_read_X509(certfp, NULL, NULL, NULL);
653#else
654		cert = PEM_read_X509(certfp, NULL, NULL);
655#endif
656		fclose(certfp);
657
658		if (cert == NULL) {
659			log_print("x509_read_from_dir: PEM_read_X509 "
660			    "failed for %s", file);
661			continue;
662		}
663
664		if (pcount != NULL)
665			(*pcount)++;
666
667		if (!X509_STORE_add_cert(ctx, cert)) {
668			/*
669			 * This is actually expected if we have several
670			 * certificates only differing in subjectAltName,
671			 * which is not an something that is strange.
672			 * Consider multi-homed machines.
673			*/
674			LOG_DBG((LOG_CRYPTO, 50,
675			    "x509_read_from_dir: X509_STORE_add_cert failed "
676			    "for %s", file));
677		}
678		if (hash)
679			if (!x509_hash_enter(cert))
680				log_print("x509_read_from_dir: "
681				    "x509_hash_enter (%s) failed",
682				    file);
683	}
684
685	return 1;
686}
687
688/* XXX share code with x509_read_from_dir() ?  */
689int
690x509_read_crls_from_dir(X509_STORE *ctx, char *name)
691{
692	FILE		*crlfp;
693	X509_CRL	*crl;
694	struct stat	sb;
695	char		fullname[PATH_MAX];
696	char		file[PATH_MAX];
697	int		fd;
698
699	if (strlen(name) >= sizeof fullname - 1) {
700		log_print("x509_read_crls_from_dir: directory name too long");
701		return 0;
702	}
703	LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs "
704	    "from %s", name));
705
706	if (monitor_req_readdir(name) == -1) {
707		LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir "
708		    "(\"%s\") failed: %s", name, strerror(errno)));
709		return 0;
710	}
711	strlcpy(fullname, name, sizeof fullname);
712
713	while ((fd = monitor_readdir(file, sizeof file)) != -1) {
714		LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading "
715		    "CRL %s", file));
716
717		if (fstat(fd, &sb) == -1) {
718			log_error("x509_read_crls_from_dir: fstat failed");
719			close(fd);
720			continue;
721		}
722
723		if (!S_ISREG(sb.st_mode)) {
724			close(fd);
725			continue;
726		}
727
728		if ((crlfp = fdopen(fd, "r")) == NULL) {
729			log_error("x509_read_crls_from_dir: fdopen failed");
730			close(fd);
731			continue;
732		}
733
734		crl = PEM_read_X509_CRL(crlfp, NULL, NULL, NULL);
735
736		fclose(crlfp);
737
738		if (crl == NULL) {
739			log_print("x509_read_crls_from_dir: "
740			    "PEM_read_X509_CRL failed for %s",
741			    file);
742			continue;
743		}
744		if (!X509_STORE_add_crl(ctx, crl)) {
745			LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: "
746			    "X509_STORE_add_crl failed for %s", file));
747			continue;
748		}
749		/*
750		 * XXX This is to make x509_cert_validate set this (and
751		 * XXX another) flag when validating certificates. Currently,
752		 * XXX OpenSSL defaults to reject an otherwise valid
753		 * XXX certificate (chain) if these flags are set but there
754		 * XXX are no CRLs to check. The current workaround is to only
755		 * XXX set the flags if we actually loaded some CRL data.
756		 */
757		X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
758	}
759
760	return 1;
761}
762
763/* Initialize our databases and load our own certificates.  */
764int
765x509_cert_init(void)
766{
767	char	*dirname;
768
769	x509_hash_init();
770
771	/* Process CA certificates we will trust.  */
772	dirname = conf_get_str("X509-certificates", "CA-directory");
773	if (!dirname) {
774		log_print("x509_cert_init: no CA-directory");
775		return 0;
776	}
777	/* Free if already initialized.  */
778	if (x509_cas)
779		X509_STORE_free(x509_cas);
780
781	x509_cas = X509_STORE_new();
782	if (!x509_cas) {
783		log_print("x509_cert_init: creating new X509_STORE failed");
784		return 0;
785	}
786	if (!x509_read_from_dir(x509_cas, dirname, 0, &n_x509_cas)) {
787		log_print("x509_cert_init: x509_read_from_dir failed");
788		return 0;
789	}
790	/* Process client certificates we will accept.  */
791	dirname = conf_get_str("X509-certificates", "Cert-directory");
792	if (!dirname) {
793		log_print("x509_cert_init: no Cert-directory");
794		return 0;
795	}
796	/* Free if already initialized.  */
797	if (x509_certs)
798		X509_STORE_free(x509_certs);
799
800	x509_certs = X509_STORE_new();
801	if (!x509_certs) {
802		log_print("x509_cert_init: creating new X509_STORE failed");
803		return 0;
804	}
805	if (!x509_read_from_dir(x509_certs, dirname, 1, NULL)) {
806		log_print("x509_cert_init: x509_read_from_dir failed");
807		return 0;
808	}
809	return 1;
810}
811
812int
813x509_crl_init(void)
814{
815	/*
816	 * XXX I'm not sure if the method to use CRLs in certificate validation
817	 * is valid for OpenSSL versions prior to 0.9.7. For now, simply do not
818	 * support it.
819	 */
820	char	*dirname;
821	dirname = conf_get_str("X509-certificates", "CRL-directory");
822	if (!dirname) {
823		log_print("x509_crl_init: no CRL-directory");
824		return 0;
825	}
826	if (!x509_read_crls_from_dir(x509_cas, dirname)) {
827		LOG_DBG((LOG_MISC, 10,
828		    "x509_crl_init: x509_read_crls_from_dir failed"));
829		return 0;
830	}
831
832	return 1;
833}
834
835void *
836x509_cert_get(u_int8_t *asn, u_int32_t len)
837{
838	return x509_from_asn(asn, len);
839}
840
841int
842x509_cert_validate(void *scert)
843{
844	X509_STORE_CTX	*csc;
845	X509_NAME	*issuer, *subject;
846	X509		*cert = (X509 *) scert;
847	EVP_PKEY	*key;
848	int		res, err, flags;
849
850	/*
851	 * Validate the peer certificate by checking with the CA certificates
852	 * we trust.
853	 */
854	csc = X509_STORE_CTX_new();
855	if (csc == NULL) {
856		log_print("x509_cert_validate: failed to get memory for "
857		    "certificate store");
858		return 0;
859	}
860	X509_STORE_CTX_init(csc, x509_cas, cert, NULL);
861	/* XXX See comment in x509_read_crls_from_dir.  */
862	flags = X509_VERIFY_PARAM_get_flags(X509_STORE_get0_param(x509_cas));
863	if (flags & X509_V_FLAG_CRL_CHECK) {
864		X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK);
865		X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK_ALL);
866	}
867	res = X509_verify_cert(csc);
868	err = X509_STORE_CTX_get_error(csc);
869	X509_STORE_CTX_free(csc);
870
871	/*
872	 * Return if validation succeeded or self-signed certs are not
873	 * accepted.
874	 *
875	 * XXX X509_verify_cert seems to return -1 if the validation should be
876	 * retried somehow.  We take this as an error and give up.
877	 */
878	if (res > 0)
879		return 1;
880	else if (res < 0 ||
881	    (res == 0 && err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) {
882		if (err)
883			log_print("x509_cert_validate: %.100s",
884			    X509_verify_cert_error_string(err));
885		return 0;
886	} else if (!conf_get_str("X509-certificates", "Accept-self-signed")) {
887		if (err)
888			log_print("x509_cert_validate: %.100s",
889			    X509_verify_cert_error_string(err));
890		return 0;
891	}
892	issuer = X509_get_issuer_name(cert);
893	subject = X509_get_subject_name(cert);
894
895	if (!issuer || !subject || X509_NAME_cmp(issuer, subject))
896		return 0;
897
898	key = X509_get_pubkey(cert);
899	if (!key) {
900		log_print("x509_cert_validate: could not get public key from "
901		    "self-signed cert");
902		return 0;
903	}
904	if (X509_verify(cert, key) == -1) {
905		log_print("x509_cert_validate: self-signed cert is bad");
906		return 0;
907	}
908	return 1;
909}
910
911int
912x509_cert_insert(int id, void *scert)
913{
914	X509	*cert;
915	int	 res;
916
917	cert = X509_dup((X509 *)scert);
918	if (!cert) {
919		log_print("x509_cert_insert: X509_dup failed");
920		return 0;
921	}
922	if (x509_generate_kn(id, cert) == 0) {
923		LOG_DBG((LOG_POLICY, 50,
924		    "x509_cert_insert: x509_generate_kn failed"));
925		X509_free(cert);
926		return 0;
927	}
928
929	res = x509_hash_enter(cert);
930	if (!res)
931		X509_free(cert);
932
933	return res;
934}
935
936static struct x509_hash *
937x509_hash_lookup(X509 *cert)
938{
939	struct x509_hash *certh;
940	int	i;
941
942	for (i = 0; i <= bucket_mask; i++)
943		for (certh = LIST_FIRST(&x509_tab[i]); certh;
944		    certh = LIST_NEXT(certh, link))
945			if (certh->cert == cert)
946				return certh;
947	return 0;
948}
949
950void
951x509_cert_free(void *cert)
952{
953	struct x509_hash *certh = x509_hash_lookup((X509 *) cert);
954
955	if (certh)
956		LIST_REMOVE(certh, link);
957	X509_free((X509 *) cert);
958}
959
960/* Validate the BER Encoding of a RDNSequence in the CERT_REQ payload.  */
961int
962x509_certreq_validate(u_int8_t *asn, u_int32_t len)
963{
964	int	res = 1;
965#if 0
966	struct norm_type name = SEQOF("issuer", RDNSequence);
967
968	if (!asn_template_clone(&name, 1) ||
969	    (asn = asn_decode_sequence(asn, len, &name)) == 0) {
970		log_print("x509_certreq_validate: can not decode 'acceptable "
971		    "CA' info");
972		res = 0;
973	}
974	asn_free(&name);
975#endif
976
977	/* XXX - not supported directly in SSL - later.  */
978
979	return res;
980}
981
982/* Decode the BER Encoding of a RDNSequence in the CERT_REQ payload.  */
983int
984x509_certreq_decode(void **pdata, u_int8_t *asn, u_int32_t len)
985{
986#if 0
987	/* XXX This needs to be done later.  */
988	struct norm_type aca = SEQOF("aca", RDNSequence);
989	struct norm_type *tmp;
990	struct x509_aca naca, *ret;
991
992	if (!asn_template_clone(&aca, 1) ||
993	    (asn = asn_decode_sequence(asn, len, &aca)) == 0) {
994		log_print("x509_certreq_decode: can not decode 'acceptable "
995		    "CA' info");
996		goto fail;
997	}
998	bzero(&naca, sizeof(naca));
999
1000	tmp = asn_decompose("aca.RelativeDistinguishedName."
1001	    "AttributeValueAssertion", &aca);
1002	if (!tmp)
1003		goto fail;
1004	x509_get_attribval(tmp, &naca.name1);
1005
1006	tmp = asn_decompose("aca.RelativeDistinguishedName[1]"
1007	    ".AttributeValueAssertion", &aca);
1008	if (tmp)
1009		x509_get_attribval(tmp, &naca.name2);
1010
1011	asn_free(&aca);
1012
1013	ret = malloc(sizeof(struct x509_aca));
1014	if (ret)
1015		memcpy(ret, &naca, sizeof(struct x509_aca));
1016	else {
1017		log_error("x509_certreq_decode: malloc (%lu) failed",
1018		    (unsigned long) sizeof(struct x509_aca));
1019		x509_free_aca(&aca);
1020	}
1021
1022	return ret;
1023
1024fail:
1025	asn_free(&aca);
1026#endif
1027	return 1;
1028}
1029
1030void
1031x509_free_aca(void *blob)
1032{
1033	struct x509_aca *aca = blob;
1034
1035	if (aca != NULL) {
1036		free(aca->name1.type);
1037		free(aca->name1.val);
1038
1039		free(aca->name2.type);
1040		free(aca->name2.val);
1041	}
1042}
1043
1044X509 *
1045x509_from_asn(u_char *asn, u_int len)
1046{
1047	BIO		*certh;
1048	X509		*scert = 0;
1049
1050	certh = BIO_new(BIO_s_mem());
1051	if (!certh) {
1052		log_error("x509_from_asn: BIO_new (BIO_s_mem ()) failed");
1053		return 0;
1054	}
1055	if (BIO_write(certh, asn, len) == -1) {
1056		log_error("x509_from_asn: BIO_write failed\n");
1057		goto end;
1058	}
1059	scert = d2i_X509_bio(certh, NULL);
1060	if (!scert) {
1061		log_print("x509_from_asn: d2i_X509_bio failed\n");
1062		goto end;
1063	}
1064end:
1065	BIO_free(certh);
1066	return scert;
1067}
1068
1069/*
1070 * Obtain a certificate from an acceptable CA.
1071 * XXX We don't check if the certificate we find is from an accepted CA.
1072 */
1073int
1074x509_cert_obtain(u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
1075    u_int32_t *certlen)
1076{
1077	struct x509_aca *aca = data;
1078	X509		*scert;
1079
1080	if (aca)
1081		LOG_DBG((LOG_CRYPTO, 60, "x509_cert_obtain: "
1082		    "acceptable certificate authorities here"));
1083
1084	/* We need our ID to find a certificate.  */
1085	if (!id) {
1086		log_print("x509_cert_obtain: ID is missing");
1087		return 0;
1088	}
1089	scert = x509_hash_find(id, id_len);
1090	if (!scert)
1091		return 0;
1092
1093	x509_serialize(scert, cert, certlen);
1094	if (!*cert)
1095		return 0;
1096	return 1;
1097}
1098
1099/* Returns a pointer to the subjectAltName information of X509 certificate.  */
1100int
1101x509_cert_subjectaltname(X509 *scert, u_int8_t **altname, u_int32_t *len)
1102{
1103	X509_EXTENSION		*subjectaltname;
1104	ASN1_OCTET_STRING	*sanasn1data;
1105	u_int8_t		*sandata;
1106	int			 extpos, santype, sanlen;
1107
1108	extpos = X509_get_ext_by_NID(scert, NID_subject_alt_name, -1);
1109	if (extpos == -1) {
1110		log_print("x509_cert_subjectaltname: "
1111		    "certificate does not contain subjectAltName");
1112		return 0;
1113	}
1114	subjectaltname = X509_get_ext(scert, extpos);
1115	sanasn1data = X509_EXTENSION_get_data(subjectaltname);
1116
1117	if (!subjectaltname || !sanasn1data || !sanasn1data->data ||
1118	    sanasn1data->length < 4) {
1119		log_print("x509_cert_subjectaltname: invalid "
1120		    "subjectaltname extension");
1121		return 0;
1122	}
1123	/* SSL does not handle unknown ASN stuff well, do it by hand.  */
1124	sandata = sanasn1data->data;
1125	santype = sandata[2] & 0x3f;
1126	sanlen = sandata[3];
1127	sandata += 4;
1128
1129	/*
1130	 * The test here used to be !=, but some certificates can include
1131	 * extra stuff in subjectAltName, so we will just take the first
1132	 * salen bytes, and not worry about what follows.
1133	 */
1134	if (sanlen + 4 > sanasn1data->length) {
1135		log_print("x509_cert_subjectaltname: subjectaltname invalid "
1136		    "length");
1137		return 0;
1138	}
1139	*len = sanlen;
1140	*altname = sandata;
1141	return santype;
1142}
1143
1144int
1145x509_cert_get_subjects(void *scert, int *cnt, u_int8_t ***id,
1146    u_int32_t **id_len)
1147{
1148	X509		*cert = scert;
1149	X509_NAME	*subject;
1150	int		type;
1151	u_int8_t	*altname;
1152	u_int32_t	altlen;
1153	u_int8_t	*buf = 0;
1154	unsigned char	*ubuf;
1155	int		i;
1156
1157	*id = 0;
1158	*id_len = 0;
1159
1160	/*
1161	 * XXX There can be a collection of subjectAltNames, but for now I
1162	 * only return the subjectName and a single subjectAltName, if
1163	 * present.
1164	 */
1165	type = x509_cert_subjectaltname(cert, &altname, &altlen);
1166	if (!type) {
1167		*cnt = 1;
1168		altlen = 0;
1169	} else
1170		*cnt = 2;
1171
1172	*id = calloc(*cnt, sizeof **id);
1173	if (!*id) {
1174		log_print("x509_cert_get_subject: malloc (%lu) failed",
1175		    *cnt * (unsigned long)sizeof **id);
1176		*cnt = 0;
1177		goto fail;
1178	}
1179	*id_len = calloc(*cnt, sizeof **id_len);
1180	if (!*id_len) {
1181		log_print("x509_cert_get_subject: malloc (%lu) failed",
1182		    *cnt * (unsigned long)sizeof **id_len);
1183		goto fail;
1184	}
1185	/* Stash the subjectName into the first slot.  */
1186	subject = X509_get_subject_name(cert);
1187	if (!subject)
1188		goto fail;
1189
1190	(*id_len)[0] =
1191		ISAKMP_ID_DATA_OFF + i2d_X509_NAME(subject, NULL) -
1192		    ISAKMP_GEN_SZ;
1193	(*id)[0] = malloc((*id_len)[0]);
1194	if (!(*id)[0]) {
1195		log_print("x509_cert_get_subject: malloc (%d) failed",
1196		    (*id_len)[0]);
1197		goto fail;
1198	}
1199	SET_ISAKMP_ID_TYPE((*id)[0] - ISAKMP_GEN_SZ, IPSEC_ID_DER_ASN1_DN);
1200	ubuf = (*id)[0] + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
1201	i2d_X509_NAME(subject, &ubuf);
1202
1203	if (altlen) {
1204		/* Stash the subjectAltName into the second slot.  */
1205		buf = malloc(altlen + ISAKMP_ID_DATA_OFF);
1206		if (!buf) {
1207			log_print("x509_cert_get_subject: malloc (%d) failed",
1208			    altlen + ISAKMP_ID_DATA_OFF);
1209			goto fail;
1210		}
1211		switch (type) {
1212		case X509v3_DNS_NAME:
1213			SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_FQDN);
1214			break;
1215
1216		case X509v3_RFC_NAME:
1217			SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_USER_FQDN);
1218			break;
1219
1220		case X509v3_IP_ADDR:
1221			/*
1222			 * XXX I dislike the numeric constants, but I don't
1223			 * know what we should use otherwise.
1224			 */
1225			switch (altlen) {
1226			case 4:
1227				SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV4_ADDR);
1228				break;
1229
1230			case 16:
1231				SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV6_ADDR);
1232				break;
1233
1234			default:
1235				log_print("x509_cert_get_subject: invalid "
1236				    "subjectAltName IPaddress length %d ",
1237				    altlen);
1238				goto fail;
1239			}
1240			break;
1241		}
1242
1243		SET_IPSEC_ID_PROTO(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
1244		SET_IPSEC_ID_PORT(buf + ISAKMP_ID_DOI_DATA_OFF, 0);
1245		memcpy(buf + ISAKMP_ID_DATA_OFF, altname, altlen);
1246
1247		(*id_len)[1] = ISAKMP_ID_DATA_OFF + altlen - ISAKMP_GEN_SZ;
1248		(*id)[1] = malloc((*id_len)[1]);
1249		if (!(*id)[1]) {
1250			log_print("x509_cert_get_subject: malloc (%d) failed",
1251			    (*id_len)[1]);
1252			goto fail;
1253		}
1254		memcpy((*id)[1], buf + ISAKMP_GEN_SZ, (*id_len)[1]);
1255
1256		free(buf);
1257		buf = 0;
1258	}
1259	return 1;
1260
1261fail:
1262	for (i = 0; i < *cnt; i++)
1263		free((*id)[i]);
1264	free(*id);
1265	free(*id_len);
1266	free(buf);
1267	return 0;
1268}
1269
1270int
1271x509_cert_get_key(void *scert, void *keyp)
1272{
1273	X509		*cert = scert;
1274	EVP_PKEY	*key;
1275
1276	key = X509_get_pubkey(cert);
1277
1278	/* Check if we got the right key type.  */
1279	if (EVP_PKEY_id(key) != EVP_PKEY_RSA) {
1280		log_print("x509_cert_get_key: public key is not a RSA key");
1281		X509_free(cert);
1282		return 0;
1283	}
1284	*(RSA **)keyp = RSAPublicKey_dup(EVP_PKEY_get0_RSA(key));
1285
1286	return *(RSA **)keyp == NULL ? 0 : 1;
1287}
1288
1289void *
1290x509_cert_dup(void *scert)
1291{
1292	return X509_dup(scert);
1293}
1294
1295void
1296x509_serialize(void *scert, u_int8_t **data, u_int32_t *datalen)
1297{
1298	u_int8_t	*p;
1299
1300	*datalen = i2d_X509((X509 *)scert, NULL);
1301	*data = p = malloc(*datalen);
1302	if (!p) {
1303		log_error("x509_serialize: malloc (%d) failed", *datalen);
1304		return;
1305	}
1306	*datalen = i2d_X509((X509 *)scert, &p);
1307}
1308
1309/* From cert to printable */
1310char *
1311x509_printable(void *cert)
1312{
1313	char		*s;
1314	u_int8_t	*data;
1315	u_int32_t	datalen;
1316
1317	x509_serialize(cert, &data, &datalen);
1318	if (!data)
1319		return 0;
1320
1321	s = raw2hex(data, datalen);
1322	free(data);
1323	return s;
1324}
1325
1326/* From printable to cert */
1327void *
1328x509_from_printable(char *cert)
1329{
1330	u_int8_t	*buf;
1331	int		plen, ret;
1332	void		*foo;
1333
1334	plen = (strlen(cert) + 1) / 2;
1335	buf = malloc(plen);
1336	if (!buf) {
1337		log_error("x509_from_printable: malloc (%d) failed", plen);
1338		return 0;
1339	}
1340	ret = hex2raw(cert, buf, plen);
1341	if (ret == -1) {
1342		free(buf);
1343		log_print("x509_from_printable: badly formatted cert");
1344		return 0;
1345	}
1346	foo = x509_cert_get(buf, plen);
1347	free(buf);
1348	if (!foo)
1349		log_print("x509_from_printable: "
1350		    "could not retrieve certificate");
1351	return foo;
1352}
1353
1354char *
1355x509_DN_string(u_int8_t *asn1, size_t sz)
1356{
1357	X509_NAME	*name;
1358	const u_int8_t	*p = asn1;
1359	char		buf[256];	/* XXX Just a guess at a maximum length.  */
1360	long len = sz;
1361
1362	name = d2i_X509_NAME(NULL, &p, len);
1363	if (!name) {
1364		log_print("x509_DN_string: d2i_X509_NAME failed");
1365		return 0;
1366	}
1367	if (!X509_NAME_oneline(name, buf, sizeof buf - 1)) {
1368		log_print("x509_DN_string: X509_NAME_oneline failed");
1369		X509_NAME_free(name);
1370		return 0;
1371	}
1372	X509_NAME_free(name);
1373	buf[sizeof buf - 1] = '\0';
1374	return strdup(buf);
1375}
1376
1377/* Number of CAs we trust (to decide whether we can send CERT_REQ) */
1378int
1379x509_ca_count(void)
1380{
1381	return n_x509_cas;
1382}
1383