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
62 static u_int16_t x509_hash(u_int8_t *, size_t);
63 static void x509_hash_init(void);
64 static X509 *x509_hash_find(u_int8_t *, size_t);
65 static 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 */
77 static X509_STORE *x509_certs = 0;
78 static X509_STORE *x509_cas = 0;
79
80 static int n_x509_cas = 0;
81
82 /* Initial number of bits used as hash. */
83 #define INITIAL_BUCKET_BITS 6
84
85 struct x509_hash {
86 LIST_ENTRY(x509_hash) link;
87
88 X509 *cert;
89 };
90
91 static LIST_HEAD(x509_list, x509_hash) *x509_tab = 0;
92
93 /* Works both as a maximum index and a mask. */
94 static 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 */
101 int
x509_generate_kn(int id,X509 * cert)102 x509_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
466 fail:
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
478 static u_int16_t
x509_hash(u_int8_t * id,size_t len)479 x509_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
497 static void
x509_hash_init(void)498 x509_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. */
526 static X509 *
x509_hash_find(u_int8_t * id,size_t len)527 x509_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
568 static int
x509_hash_enter(X509 * cert)569 x509_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
605 int
x509_read_from_dir(X509_STORE * ctx,char * name,int hash,int * pcount)606 x509_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() ? */
689 int
x509_read_crls_from_dir(X509_STORE * ctx,char * name)690 x509_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. */
764 int
x509_cert_init(void)765 x509_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
812 int
x509_crl_init(void)813 x509_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
835 void *
x509_cert_get(u_int8_t * asn,u_int32_t len)836 x509_cert_get(u_int8_t *asn, u_int32_t len)
837 {
838 return x509_from_asn(asn, len);
839 }
840
841 int
x509_cert_validate(void * scert)842 x509_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
911 int
x509_cert_insert(int id,void * scert)912 x509_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
936 static struct x509_hash *
x509_hash_lookup(X509 * cert)937 x509_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
950 void
x509_cert_free(void * cert)951 x509_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. */
961 int
x509_certreq_validate(u_int8_t * asn,u_int32_t len)962 x509_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. */
983 int
x509_certreq_decode(void ** pdata,u_int8_t * asn,u_int32_t len)984 x509_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
1024 fail:
1025 asn_free(&aca);
1026 #endif
1027 return 1;
1028 }
1029
1030 void
x509_free_aca(void * blob)1031 x509_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
1044 X509 *
x509_from_asn(u_char * asn,u_int len)1045 x509_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 }
1064 end:
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 */
1073 int
x509_cert_obtain(u_int8_t * id,size_t id_len,void * data,u_int8_t ** cert,u_int32_t * certlen)1074 x509_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. */
1100 int
x509_cert_subjectaltname(X509 * scert,u_int8_t ** altname,u_int32_t * len)1101 x509_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
1144 int
x509_cert_get_subjects(void * scert,int * cnt,u_int8_t *** id,u_int32_t ** id_len)1145 x509_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
1261 fail:
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
1270 int
x509_cert_get_key(void * scert,void * keyp)1271 x509_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
1289 void *
x509_cert_dup(void * scert)1290 x509_cert_dup(void *scert)
1291 {
1292 return X509_dup(scert);
1293 }
1294
1295 void
x509_serialize(void * scert,u_int8_t ** data,u_int32_t * datalen)1296 x509_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 */
1310 char *
x509_printable(void * cert)1311 x509_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 */
1327 void *
x509_from_printable(char * cert)1328 x509_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
1354 char *
x509_DN_string(u_int8_t * asn1,size_t sz)1355 x509_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) */
1378 int
x509_ca_count(void)1379 x509_ca_count(void)
1380 {
1381 return n_x509_cas;
1382 }
1383