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