policy.c revision 1.39
1/*	$OpenBSD: policy.c,v 1.39 2001/07/03 11:00:52 ho Exp $	*/
2/*	$EOM: policy.c,v 1.49 2000/10/24 13:33:39 niklas Exp $ */
3
4/*
5 * Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis.  All rights reserved.
6 * Copyright (c) 1999, 2000, 2001 Niklas Hallqvist.  All rights reserved.
7 * Copyright (c) 2001 H�kan Olsson.  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#include <sys/types.h>
40#include <sys/param.h>
41#include <sys/mman.h>
42#include <sys/queue.h>
43#include <sys/stat.h>
44#include <regex.h>
45#include <ctype.h>
46#include <fcntl.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <unistd.h>
51#include <keynote.h>
52#include <sys/socket.h>
53#include <netinet/in.h>
54#include <arpa/inet.h>
55#include <errno.h>
56#include <openssl/ssl.h>
57
58#include "sysdep.h"
59
60#include "app.h"
61#include "conf.h"
62#include "connection.h"
63#include "cookie.h"
64#include "doi.h"
65#include "dyn.h"
66#include "exchange.h"
67#include "init.h"
68#include "ipsec.h"
69#include "isakmp_doi.h"
70#include "math_group.h"
71#include "sa.h"
72#include "timer.h"
73#include "transport.h"
74#include "udp.h"
75#include "log.h"
76#include "message.h"
77#include "ui.h"
78#include "util.h"
79#include "policy.h"
80#include "x509.h"
81
82#if defined (HAVE_DLOPEN) && !defined (USE_KEYNOTE) && 0
83
84void *libkeynote = 0;
85
86/*
87 * These prototypes matches OpenBSD keynote.h 1.6.  If you use
88 * a different version than that, you are on your own.
89 */
90int *lk_keynote_errno;
91int (*lk_kn_add_action) (int, char *, char *, int);
92int (*lk_kn_add_assertion) (int, char *, int, int);
93int (*lk_kn_add_authorizer) (int, char *);
94int (*lk_kn_close) (int);
95int (*lk_kn_do_query) (int, char **, int);
96char *(*lk_kn_encode_key) (struct keynote_deckey *, int, int, int);
97int (*lk_kn_init) (void);
98char **(*lk_kn_read_asserts) (char *, int, int *);
99int (*lk_kn_remove_authorizer) (int, char *);
100int (*lk_kn_get_authorizer) (int, int, int *);
101void (*lk_kn_free_key) (struct keynote_deckey *);
102struct keynote_keylist *(*lk_kn_get_licensees) (int, int);
103#define SYMENTRY(x) { SYM, SYM (x), (void **)&lk_ ## x }
104
105static struct dynload_script libkeynote_script[] = {
106  { LOAD, "libc.so", &libkeynote },
107  { LOAD, "libcrypto.so", &libkeynote },
108  { LOAD, "libm.so", &libkeynote },
109  { LOAD, "libkeynote.so", &libkeynote },
110  SYMENTRY (keynote_errno),
111  SYMENTRY (kn_add_action),
112  SYMENTRY (kn_add_assertion),
113  SYMENTRY (kn_add_authorizer),
114  SYMENTRY (kn_close),
115  SYMENTRY (kn_do_query),
116  SYMENTRY (kn_encode_key),
117  SYMENTRY (kn_init),
118  SYMENTRY (kn_read_asserts),
119  SYMENTRY (kn_remove_authorizer),
120  SYMENTRY (kn_get_licensees),
121  SYMENTRY (kn_get_authorizer),
122  { EOS }
123};
124#endif
125
126char **keynote_policy_asserts = NULL;
127int keynote_policy_asserts_num = 0;
128struct exchange *policy_exchange = 0;
129struct sa *policy_sa = 0;
130struct sa *policy_isakmp_sa = 0;
131
132static const char hextab[] = {
133  '0', '1', '2', '3', '4', '5', '6', '7',
134  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
135};
136
137/*
138 * Adaptation of Vixie's inet_ntop4 ()
139 */
140static const char *
141my_inet_ntop4 (const in_addr_t *src, char *dst, size_t size, int normalize)
142{
143  static const char fmt[] = "%03u.%03u.%03u.%03u";
144  char tmp[sizeof "255.255.255.255"];
145  in_addr_t src2;
146
147  if (normalize)
148    src2 = ntohl (*src);
149  else
150    src2 = *src;
151
152  if (sprintf (tmp, fmt, ((u_int8_t *) &src2)[0], ((u_int8_t *) &src2)[1],
153	       ((u_int8_t *) &src2)[2], ((u_int8_t *) &src2)[3]) > size)
154    {
155      errno = ENOSPC;
156      return 0;
157    }
158  strcpy (dst, tmp);
159  return dst;
160}
161
162static const char *
163my_inet_ntop6 (const unsigned char *src, char *dst, size_t size)
164{
165  static const char fmt[] = "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x";
166  char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
167
168  if (sprintf (tmp, fmt, src[0], src[1], src[2], src[3], src[4], src[5],
169               src[6], src[7], src[8], src[9], src[10], src[11], src[12],
170               src[13], src[14], src[15]) > size)
171    {
172      errno = ENOSPC;
173      return 0;
174    }
175  strcpy (dst, tmp);
176  return dst;
177}
178
179char *
180policy_callback (char *name)
181{
182  struct proto *proto;
183
184  u_int8_t *attr, *value, *id, *idlocal, *idremote;
185  size_t id_sz, idlocalsz, idremotesz;
186  struct sockaddr *sin;
187  struct ipsec_exch *ie;
188  struct ipsec_sa *is;
189  int fmt, i, lifetype = 0;
190  in_addr_t net, subnet;
191  u_int16_t len, type;
192  time_t tt;
193  char *addr;
194  static char mytimeofday[15];
195
196  /* We use all these as a cache.  */
197  static char *esp_present, *ah_present, *comp_present;
198  static char *ah_hash_alg, *ah_auth_alg, *esp_auth_alg, *esp_enc_alg;
199  static char *comp_alg, ah_life_kbytes[32], ah_life_seconds[32];
200  static char esp_life_kbytes[32], esp_life_seconds[32], comp_life_kbytes[32];
201  static char comp_life_seconds[32], *ah_encapsulation, *esp_encapsulation;
202  static char *comp_encapsulation, ah_key_length[32], esp_key_length[32];
203  static char ah_key_rounds[32], esp_key_rounds[32], comp_dict_size[32];
204  static char comp_private_alg[32], *remote_filter_type, *local_filter_type;
205  static char remote_filter_addr_upper[64], remote_filter_addr_lower[64];
206  static char local_filter_addr_upper[64], local_filter_addr_lower[64];
207  static char ah_group_desc[32], esp_group_desc[32], comp_group_desc[32];
208  static char remote_ike_address[64], local_ike_address[64];
209  static char *remote_id_type, remote_id_addr_upper[64], *phase_1;
210  static char remote_id_addr_lower[64], *remote_id_proto, remote_id_port[32];
211  static char remote_filter_port[32], local_filter_port[32];
212  static char *remote_filter_proto, *local_filter_proto, *pfs, *initiator;
213  static char remote_filter_proto_num[3], local_filter_proto_num[3];
214  static char remote_id_proto_num[3];
215  static char phase1_group[32];
216
217  /* Allocated.  */
218  static char *remote_filter = 0, *local_filter = 0, *remote_id = 0;
219
220  static int dirty = 1;
221
222  /* We only need to set dirty at initialization time really.  */
223  if (strcmp (name, KEYNOTE_CALLBACK_CLEANUP) == 0
224      || strcmp (name, KEYNOTE_CALLBACK_INITIALIZE) == 0)
225    {
226      esp_present = ah_present = comp_present = pfs = "no";
227      ah_hash_alg = ah_auth_alg = phase_1 = "";
228      esp_auth_alg = esp_enc_alg = comp_alg = ah_encapsulation = "";
229      esp_encapsulation = comp_encapsulation = remote_filter_type = "";
230      local_filter_type = remote_id_type = initiator = "";
231      remote_filter_proto = local_filter_proto = remote_id_proto = "";
232
233      if (remote_filter != 0)
234        {
235	  free (remote_filter);
236	  remote_filter = 0;
237	}
238
239      if (local_filter != 0)
240        {
241	  free (local_filter);
242	  local_filter = 0;
243	}
244
245      if (remote_id != 0)
246        {
247	  free (remote_id);
248	  remote_id = 0;
249	}
250
251      memset (remote_ike_address, 0, sizeof remote_ike_address);
252      memset (local_ike_address, 0, sizeof local_ike_address);
253      memset (ah_life_kbytes, 0, sizeof ah_life_kbytes);
254      memset (ah_life_seconds, 0, sizeof ah_life_seconds);
255      memset (esp_life_kbytes, 0, sizeof esp_life_kbytes);
256      memset (esp_life_seconds, 0, sizeof esp_life_seconds);
257      memset (comp_life_kbytes, 0, sizeof comp_life_kbytes);
258      memset (comp_life_seconds, 0, sizeof comp_life_seconds);
259      memset (ah_key_length, 0, sizeof ah_key_length);
260      memset (ah_key_rounds, 0, sizeof ah_key_rounds);
261      memset (esp_key_length, 0, sizeof esp_key_length);
262      memset (esp_key_rounds, 0, sizeof esp_key_rounds);
263      memset (comp_dict_size, 0, sizeof comp_dict_size);
264      memset (comp_private_alg, 0, sizeof comp_private_alg);
265      memset (remote_filter_addr_upper, 0, sizeof remote_filter_addr_upper);
266      memset (remote_filter_addr_lower, 0, sizeof remote_filter_addr_lower);
267      memset (local_filter_addr_upper, 0, sizeof local_filter_addr_upper);
268      memset (local_filter_addr_lower, 0, sizeof local_filter_addr_lower);
269      memset (remote_id_addr_upper, 0, sizeof remote_id_addr_upper);
270      memset (remote_id_addr_lower, 0, sizeof remote_id_addr_lower);
271      memset (ah_group_desc, 0, sizeof ah_group_desc);
272      memset (esp_group_desc, 0, sizeof esp_group_desc);
273      memset (remote_id_port, 0, sizeof remote_id_port);
274      memset (remote_filter_port, 0, sizeof remote_filter_port);
275      memset (local_filter_port, 0, sizeof local_filter_port);
276      memset (phase1_group, 0, sizeof phase1_group);
277
278      dirty = 1;
279      return "";
280    }
281
282  /*
283   * If dirty is set, this is the first request for an attribute, so
284   * populate our value cache.
285   */
286  if (dirty)
287    {
288      ie = policy_exchange->data;
289
290      if (ie->pfs)
291	pfs = "yes";
292
293      is = policy_isakmp_sa->data;
294      sprintf (phase1_group, "%u", is->group_desc);
295
296      for (proto = TAILQ_FIRST (&policy_sa->protos); proto;
297	   proto = TAILQ_NEXT (proto, link))
298	{
299	  switch (proto->proto)
300	    {
301	    case IPSEC_PROTO_IPSEC_AH:
302	      ah_present = "yes";
303	      switch (proto->id)
304		{
305		case IPSEC_AH_MD5:
306		  ah_hash_alg = "md5";
307		  break;
308
309		case IPSEC_AH_SHA:
310		  ah_hash_alg = "sha";
311		  break;
312
313		case IPSEC_AH_RIPEMD:
314		  ah_hash_alg = "ripemd";
315		  break;
316
317		case IPSEC_AH_DES:
318		  ah_hash_alg = "des";
319		  break;
320		}
321
322	      break;
323
324	    case IPSEC_PROTO_IPSEC_ESP:
325	      esp_present = "yes";
326	      switch (proto->id)
327		{
328		case IPSEC_ESP_DES_IV64:
329		  esp_enc_alg = "des-iv64";
330		  break;
331
332		case IPSEC_ESP_DES:
333		  esp_enc_alg = "des";
334		  break;
335
336		case IPSEC_ESP_3DES:
337		  esp_enc_alg = "3des";
338		  break;
339
340		case IPSEC_ESP_AES:
341		  esp_enc_alg = "aes";
342		  break;
343
344		case IPSEC_ESP_RC5:
345		  esp_enc_alg = "rc5";
346		  break;
347
348		case IPSEC_ESP_IDEA:
349		  esp_enc_alg = "idea";
350		  break;
351
352		case IPSEC_ESP_CAST:
353		  esp_enc_alg = "cast";
354		  break;
355
356		case IPSEC_ESP_BLOWFISH:
357		  esp_enc_alg = "blowfish";
358		  break;
359
360		case IPSEC_ESP_3IDEA:
361		  esp_enc_alg = "3idea";
362		  break;
363
364		case IPSEC_ESP_DES_IV32:
365		  esp_enc_alg = "des-iv32";
366		  break;
367
368		case IPSEC_ESP_RC4:
369		  esp_enc_alg = "rc4";
370		  break;
371
372		case IPSEC_ESP_NULL:
373		  esp_enc_alg = "null";
374		  break;
375		}
376
377	      break;
378
379	    case IPSEC_PROTO_IPCOMP:
380	      comp_present = "yes";
381	      switch (proto->id)
382		{
383		case IPSEC_IPCOMP_OUI:
384		  comp_alg = "oui";
385		  break;
386
387		case IPSEC_IPCOMP_DEFLATE:
388		  comp_alg = "deflate";
389		  break;
390
391		case IPSEC_IPCOMP_LZS:
392		  comp_alg = "lzs";
393		  break;
394
395		case IPSEC_IPCOMP_V42BIS:
396		  comp_alg = "v42bis";
397		  break;
398		}
399
400	      break;
401	    }
402
403	  for (attr = proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
404	       attr
405		 < proto->chosen->p + GET_ISAKMP_GEN_LENGTH (proto->chosen->p);
406	       attr = value + len)
407	    {
408	      if (attr + ISAKMP_ATTR_VALUE_OFF
409		  > (proto->chosen->p
410		     + GET_ISAKMP_GEN_LENGTH (proto->chosen->p)))
411		return "";
412
413	      type = GET_ISAKMP_ATTR_TYPE (attr);
414	      fmt = ISAKMP_ATTR_FORMAT (type);
415	      type = ISAKMP_ATTR_TYPE (type);
416	      value = attr + (fmt ? ISAKMP_ATTR_LENGTH_VALUE_OFF :
417			      ISAKMP_ATTR_VALUE_OFF);
418	      len = (fmt ? ISAKMP_ATTR_LENGTH_VALUE_LEN :
419		     GET_ISAKMP_ATTR_LENGTH_VALUE (attr));
420
421	      if (value + len > proto->chosen->p +
422		  GET_ISAKMP_GEN_LENGTH (proto->chosen->p))
423		return "";
424
425	      switch (type)
426		{
427		case IPSEC_ATTR_SA_LIFE_TYPE:
428		  lifetype = decode_16 (value);
429		  break;
430
431		case IPSEC_ATTR_SA_LIFE_DURATION:
432		  switch (proto->proto)
433		    {
434		    case IPSEC_PROTO_IPSEC_AH:
435		      if (lifetype == IPSEC_DURATION_SECONDS)
436			{
437			  if (len == 2)
438			    sprintf (ah_life_seconds, "%u",
439				     decode_16 (value));
440			  else
441			    sprintf (ah_life_seconds, "%u",
442				     decode_32 (value));
443			}
444		      else
445			{
446			  if (len == 2)
447			    sprintf (ah_life_kbytes, "%u",
448				     decode_16 (value));
449			  else
450			    sprintf (ah_life_kbytes, "%u",
451				     decode_32 (value));
452			}
453
454		      break;
455
456		    case IPSEC_PROTO_IPSEC_ESP:
457		      if (lifetype == IPSEC_DURATION_SECONDS)
458			{
459			  if (len == 2)
460			    sprintf (esp_life_seconds, "%u",
461				     decode_16 (value));
462			  else
463			    sprintf (esp_life_seconds, "%u",
464				     decode_32 (value));
465			}
466		      else
467			{
468			  if (len == 2)
469			    sprintf (esp_life_kbytes, "%u",
470				     decode_16 (value));
471			  else
472			    sprintf (esp_life_kbytes, "%u",
473				     decode_32 (value));
474			}
475
476		      break;
477
478		    case IPSEC_PROTO_IPCOMP:
479		      if (lifetype == IPSEC_DURATION_SECONDS)
480			{
481			  if (len == 2)
482			    sprintf (comp_life_seconds, "%u",
483				     decode_16 (value));
484			  else
485			    sprintf (comp_life_seconds, "%u",
486				     decode_32 (value));
487			}
488		      else
489			{
490			  if (len == 2)
491			    sprintf (comp_life_kbytes, "%u",
492				     decode_16 (value));
493			  else
494			    sprintf (comp_life_kbytes, "%u",
495				     decode_32 (value));
496			}
497
498		      break;
499		    }
500		  break;
501
502		case IPSEC_ATTR_GROUP_DESCRIPTION:
503		  switch (proto->proto)
504		    {
505		    case IPSEC_PROTO_IPSEC_AH:
506		      sprintf (ah_group_desc, "%u", decode_16 (value));
507		      break;
508
509		    case IPSEC_PROTO_IPSEC_ESP:
510		      sprintf (esp_group_desc, "%u",
511			       decode_16 (value));
512		      break;
513
514		    case IPSEC_PROTO_IPCOMP:
515		      sprintf (comp_group_desc, "%u",
516			       decode_16 (value));
517		      break;
518		    }
519		  break;
520
521		case IPSEC_ATTR_ENCAPSULATION_MODE:
522		  if (decode_16 (value) == IPSEC_ENCAP_TUNNEL)
523		    switch (proto->proto)
524		      {
525		      case IPSEC_PROTO_IPSEC_AH:
526			ah_encapsulation = "tunnel";
527			break;
528
529		      case IPSEC_PROTO_IPSEC_ESP:
530			esp_encapsulation = "tunnel";
531			break;
532
533		      case IPSEC_PROTO_IPCOMP:
534			comp_encapsulation = "tunnel";
535			break;
536		      }
537		  else
538		    switch (proto->proto)
539		      {
540		      case IPSEC_PROTO_IPSEC_AH:
541			ah_encapsulation = "transport";
542			break;
543
544		      case IPSEC_PROTO_IPSEC_ESP:
545			esp_encapsulation = "transport";
546			break;
547
548		      case IPSEC_PROTO_IPCOMP:
549			comp_encapsulation = "transport";
550			break;
551		      }
552		  break;
553
554		case IPSEC_ATTR_AUTHENTICATION_ALGORITHM:
555		  switch (proto->proto)
556		    {
557		    case IPSEC_PROTO_IPSEC_AH:
558		      switch (decode_16 (value))
559			{
560			case IPSEC_AUTH_HMAC_MD5:
561			  ah_auth_alg = "hmac-md5";
562			  break;
563
564			case IPSEC_AUTH_HMAC_SHA:
565			  ah_auth_alg = "hmac-sha";
566			  break;
567
568			case IPSEC_AUTH_HMAC_RIPEMD:
569			  ah_auth_alg = "hmac-ripemd";
570			  break;
571
572			case IPSEC_AUTH_DES_MAC:
573			  ah_auth_alg = "des-mac";
574			  break;
575
576			case IPSEC_AUTH_KPDK:
577			  ah_auth_alg = "kpdk";
578			  break;
579			}
580		      break;
581
582		    case IPSEC_PROTO_IPSEC_ESP:
583		      switch (decode_16 (value))
584			{
585			case IPSEC_AUTH_HMAC_MD5:
586			  esp_auth_alg = "hmac-md5";
587			  break;
588
589			case IPSEC_AUTH_HMAC_SHA:
590			  esp_auth_alg = "hmac-sha";
591			  break;
592
593			case IPSEC_AUTH_HMAC_RIPEMD:
594			  esp_auth_alg = "hmac-ripemd";
595			  break;
596
597			case IPSEC_AUTH_DES_MAC:
598			  esp_auth_alg = "des-mac";
599			  break;
600
601			case IPSEC_AUTH_KPDK:
602			  esp_auth_alg = "kpdk";
603			  break;
604			}
605		      break;
606		    }
607		  break;
608
609		case IPSEC_ATTR_KEY_LENGTH:
610		  switch (proto->proto)
611		    {
612		    case IPSEC_PROTO_IPSEC_AH:
613		      sprintf (ah_key_length, "%u", decode_16 (value));
614		      break;
615
616		    case IPSEC_PROTO_IPSEC_ESP:
617		      sprintf (esp_key_length, "%u",
618			       decode_16 (value));
619		      break;
620		    }
621		  break;
622
623		case IPSEC_ATTR_KEY_ROUNDS:
624		  switch (proto->proto)
625		    {
626		    case IPSEC_PROTO_IPSEC_AH:
627		      sprintf (ah_key_rounds, "%u", decode_16 (value));
628		      break;
629
630		    case IPSEC_PROTO_IPSEC_ESP:
631		      sprintf (esp_key_rounds, "%u",
632			       decode_16 (value));
633		      break;
634		    }
635		  break;
636
637		case IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE:
638		  sprintf (comp_dict_size, "%u", decode_16 (value));
639		  break;
640
641		case IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM:
642		  sprintf (comp_private_alg, "%u", decode_16 (value));
643		  break;
644		}
645	    }
646	}
647
648      policy_sa->transport->vtbl->get_src (policy_sa->transport, &sin);
649      if (sockaddr2text (sin, &addr, 1))
650	{
651	  log_error ("policy_callback: sockaddr2text failed");
652	  goto bad;
653	}
654      strncpy (local_ike_address, addr, sizeof local_ike_address);
655      local_ike_address[sizeof local_ike_address - 1] = '\0';
656      free (addr);
657
658      policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
659      if (sockaddr2text (sin, &addr, 1))
660	{
661	  log_error ("policy_callback: sockaddr2text failed");
662	  goto bad;
663	}
664      strncpy (remote_ike_address, addr, sizeof remote_ike_address);
665      remote_ike_address[sizeof remote_ike_address - 1] = '\0';
666      free (addr);
667
668      switch (policy_isakmp_sa->exch_type)
669	{
670	case ISAKMP_EXCH_AGGRESSIVE:
671	  phase_1 = "aggressive";
672	  break;
673
674	case ISAKMP_EXCH_ID_PROT:
675	  phase_1 = "main";
676	  break;
677	}
678
679      if (policy_isakmp_sa->initiator)
680        {
681	  id = policy_isakmp_sa->id_r;
682	  id_sz = policy_isakmp_sa->id_r_len;
683	}
684      else
685        {
686	  id = policy_isakmp_sa->id_i;
687	  id_sz = policy_isakmp_sa->id_i_len;
688	}
689
690      switch (id[0])
691        {
692	case IPSEC_ID_IPV4_ADDR:
693	  remote_id_type = "IPv4 address";
694
695	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
696	  my_inet_ntop4 (&net, remote_id_addr_upper,
697			 sizeof remote_id_addr_upper - 1, 1);
698	  my_inet_ntop4 (&net, remote_id_addr_lower,
699			 sizeof remote_id_addr_lower - 1, 1);
700	  remote_id = strdup (remote_id_addr_upper);
701	  if (!remote_id)
702  	    {
703	      log_error ("policy_callback: strdup (\"%s\") failed",
704			 remote_id_addr_upper);
705	      goto bad;
706	    }
707	  break;
708
709	case IPSEC_ID_IPV4_RANGE:
710	  remote_id_type = "IPv4 range";
711
712	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
713	  my_inet_ntop4 (&net, remote_id_addr_lower,
714			 sizeof remote_id_addr_lower - 1, 1);
715	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
716	  my_inet_ntop4 (&net, remote_id_addr_upper,
717			 sizeof remote_id_addr_upper - 1, 1);
718	  remote_id = calloc (strlen (remote_id_addr_upper)
719			      + strlen (remote_id_addr_lower) + 2,
720			      sizeof (char));
721	  if (!remote_id)
722	    {
723	      log_error ("policy_callback: calloc (%d, %d) failed",
724			 strlen (remote_id_addr_upper)
725			 + strlen (remote_id_addr_lower) + 2,
726			 sizeof (char));
727	      goto bad;
728	    }
729
730	  strcpy (remote_id, remote_id_addr_lower);
731	  remote_id[strlen (remote_id_addr_lower)] = '-';
732	  strcpy (remote_id + strlen (remote_id_addr_lower) + 1,
733		  remote_id_addr_upper);
734	  break;
735
736	case IPSEC_ID_IPV4_ADDR_SUBNET:
737	  remote_id_type = "IPv4 subnet";
738
739	  net = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ);
740	  subnet = decode_32 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ + 4);
741	  net &= subnet;
742	  my_inet_ntop4 (&net, remote_id_addr_lower,
743			 sizeof remote_id_addr_lower - 1, 1);
744	  net |= ~subnet;
745	  my_inet_ntop4 (&net, remote_id_addr_upper,
746			 sizeof remote_id_addr_upper - 1, 1);
747	  remote_id = calloc (strlen (remote_id_addr_upper)
748			      + strlen (remote_id_addr_lower) + 2,
749			      sizeof (char));
750	  if (!remote_id)
751	    {
752	      log_error ("policy_callback: calloc (%d, %d) failed",
753			 strlen (remote_id_addr_upper)
754			 + strlen (remote_id_addr_lower) + 2,
755			 sizeof (char));
756	      goto bad;
757	    }
758
759	  strcpy (remote_id, remote_id_addr_lower);
760	  remote_id[strlen (remote_id_addr_lower)] = '-';
761	  strcpy (remote_id + strlen (remote_id_addr_lower) + 1,
762		  remote_id_addr_upper);
763	  break;
764
765	case IPSEC_ID_IPV6_ADDR:
766	  remote_id_type = "IPv6 address";
767	  my_inet_ntop6 (id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
768	                 remote_id_addr_upper, sizeof remote_id_addr_upper);
769	  strcpy (remote_id_addr_lower, remote_id_addr_upper);
770	  remote_id = strdup (remote_id_addr_upper);
771	  if (!remote_id)
772  	    {
773	      log_error ("policy_callback: strdup (\"%s\") failed",
774			 remote_id_addr_upper);
775	      goto bad;
776	    }
777	  break;
778
779	case IPSEC_ID_IPV6_RANGE:
780	  /* XXX Not yet implemented.  */
781	  remote_id_type = "IPv6 range";
782	  break;
783
784	case IPSEC_ID_IPV6_ADDR_SUBNET:
785	  /* XXX Not yet implemented.  */
786	  remote_id_type = "IPv6 address";
787	  break;
788
789	case IPSEC_ID_FQDN:
790	  remote_id_type = "FQDN";
791	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
792			      sizeof (char));
793	  if (!remote_id)
794	    {
795	      log_error ("policy_callback: calloc (%d, %d) failed",
796			 id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
797			 sizeof (char));
798	      goto bad;
799	    }
800	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
801		  id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
802	  break;
803
804	case IPSEC_ID_USER_FQDN:
805	  remote_id_type = "User FQDN";
806	  remote_id = calloc (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
807			      sizeof (char));
808	  if (!remote_id)
809	    {
810	      log_error ("policy_callback: calloc (%d, %d) failed",
811			 id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ + 1,
812			 sizeof (char));
813	      goto bad;
814	    }
815	  memcpy (remote_id, id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ,
816		  id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ);
817	  break;
818
819	case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
820	  remote_id_type = "ASN1 DN";
821	  break;
822
823	case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
824	  remote_id_type = "ASN1 GN";
825	  break;
826
827	case IPSEC_ID_KEY_ID:
828	  remote_id_type = "Key ID";
829	  remote_id
830	    = calloc (2 * (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
831		      sizeof (char));
832	  if (!remote_id)
833	    {
834	      log_error ("policy_callback: calloc (%d, %d) failed",
835			 2 * (id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ) + 1,
836			 sizeof (char));
837	      goto bad;
838	    }
839          for (i = 0; i < id_sz - ISAKMP_ID_DATA_OFF + ISAKMP_GEN_SZ; i++)
840	    {
841	      remote_id[2 * i]
842		= hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) >> 4];
843	      remote_id[2 * i + 1]
844		= hextab[*(id + ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ) & 0xF];
845	    }
846	  break;
847
848	default:
849	  log_print ("policy_callback: unknown remote ID type %u", id[0]);
850	  goto bad;
851	}
852
853      switch (id[1])
854        {
855	case IPPROTO_TCP:
856	  remote_id_proto = "tcp";
857	  break;
858
859	case IPPROTO_UDP:
860	  remote_id_proto = "udp";
861	  break;
862
863#ifdef IPPROTO_ETHERIP
864	case IPPROTO_ETHERIP:
865	  remote_id_proto = "etherip";
866	  break;
867#endif
868
869 	default:
870	  sprintf (remote_id_proto_num, "%2d", id[1]);
871	  remote_id_proto = remote_id_proto_num;
872	  break;
873	}
874
875      snprintf (remote_id_port, sizeof remote_id_port - 1, "%u",
876		decode_16 (id + 2));
877
878      if (policy_exchange->initiator)
879        {
880	  initiator = "yes";
881	  idlocal = ie->id_ci;
882	  idremote = ie->id_cr;
883	  idlocalsz = ie->id_ci_sz;
884	  idremotesz = ie->id_cr_sz;
885        }
886      else
887        {
888	  initiator = "no";
889	  idlocal = ie->id_cr;
890	  idremote = ie->id_ci;
891	  idlocalsz = ie->id_cr_sz;
892	  idremotesz = ie->id_ci_sz;
893	}
894
895      /* Initialize the ID variables.  */
896      if (idremote)
897        {
898	  switch (GET_ISAKMP_ID_TYPE (idremote))
899	    {
900	    case IPSEC_ID_IPV4_ADDR:
901	      remote_filter_type = "IPv4 address";
902
903	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
904	      my_inet_ntop4 (&net, remote_filter_addr_upper,
905			     sizeof remote_filter_addr_upper - 1, 1);
906	      my_inet_ntop4 (&net, remote_filter_addr_lower,
907			     sizeof remote_filter_addr_lower - 1, 1);
908	      remote_filter = strdup (remote_filter_addr_upper);
909	      if (!remote_filter)
910	        {
911		  log_error ("policy_callback: strdup (\"%s\") failed",
912			     remote_filter_addr_upper);
913		  goto bad;
914		}
915	      break;
916
917	    case IPSEC_ID_IPV4_RANGE:
918	      remote_filter_type = "IPv4 range";
919
920	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
921	      my_inet_ntop4 (&net, remote_filter_addr_lower,
922			     sizeof remote_filter_addr_lower - 1, 1);
923	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
924	      my_inet_ntop4 (&net, remote_filter_addr_upper,
925			     sizeof remote_filter_addr_upper - 1, 1);
926	      remote_filter = calloc (strlen (remote_filter_addr_upper)
927				      + strlen (remote_filter_addr_lower) + 2,
928				      sizeof (char));
929	      if (!remote_filter)
930	        {
931		  log_error ("policy_callback: calloc (%d, %d) failed",
932			     strlen (remote_filter_addr_upper)
933			     + strlen (remote_filter_addr_lower) + 2,
934			     sizeof (char));
935		  goto bad;
936		}
937	      strcpy (remote_filter, remote_filter_addr_lower);
938	      remote_filter[strlen (remote_filter_addr_lower)] = '-';
939	      strcpy (remote_filter + strlen (remote_filter_addr_lower) + 1,
940		      remote_filter_addr_upper);
941	      break;
942
943	    case IPSEC_ID_IPV4_ADDR_SUBNET:
944	      remote_filter_type = "IPv4 subnet";
945
946	      net = decode_32 (idremote + ISAKMP_ID_DATA_OFF);
947	      subnet = decode_32 (idremote + ISAKMP_ID_DATA_OFF + 4);
948	      net &= subnet;
949	      my_inet_ntop4 (&net, remote_filter_addr_lower,
950			     sizeof remote_filter_addr_lower - 1, 1);
951	      net |= ~subnet;
952	      my_inet_ntop4 (&net, remote_filter_addr_upper,
953			     sizeof remote_filter_addr_upper - 1, 1);
954	      remote_filter = calloc (strlen (remote_filter_addr_upper)
955				      + strlen (remote_filter_addr_lower) + 2,
956				      sizeof (char));
957	      if (!remote_filter)
958	        {
959		  log_error ("policy_callback: calloc (%d, %d) failed",
960			     strlen (remote_filter_addr_upper)
961			     + strlen (remote_filter_addr_lower) + 2,
962			     sizeof (char));
963		  goto bad;
964		}
965	      strcpy (remote_filter, remote_filter_addr_lower);
966	      remote_filter[strlen (remote_filter_addr_lower)] = '-';
967	      strcpy (remote_filter + strlen (remote_filter_addr_lower) + 1,
968		      remote_filter_addr_upper);
969	      break;
970
971	    case IPSEC_ID_IPV6_ADDR:
972	      remote_filter_type = "IPv6 address";
973	      my_inet_ntop6 (idremote + ISAKMP_ID_DATA_OFF,
974			     remote_filter_addr_upper,
975			     sizeof remote_filter_addr_upper - 1);
976	      strcpy (remote_filter_addr_lower, remote_filter_addr_upper);
977	      remote_filter = strdup (remote_filter_addr_upper);
978	      if (!remote_filter)
979	        {
980		  log_error ("policy_callback: strdup (\"%s\") failed",
981			     remote_filter_addr_upper);
982		  goto bad;
983		}
984	      break;
985
986	    case IPSEC_ID_IPV6_RANGE:
987	      /* XXX Not yet implemented.  */
988	      remote_filter_type = "IPv6 range";
989	      break;
990
991	    case IPSEC_ID_IPV6_ADDR_SUBNET:
992	      /* XXX Not yet implemented.  */
993	      remote_filter_type = "IPv6 subnet";
994	      break;
995
996	    case IPSEC_ID_FQDN:
997	      remote_filter_type = "FQDN";
998	      remote_filter = calloc (idremotesz - ISAKMP_ID_DATA_OFF + 1,
999				      sizeof (char));
1000	      if (!remote_filter)
1001	        {
1002		  log_error ("policy_callback: calloc (%d, %d) failed",
1003			     idremotesz - ISAKMP_ID_DATA_OFF + 1,
1004			     sizeof (char));
1005		  goto bad;
1006		}
1007	      memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
1008		      idremotesz);
1009	      break;
1010
1011	    case IPSEC_ID_USER_FQDN:
1012	      remote_filter_type = "User FQDN";
1013	      remote_filter = calloc (idremotesz - ISAKMP_ID_DATA_OFF + 1,
1014				      sizeof (char));
1015	      if (!remote_filter)
1016	        {
1017		  log_error ("policy_callback: calloc (%d, %d) failed",
1018			     idremotesz - ISAKMP_ID_DATA_OFF + 1,
1019			     sizeof (char));
1020		  goto bad;
1021		}
1022	      memcpy (remote_filter, idremote + ISAKMP_ID_DATA_OFF,
1023		      idremotesz);
1024	      break;
1025
1026	    case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
1027	      remote_filter_type = "ASN1 DN";
1028	      break;
1029
1030	    case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
1031	      remote_filter_type = "ASN1 GN";
1032	      break;
1033
1034	    case IPSEC_ID_KEY_ID:
1035	      remote_filter_type = "Key ID";
1036	      remote_filter
1037		= calloc (2 * (idremotesz - ISAKMP_ID_DATA_OFF) + 1,
1038			  sizeof (char));
1039	      if (!remote_filter)
1040	        {
1041		  log_error ("policy_callback: calloc (%d, %d) failed",
1042			     2 * (idremotesz - ISAKMP_ID_DATA_OFF) + 1,
1043			     sizeof (char));
1044		  goto bad;
1045	        }
1046              for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
1047	        {
1048		  remote_filter[2 * i]
1049		    = hextab[*(idremote + ISAKMP_ID_DATA_OFF) >> 4];
1050		  remote_filter[2 * i + 1]
1051		    = hextab[*(idremote + ISAKMP_ID_DATA_OFF) & 0xF];
1052	        }
1053	      break;
1054
1055	    default:
1056	      log_print ("policy_callback: unknown Remote ID type %u",
1057			 GET_ISAKMP_ID_TYPE (idremote));
1058	      goto bad;
1059	    }
1060
1061	  switch (idremote[ISAKMP_GEN_SZ + 1])
1062	    {
1063	    case IPPROTO_TCP:
1064	      remote_filter_proto = "tcp";
1065	      break;
1066
1067	    case IPPROTO_UDP:
1068	      remote_filter_proto = "udp";
1069	      break;
1070
1071#ifdef IPPROTO_ETHERIP
1072	    case IPPROTO_ETHERIP:
1073	      remote_filter_proto = "etherip";
1074	      break;
1075#endif
1076
1077 	    default:
1078	      sprintf (remote_filter_proto_num, "%2d",
1079		       idremote[ISAKMP_GEN_SZ + 1]);
1080	      remote_filter_proto = remote_filter_proto_num;
1081	      break;
1082	    }
1083
1084	  snprintf (remote_filter_port, sizeof remote_filter_port - 1,
1085		    "%u", decode_16 (idremote + ISAKMP_GEN_SZ + 2));
1086	}
1087      else
1088        {
1089	  policy_sa->transport->vtbl->get_dst (policy_sa->transport, &sin);
1090	  switch (sin->sa_family)
1091	    {
1092	    case AF_INET:
1093	      remote_filter_type = "IPv4 address";
1094	      break;
1095	    case AF_INET6:
1096	      remote_filter_type = "IPv6 address";
1097	      break;
1098	    default:
1099	      log_print ("policy_callback: unsupported protocol family %d",
1100			 sin->sa_family);
1101	      goto bad;
1102	    }
1103	  if (sockaddr2text (sin, &addr, 1))
1104	    {
1105	      log_error ("policy_callback: sockaddr2text failed");
1106	      goto bad;
1107	    }
1108	  memcpy (remote_filter_addr_upper, addr,
1109		  sizeof remote_filter_addr_upper);
1110	  memcpy (remote_filter_addr_lower, addr,
1111		  sizeof remote_filter_addr_lower);
1112	  free (addr);
1113	  remote_filter = strdup (remote_filter_addr_upper);
1114	  if (!remote_filter)
1115	    {
1116	      log_error ("policy_callback: strdup (\"%s\") failed",
1117			 remote_filter_addr_upper);
1118	      goto bad;
1119	    }
1120	}
1121
1122      if (idlocal)
1123        {
1124	  switch (GET_ISAKMP_ID_TYPE (idlocal))
1125	    {
1126	    case IPSEC_ID_IPV4_ADDR:
1127	      local_filter_type = "IPv4 address";
1128
1129	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1130	      my_inet_ntop4 (&net, local_filter_addr_upper,
1131			     sizeof local_filter_addr_upper - 1, 1);
1132	      my_inet_ntop4 (&net, local_filter_addr_lower,
1133			     sizeof local_filter_addr_upper - 1, 1);
1134	      local_filter = strdup (local_filter_addr_upper);
1135	      if (!local_filter)
1136	        {
1137		  log_error ("policy_callback: strdup (\"%s\") failed",
1138			     local_filter_addr_upper);
1139		  goto bad;
1140		}
1141	      break;
1142
1143	    case IPSEC_ID_IPV4_RANGE:
1144	      local_filter_type = "IPv4 range";
1145
1146	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1147	      my_inet_ntop4 (&net, local_filter_addr_lower,
1148			     sizeof local_filter_addr_lower - 1, 1);
1149	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
1150	      my_inet_ntop4 (&net, local_filter_addr_upper,
1151			     sizeof local_filter_addr_upper - 1, 1);
1152	      local_filter = calloc (strlen (local_filter_addr_upper)
1153				     + strlen (local_filter_addr_lower) + 2,
1154				     sizeof (char));
1155	      if (!local_filter)
1156	        {
1157		  log_error ("policy_callback: calloc (%d, %d) failed",
1158			     strlen (local_filter_addr_upper)
1159			     + strlen (local_filter_addr_lower) + 2,
1160			     sizeof (char));
1161		  goto bad;
1162		}
1163	      strcpy (local_filter, local_filter_addr_lower);
1164	      local_filter[strlen (local_filter_addr_lower)] = '-';
1165	      strcpy (local_filter + strlen (local_filter_addr_lower) + 1,
1166		      local_filter_addr_upper);
1167	      break;
1168
1169	    case IPSEC_ID_IPV4_ADDR_SUBNET:
1170	      local_filter_type = "IPv4 subnet";
1171
1172	      net = decode_32 (idlocal + ISAKMP_ID_DATA_OFF);
1173	      subnet = decode_32 (idlocal + ISAKMP_ID_DATA_OFF + 4);
1174	      net &= subnet;
1175	      my_inet_ntop4 (&net, local_filter_addr_lower,
1176			     sizeof local_filter_addr_lower - 1, 1);
1177	      net |= ~subnet;
1178	      my_inet_ntop4 (&net, local_filter_addr_upper,
1179			     sizeof local_filter_addr_upper - 1, 1);
1180	      local_filter = calloc (strlen (local_filter_addr_upper)
1181				     + strlen (local_filter_addr_lower) + 2,
1182				     sizeof (char));
1183	      if (!local_filter)
1184	        {
1185		  log_error ("policy_callback: calloc (%d, %d) failed",
1186			     strlen (local_filter_addr_upper)
1187			     + strlen (local_filter_addr_lower) + 2,
1188			     sizeof (char));
1189		  goto bad;
1190		}
1191	      strcpy (local_filter, local_filter_addr_lower);
1192	      local_filter[strlen (local_filter_addr_lower)] = '-';
1193	      strcpy (local_filter + strlen (local_filter_addr_lower) + 1,
1194		      local_filter_addr_upper);
1195	      break;
1196
1197	    case IPSEC_ID_IPV6_ADDR:
1198	      local_filter_type = "IPv6 address";
1199	      my_inet_ntop6 (idlocal + ISAKMP_ID_DATA_OFF,
1200			     local_filter_addr_upper,
1201			     sizeof local_filter_addr_upper - 1);
1202	      strcpy (local_filter_addr_lower, local_filter_addr_upper);
1203	      local_filter = strdup (local_filter_addr_upper);
1204	      if (!local_filter)
1205	        {
1206		  log_error ("policy_callback: strdup (\"%s\") failed",
1207			     local_filter_addr_upper);
1208		  goto bad;
1209		}
1210	      break;
1211
1212	    case IPSEC_ID_IPV6_RANGE:
1213	      /* XXX Not yet implemented.  */
1214	      local_filter_type = "IPv6 range";
1215	      break;
1216
1217	    case IPSEC_ID_IPV6_ADDR_SUBNET:
1218	      /* XXX Not yet implemented.  */
1219	      local_filter_type = "IPv6 subnet";
1220	      break;
1221
1222	    case IPSEC_ID_FQDN:
1223	      local_filter_type = "FQDN";
1224	      local_filter = calloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1,
1225				     sizeof (char));
1226	      if (!local_filter)
1227	        {
1228		  log_error ("policy_callback: calloc (%d, %d) failed",
1229			     idlocalsz - ISAKMP_ID_DATA_OFF + 1,
1230			     sizeof (char));
1231		  goto bad;
1232		}
1233	      memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
1234		      idlocalsz);
1235	      break;
1236
1237	    case IPSEC_ID_USER_FQDN:
1238	      local_filter_type = "User FQDN";
1239	      local_filter = calloc (idlocalsz - ISAKMP_ID_DATA_OFF + 1,
1240				     sizeof (char));
1241	      if (!local_filter)
1242	        {
1243		  log_error ("policy_callback: calloc (%d, %d) failed",
1244			     idlocalsz - ISAKMP_ID_DATA_OFF + 1,
1245			     sizeof (char));
1246		  goto bad;
1247		}
1248	      memcpy (local_filter, idlocal + ISAKMP_ID_DATA_OFF,
1249		      idlocalsz);
1250	      break;
1251
1252	    case IPSEC_ID_DER_ASN1_DN: /* XXX -- not sure what's in this.  */
1253	      local_filter_type = "ASN1 DN";
1254	      break;
1255
1256	    case IPSEC_ID_DER_ASN1_GN: /* XXX -- not sure what's in this.  */
1257	      local_filter_type = "ASN1 GN";
1258	      break;
1259
1260	    case IPSEC_ID_KEY_ID:
1261	      local_filter_type = "Key ID";
1262	      local_filter = calloc (2 * (idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
1263				     sizeof (char));
1264	      if (!local_filter)
1265	        {
1266		  log_error ("policy_callback: calloc (%d, %d) failed",
1267			     2 * (idlocalsz - ISAKMP_ID_DATA_OFF) + 1,
1268			     sizeof (char));
1269		  goto bad;
1270	        }
1271              for (i = 0; i < idremotesz - ISAKMP_ID_DATA_OFF; i++)
1272	        {
1273		  local_filter[2 * i]
1274		    = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) >> 4];
1275		  local_filter[2 * i + 1]
1276		    = hextab[*(idlocal + ISAKMP_ID_DATA_OFF) & 0xF];
1277	        }
1278	      break;
1279
1280	    default:
1281	      log_print ("policy_callback: unknown Local ID type %u",
1282			 GET_ISAKMP_ID_TYPE (idlocal));
1283	      goto bad;
1284	    }
1285
1286	  switch (idlocal[ISAKMP_GEN_SZ + 1])
1287	    {
1288	    case IPPROTO_TCP:
1289	      local_filter_proto = "tcp";
1290	      break;
1291
1292	    case IPPROTO_UDP:
1293	      local_filter_proto = "udp";
1294	      break;
1295
1296#ifdef IPPROTO_ETHERIP
1297	    case IPPROTO_ETHERIP:
1298	      local_filter_proto = "etherip";
1299	      break;
1300#endif
1301
1302 	    default:
1303	      sprintf (local_filter_proto_num, "%2d",
1304		       idlocal[ISAKMP_GEN_SZ + 1]);
1305	      local_filter_proto = local_filter_proto_num;
1306	      break;
1307	    }
1308
1309	  snprintf (local_filter_port, sizeof local_filter_port - 1,
1310		    "%u", decode_16 (idlocal + ISAKMP_GEN_SZ + 2));
1311	}
1312      else
1313        {
1314	  policy_sa->transport->vtbl->get_src (policy_sa->transport,
1315					       (struct sockaddr **)&sin);
1316	  switch (sin->sa_family)
1317	    {
1318	    case AF_INET:
1319	      local_filter_type = "IPv4 address";
1320	      break;
1321	    case AF_INET6:
1322	      local_filter_type = "IPv6 address";
1323	      break;
1324	    default:
1325	      log_print ("policy_callback: unsupported protocol family %d",
1326			 sin->sa_family);
1327	      goto bad;
1328	    }
1329
1330	  if (sockaddr2text (sin, &addr, 1))
1331	    {
1332	      log_error ("policy_callback: sockaddr2text failed");
1333	      goto bad;
1334	    }
1335	  memcpy (local_filter_addr_upper, addr,
1336		  sizeof local_filter_addr_upper);
1337	  memcpy (local_filter_addr_lower, addr,
1338		  sizeof local_filter_addr_lower);
1339	  free (addr);
1340	  local_filter = strdup (local_filter_addr_upper);
1341	  if (!local_filter)
1342	    {
1343	      log_error ("policy_callback: strdup (\"%s\") failed",
1344			 local_filter_addr_upper);
1345	      goto bad;
1346	    }
1347        }
1348
1349      LOG_DBG ((LOG_POLICY, 80, "Policy context (action attributes):"));
1350      LOG_DBG ((LOG_POLICY, 80, "esp_present == %s", esp_present));
1351      LOG_DBG ((LOG_POLICY, 80, "ah_present == %s", ah_present));
1352      LOG_DBG ((LOG_POLICY, 80, "comp_present == %s", comp_present));
1353      LOG_DBG ((LOG_POLICY, 80, "ah_hash_alg == %s", ah_hash_alg));
1354      LOG_DBG ((LOG_POLICY, 80, "esp_enc_alg == %s", esp_enc_alg));
1355      LOG_DBG ((LOG_POLICY, 80, "comp_alg == %s", comp_alg));
1356      LOG_DBG ((LOG_POLICY, 80, "ah_auth_alg == %s", ah_auth_alg));
1357      LOG_DBG ((LOG_POLICY, 80, "esp_auth_alg == %s", esp_auth_alg));
1358      LOG_DBG ((LOG_POLICY, 80, "ah_life_seconds == %s", ah_life_seconds));
1359      LOG_DBG ((LOG_POLICY, 80, "ah_life_kbytes == %s", ah_life_kbytes));
1360      LOG_DBG ((LOG_POLICY, 80, "esp_life_seconds == %s", esp_life_seconds));
1361      LOG_DBG ((LOG_POLICY, 80, "esp_life_kbytes == %s", esp_life_kbytes));
1362      LOG_DBG ((LOG_POLICY, 80, "comp_life_seconds == %s", comp_life_seconds));
1363      LOG_DBG ((LOG_POLICY, 80, "comp_life_kbytes == %s", comp_life_kbytes));
1364      LOG_DBG ((LOG_POLICY, 80, "ah_encapsulation == %s", ah_encapsulation));
1365      LOG_DBG ((LOG_POLICY, 80, "esp_encapsulation == %s", esp_encapsulation));
1366      LOG_DBG ((LOG_POLICY, 80, "comp_encapsulation == %s",
1367		comp_encapsulation));
1368      LOG_DBG ((LOG_POLICY, 80, "comp_dict_size == %s", comp_dict_size));
1369      LOG_DBG ((LOG_POLICY, 80, "comp_private_alg == %s", comp_private_alg));
1370      LOG_DBG ((LOG_POLICY, 80, "ah_key_length == %s", ah_key_length));
1371      LOG_DBG ((LOG_POLICY, 80, "ah_key_rounds == %s", ah_key_rounds));
1372      LOG_DBG ((LOG_POLICY, 80, "esp_key_length == %s", esp_key_length));
1373      LOG_DBG ((LOG_POLICY, 80, "esp_key_rounds == %s", esp_key_rounds));
1374      LOG_DBG ((LOG_POLICY, 80, "ah_group_desc == %s", ah_group_desc));
1375      LOG_DBG ((LOG_POLICY, 80, "esp_group_desc == %s", esp_group_desc));
1376      LOG_DBG ((LOG_POLICY, 80, "comp_group_desc == %s", comp_group_desc));
1377      LOG_DBG ((LOG_POLICY, 80, "remote_filter_type == %s",
1378		remote_filter_type));
1379      LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_upper == %s",
1380		remote_filter_addr_upper));
1381      LOG_DBG ((LOG_POLICY, 80, "remote_filter_addr_lower == %s",
1382		remote_filter_addr_lower));
1383      LOG_DBG ((LOG_POLICY, 80, "remote_filter == %s",
1384		(remote_filter ? remote_filter : "")));
1385      LOG_DBG ((LOG_POLICY, 80, "remote_filter_port == %s",
1386		remote_filter_port));
1387      LOG_DBG ((LOG_POLICY, 80, "remote_filter_proto == %s",
1388		remote_filter_proto));
1389      LOG_DBG ((LOG_POLICY, 80, "local_filter_type == %s", local_filter_type));
1390      LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_upper == %s",
1391		local_filter_addr_upper));
1392      LOG_DBG ((LOG_POLICY, 80, "local_filter_addr_lower == %s",
1393		local_filter_addr_lower));
1394      LOG_DBG ((LOG_POLICY, 80, "local_filter == %s",
1395		(local_filter ? local_filter : "")));
1396      LOG_DBG ((LOG_POLICY, 80, "local_filter_port == %s", local_filter_port));
1397      LOG_DBG ((LOG_POLICY, 80, "local_filter_proto == %s",
1398		local_filter_proto));
1399      LOG_DBG ((LOG_POLICY, 80, "remote_id_type == %s", remote_id_type));
1400      LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_upper == %s",
1401		remote_id_addr_upper));
1402      LOG_DBG ((LOG_POLICY, 80, "remote_id_addr_lower == %s",
1403		remote_id_addr_lower));
1404      LOG_DBG ((LOG_POLICY, 80, "remote_id == %s",
1405		(remote_id ? remote_id : "")));
1406      LOG_DBG ((LOG_POLICY, 80, "remote_id_port == %s", remote_id_port));
1407      LOG_DBG ((LOG_POLICY, 80, "remote_id_proto == %s", remote_id_proto));
1408      LOG_DBG ((LOG_POLICY, 80, "remote_negotiation_address == %s",
1409		remote_ike_address));
1410      LOG_DBG ((LOG_POLICY, 80, "local_negotiation_address == %s",
1411		local_ike_address));
1412      LOG_DBG ((LOG_POLICY, 80, "pfs == %s", pfs));
1413      LOG_DBG ((LOG_POLICY, 80, "initiator == %s", initiator));
1414      LOG_DBG ((LOG_POLICY, 80, "phase1_group_desc == %s", phase1_group));
1415
1416      /* Unset dirty now.  */
1417      dirty = 0;
1418    }
1419
1420  if (strcmp (name, "phase_1") == 0)
1421    return phase_1;
1422
1423  if (strcmp (name, "GMTTimeOfDay") == 0)
1424    {
1425      tt = time ((time_t) NULL);
1426      strftime (mytimeofday, 14, "%G%m%d%H%M%S", gmtime (&tt));
1427      return mytimeofday;
1428    }
1429
1430  if (strcmp (name, "LocalTimeOfDay") == 0)
1431    {
1432      tt = time ((time_t) NULL);
1433      strftime (mytimeofday, 14, "%G%m%d%H%M%S", localtime (&tt));
1434      return mytimeofday;
1435    }
1436
1437  if (strcmp (name, "initiator") == 0)
1438    return initiator;
1439
1440  if (strcmp (name, "pfs") == 0)
1441    return pfs;
1442
1443  if (strcmp (name, "app_domain") == 0)
1444    return "IPsec policy";
1445
1446  if (strcmp (name, "doi") == 0)
1447    return "ipsec";
1448
1449  if (strcmp (name, "esp_present") == 0)
1450    return esp_present;
1451
1452  if (strcmp (name, "ah_present") == 0)
1453    return ah_present;
1454
1455  if (strcmp (name, "comp_present") == 0)
1456    return comp_present;
1457
1458  if (strcmp (name, "ah_hash_alg") == 0)
1459    return ah_hash_alg;
1460
1461  if (strcmp (name, "ah_auth_alg") == 0)
1462    return ah_auth_alg;
1463
1464  if (strcmp (name, "esp_auth_alg") == 0)
1465    return esp_auth_alg;
1466
1467  if (strcmp (name, "esp_enc_alg") == 0)
1468    return esp_enc_alg;
1469
1470  if (strcmp (name, "comp_alg") == 0)
1471    return comp_alg;
1472
1473  if (strcmp (name, "ah_life_kbytes") == 0)
1474    return ah_life_kbytes;
1475
1476  if (strcmp (name, "ah_life_seconds") == 0)
1477    return ah_life_seconds;
1478
1479  if (strcmp (name, "esp_life_kbytes") == 0)
1480    return esp_life_kbytes;
1481
1482  if (strcmp (name, "esp_life_seconds") == 0)
1483    return esp_life_seconds;
1484
1485  if (strcmp (name, "comp_life_kbytes") == 0)
1486    return comp_life_kbytes;
1487
1488  if (strcmp (name, "comp_life_seconds") == 0)
1489    return comp_life_seconds;
1490
1491  if (strcmp (name, "ah_encapsulation") == 0)
1492    return ah_encapsulation;
1493
1494  if (strcmp (name, "esp_encapsulation") == 0)
1495    return esp_encapsulation;
1496
1497  if (strcmp (name, "comp_encapsulation") == 0)
1498    return comp_encapsulation;
1499
1500  if (strcmp (name, "ah_key_length") == 0)
1501    return ah_key_length;
1502
1503  if (strcmp (name, "ah_key_rounds") == 0)
1504    return ah_key_rounds;
1505
1506  if (strcmp (name, "esp_key_length") == 0)
1507    return esp_key_length;
1508
1509  if (strcmp (name, "esp_key_rounds") == 0)
1510    return esp_key_rounds;
1511
1512  if (strcmp (name, "comp_dict_size") == 0)
1513    return comp_dict_size;
1514
1515  if (strcmp (name, "comp_private_alg") == 0)
1516    return comp_private_alg;
1517
1518  if (strcmp (name, "remote_filter_type") == 0)
1519    return remote_filter_type;
1520
1521  if (strcmp (name, "remote_filter") == 0)
1522    return (remote_filter ? remote_filter : "");
1523
1524  if (strcmp (name, "remote_filter_addr_upper") == 0)
1525    return remote_filter_addr_upper;
1526
1527  if (strcmp (name, "remote_filter_addr_lower") == 0)
1528    return remote_filter_addr_lower;
1529
1530  if (strcmp (name, "remote_filter_port") == 0)
1531    return remote_filter_port;
1532
1533  if (strcmp (name, "remote_filter_proto") == 0)
1534    return remote_filter_proto;
1535
1536  if (strcmp (name, "local_filter_type") == 0)
1537    return local_filter_type;
1538
1539  if (strcmp (name, "local_filter") == 0)
1540    return (local_filter ? local_filter : "");
1541
1542  if (strcmp (name, "local_filter_addr_upper") == 0)
1543    return local_filter_addr_upper;
1544
1545  if (strcmp (name, "local_filter_addr_lower") == 0)
1546    return local_filter_addr_lower;
1547
1548  if (strcmp (name, "local_filter_port") == 0)
1549    return local_filter_port;
1550
1551  if (strcmp (name, "local_filter_proto") == 0)
1552    return local_filter_proto;
1553
1554  if (strcmp (name, "remote_ike_address") == 0)
1555    return remote_ike_address;
1556
1557  if (strcmp (name, "remote_negotiation_address") == 0)
1558    return remote_ike_address;
1559
1560  if (strcmp (name, "local_ike_address") == 0)
1561    return local_ike_address;
1562
1563  if (strcmp (name, "local_negotiation_address") == 0)
1564    return local_ike_address;
1565
1566  if (strcmp (name, "remote_id_type") == 0)
1567    return remote_id_type;
1568
1569  if (strcmp (name, "remote_id") == 0)
1570    return (remote_id ? remote_id : "");
1571
1572  if (strcmp (name, "remote_id_addr_upper") == 0)
1573    return remote_id_addr_upper;
1574
1575  if (strcmp (name, "remote_id_addr_lower") == 0)
1576    return remote_id_addr_lower;
1577
1578  if (strcmp (name, "remote_id_port") == 0)
1579    return remote_id_port;
1580
1581  if (strcmp (name, "remote_id_proto") == 0)
1582    return remote_id_proto;
1583
1584  if (strcmp (name, "phase1_group_desc") == 0)
1585    return phase1_group;
1586
1587  return "";
1588
1589 bad:
1590  policy_callback (KEYNOTE_CALLBACK_INITIALIZE);
1591  return "";
1592}
1593
1594void
1595policy_init (void)
1596{
1597  char *ptr, *policy_file;
1598  char **asserts;
1599  off_t sz;
1600  int fd, len, i;
1601
1602  LOG_DBG ((LOG_POLICY, 30, "policy_init: initializing"));
1603
1604#if defined (HAVE_DLOPEN) && !defined (USE_KEYNOTE)
1605  if (!dyn_load (libkeynote_script))
1606    return;
1607#endif
1608
1609  /* Get policy file from configuration.  */
1610  policy_file = conf_get_str ("General", "Policy-file");
1611  if (!policy_file)
1612    policy_file = POLICY_FILE_DEFAULT;
1613
1614  /* Check file modes and collect file size */
1615  if (check_file_secrecy (policy_file, &sz))
1616    log_fatal ("policy_init: cannot read %s", policy_file);
1617
1618  /* Open policy file.  */
1619  fd = open (policy_file, O_RDONLY);
1620  if (fd == -1)
1621    log_fatal ("policy_init: open (\"%s\", O_RDONLY) failed", policy_file);
1622
1623  /* Allocate memory to keep policies.  */
1624  ptr = calloc (sz + 1, sizeof (char));
1625  if (!ptr)
1626    log_fatal ("policy_init: calloc (%d, %d) failed", sz + 1,
1627	       sizeof (char));
1628
1629  /* Just in case there are short reads...  */
1630  for (len = 0; len < sz; len += i)
1631    {
1632      i = read (fd, ptr + len, sz - len);
1633      if (i == -1)
1634	log_fatal ("policy_init: read (%d, %p, %d) failed", fd, ptr + len,
1635		   sz - len);
1636    }
1637
1638  /* We're done with this.  */
1639  close (fd);
1640
1641  /* Parse buffer, break up into individual policies.  */
1642  asserts = LK (kn_read_asserts, (ptr, sz, &i));
1643
1644  /* Begone!  */
1645  free (ptr);
1646
1647  if (asserts == (char **) NULL)
1648    log_print ("policy_init: all policies flushed");
1649
1650  /* Cleanup */
1651  if (keynote_policy_asserts)
1652    {
1653      for (fd = 0; fd < keynote_policy_asserts_num; fd++)
1654        if (keynote_policy_asserts && keynote_policy_asserts[fd])
1655          free (keynote_policy_asserts[fd]);
1656
1657      free (keynote_policy_asserts);
1658    }
1659
1660  keynote_policy_asserts = asserts;
1661  keynote_policy_asserts_num = i;
1662}
1663
1664/* Nothing needed for initialization */
1665int
1666keynote_cert_init (void)
1667{
1668  return 1;
1669}
1670
1671/* Just copy and return.  */
1672void *
1673keynote_cert_get (u_int8_t *data, u_int32_t len)
1674{
1675  char *foo = malloc (len + 1);
1676
1677  if (foo == NULL)
1678    return NULL;
1679
1680  memcpy (foo, data, len);
1681  foo[len] = '\0';
1682  return foo;
1683}
1684
1685/*
1686 * We just verify the signature on the credentials.
1687 * On signature failure, just drop the whole payload.
1688 */
1689int
1690keynote_cert_validate (void *scert)
1691{
1692  char **foo;
1693  int num, i;
1694
1695  if (scert == NULL)
1696    return 0;
1697
1698  foo = LK (kn_read_asserts, ((char *) scert, strlen ((char *) scert),
1699			      &num));
1700  if (foo == NULL)
1701    return 0;
1702
1703  for (i = 0; i < num; i++)
1704    {
1705      if (LK (kn_verify_assertion, (scert, strlen ((char *) scert)))
1706	  != SIGRESULT_TRUE)
1707        {
1708	  for (; i < num; i++)
1709	    free (foo[i]);
1710	  free (foo);
1711	  return 0;
1712	}
1713
1714      free (foo[i]);
1715    }
1716
1717  free (foo);
1718  return 1;
1719}
1720
1721/* Add received credentials.  */
1722int
1723keynote_cert_insert (int sid, void *scert)
1724{
1725  char **foo;
1726  int num;
1727
1728  if (scert == NULL)
1729    return 0;
1730
1731  foo = LK (kn_read_asserts, ((char *) scert, strlen ((char *) scert),
1732			      &num));
1733  if (foo == NULL)
1734    return 0;
1735
1736  while (num--)
1737    LK (kn_add_assertion, (sid, foo[num], strlen (foo[num]), 0));
1738
1739  return 1;
1740}
1741
1742/* Just regular memory free.  */
1743void
1744keynote_cert_free (void *cert)
1745{
1746  free (cert);
1747}
1748
1749/* Verify that the key given to us is valid.  */
1750int
1751keynote_certreq_validate (u_int8_t *data, u_int32_t len)
1752{
1753  struct keynote_deckey dc;
1754  int err = 1;
1755  char *dat;
1756
1757  dat = calloc (len + 1, sizeof (char));
1758  if (!dat)
1759    {
1760      log_error ("keynote_certreq_validate: calloc (%d, %d) failed", len + 1,
1761		 sizeof (char));
1762	return 0;
1763    }
1764
1765  memcpy (dat, data, len);
1766
1767  if (LK (kn_decode_key, (&dc, dat, KEYNOTE_PUBLIC_KEY)) != 0)
1768    err = 0;
1769  else
1770    LK (kn_free_key, (&dc));
1771
1772  free (dat);
1773
1774  return err;
1775}
1776
1777/* Beats me what we should be doing with this.  */
1778void *
1779keynote_certreq_decode (u_int8_t *data, u_int32_t len)
1780{
1781  /* XXX */
1782  return NULL;
1783}
1784
1785void
1786keynote_free_aca (void *blob)
1787{
1788  /* XXX */
1789}
1790
1791int
1792keynote_cert_obtain (u_int8_t *id, size_t id_len, void *data, u_int8_t **cert,
1793		     u_int32_t *certlen)
1794{
1795  char *dirname, *file, *addr_str;
1796  struct stat sb;
1797  int idtype, fd, len;
1798
1799  if (!id)
1800    {
1801      log_print ("keynote_cert_obtain: ID is missing");
1802      return 0;
1803    }
1804
1805  /* Get type of ID.  */
1806  idtype = id[0];
1807  id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
1808  id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ;
1809
1810  dirname = conf_get_str ("KeyNote", "Credential-directory");
1811  if (!dirname)
1812    {
1813      LOG_DBG ((LOG_POLICY, 30,
1814		"keynote_cert_obtain: no Credential-directory"));
1815      return 0;
1816    }
1817
1818  len = strlen (dirname) + strlen (CREDENTIAL_FILE) + 3;
1819
1820  switch (idtype)
1821    {
1822    case IPSEC_ID_IPV4_ADDR:
1823    case IPSEC_ID_IPV6_ADDR:
1824      util_ntoa (&addr_str, idtype == IPSEC_ID_IPV4_ADDR ? AF_INET : AF_INET6,
1825		 id);
1826      if (addr_str == 0)
1827	return 0;
1828
1829      file = calloc (len + strlen (addr_str), sizeof (char));
1830      if (file == NULL)
1831	{
1832	  log_error ("keynote_cert_obtain: failed to allocate %d bytes",
1833		     len + strlen (addr_str));
1834	  free (addr_str);
1835	  return 0;
1836	}
1837
1838      sprintf (file, "%s/%s/%s", dirname, addr_str, CREDENTIAL_FILE);
1839      free (addr_str);
1840      break;
1841
1842    case IPSEC_ID_FQDN:
1843    case IPSEC_ID_USER_FQDN:
1844      {
1845        file = calloc (len + id_len, sizeof (char));
1846	if (file == NULL)
1847	  {
1848	    log_error ("keynote_cert_obtain: failed to allocate %d bytes",
1849		       len + id_len);
1850	    return 0;
1851	  }
1852
1853	sprintf (file, "%s/", dirname);
1854	memcpy (file + strlen (file), id, id_len);
1855	sprintf (file + strlen (dirname) + 1 + id_len, "/%s", CREDENTIAL_FILE);
1856	break;
1857      }
1858
1859    default:
1860      return 0;
1861    }
1862
1863  if (stat (file, &sb) < 0)
1864    {
1865      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to stat \"%s\"",
1866		file));
1867      free (file);
1868      return 0;
1869    }
1870
1871  *cert = calloc (sb.st_size, sizeof (char));
1872  if (*cert == NULL)
1873    {
1874      log_error ("keynote_cert_obtain: failed to allocate %d bytes",
1875		 sb.st_size);
1876      free (file);
1877      return 0;
1878    }
1879
1880  fd = open (file, O_RDONLY, 0);
1881  if (fd < 0)
1882    {
1883      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to open \"%s\"",
1884		file));
1885      free (file);
1886      return 0;
1887    }
1888
1889  if (read (fd, *cert, sb.st_size) != sb.st_size)
1890    {
1891      LOG_DBG ((LOG_POLICY, 30, "keynote_cert_obtain: failed to read %d "
1892		"bytes from \"%s\"", sb.st_size, file));
1893      free (file);
1894      close (fd);
1895      return 0;
1896    }
1897
1898  close (fd);
1899  free (file);
1900  *certlen = sb.st_size;
1901  return 1;
1902}
1903
1904/* This should never be called.  */
1905int
1906keynote_cert_get_subjects (void *scert, int *n, u_int8_t ***id,
1907			   u_int32_t **id_len)
1908{
1909  return 0;
1910}
1911
1912/* Get the authorizer key.  */
1913int
1914keynote_cert_get_key (void *scert, void *keyp)
1915{
1916  struct keynote_keylist *kl;
1917  int sid, kid, num;
1918  char **foo;
1919
1920  foo = LK (kn_read_asserts, ((char *)scert, strlen ((char *)scert), &num));
1921  if (foo == NULL || num == 0)
1922    {
1923      log_print ("keynote_cert_get_key: failed to decompose credentials");
1924      return 0;
1925    }
1926
1927  kid = LK (kn_init, ());
1928  if (kid == -1)
1929    {
1930      log_print ("keynote_cert_get_key: failed to initialize new policy "
1931		 "session");
1932      while (num--)
1933	free (foo[num]);
1934      free (foo);
1935      return 0;
1936    }
1937
1938  sid = LK (kn_add_assertion, (kid, foo[num - 1],
1939			       strlen (foo[num - 1]), 0));
1940  while (num--)
1941    free (foo[num]);
1942  free (foo);
1943
1944  if (sid == -1)
1945    {
1946      log_print ("keynote_cert_get_key: failed to add assertion");
1947      LK (kn_close, (kid));
1948      return 0;
1949    }
1950
1951  *(RSA **)keyp = NULL;
1952
1953  kl = LK (kn_get_licensees, (kid, sid));
1954  while (kl)
1955    {
1956      if (kl->key_alg == KEYNOTE_ALGORITHM_RSA)
1957	{
1958	  *(RSA **)keyp = LC (RSAPublicKey_dup, (kl->key_key));
1959	  break;
1960	}
1961
1962      kl = kl->key_next;
1963    }
1964
1965  LK (kn_remove_assertion, (kid, sid));
1966  LK (kn_close, (kid));
1967  return *(RSA **)keyp == NULL ? 0 : 1;
1968}
1969
1970void *
1971keynote_cert_dup (void *cert)
1972{
1973  return strdup((char *)cert);
1974}
1975
1976void
1977keynote_serialize (void *cert, u_int8_t **data, u_int32_t *datalen)
1978{
1979  *datalen = strlen ((char *)cert) + 1;
1980  *data = strdup (cert); /* So we allocate an extra character at the end... */
1981  if (*data == NULL)
1982    log_error ("keynote_serialize: malloc (%d) failed", *datalen);
1983}
1984
1985/* From cert to printable */
1986char *
1987keynote_printable (void *cert)
1988{
1989  return strdup ((char *)cert);
1990}
1991
1992/* From printable to cert */
1993void *
1994keynote_from_printable (char *cert)
1995{
1996  return strdup (cert);
1997}
1998