xref: /openbsd/sbin/isakmpd/ike_phase_1.c (revision 133306f0)
1 /*	$OpenBSD: ike_phase_1.c,v 1.21 2000/12/12 01:45:45 niklas Exp $	*/
2 /*	$EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $	*/
3 
4 /*
5  * Copyright (c) 1999, 2000 Niklas Hallqvist.  All rights reserved.
6  * Copyright (c) 1999, 2000 Angelos D. Keromytis.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by Ericsson Radio Systems.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * This code was written under funding by Ericsson Radio Systems.
36  */
37 
38 #include <sys/types.h>
39 #include <netinet/in.h>
40 #include <stdlib.h>
41 #include <string.h>
42 
43 #include "sysdep.h"
44 
45 #include "attribute.h"
46 #include "conf.h"
47 #include "constants.h"
48 #include "crypto.h"
49 #include "dh.h"
50 #include "doi.h"
51 #include "exchange.h"
52 #include "hash.h"
53 #include "ike_auth.h"
54 #include "ike_phase_1.h"
55 #include "ipsec.h"
56 #include "ipsec_doi.h"
57 #include "isakmp.h"
58 #include "log.h"
59 #include "math_group.h"
60 #include "message.h"
61 #include "prf.h"
62 #include "sa.h"
63 #include "transport.h"
64 #include "util.h"
65 
66 static int attribute_unacceptable (u_int16_t, u_int8_t *, u_int16_t, void *);
67 static int ike_phase_1_validate_prop (struct exchange *, struct sa *,
68 				      struct sa *);
69 
70 /* Offer a set of transforms to the responder in the MSG message.  */
71 int
72 ike_phase_1_initiator_send_SA (struct message *msg)
73 {
74   struct exchange *exchange = msg->exchange;
75   struct ipsec_exch *ie = exchange->data;
76   u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr;
77   u_int8_t **transform = 0;
78   size_t transforms_len = 0, proposal_len, sa_len;
79   size_t *transform_len = 0;
80   struct conf_list *conf, *life_conf;
81   struct conf_list_node *xf, *life;
82   int i, value, update_nextp;
83   struct payload *p;
84   struct proto *proto;
85   int group_desc = -1, new_group_desc;
86 
87   /* Get the list of transforms.  */
88   conf = conf_get_list (exchange->policy, "Transforms");
89   if (!conf)
90     return -1;
91 
92   transform = calloc (conf->cnt, sizeof *transform);
93   if (!transform)
94     {
95       log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %d) failed",
96 		 conf->cnt, sizeof *transform);
97       goto bail_out;
98     }
99 
100   transform_len = calloc (conf->cnt, sizeof *transform_len);
101   if (!transform_len)
102     {
103       log_error ("ike_phase_1_initiator_send_SA: calloc (%d, %d) failed",
104 		 conf->cnt, sizeof *transform_len);
105       goto bail_out;
106     }
107 
108   for (xf = TAILQ_FIRST (&conf->fields), i = 0; i < conf->cnt;
109        i++, xf = TAILQ_NEXT (xf, link))
110     {
111       /* XXX The sizing needs to be dynamic.  */
112       transform[i]
113 	= malloc (ISAKMP_TRANSFORM_SA_ATTRS_OFF + 16 * ISAKMP_ATTR_VALUE_OFF);
114       if (!transform[i])
115 	{
116 	  log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed",
117 		     ISAKMP_TRANSFORM_SA_ATTRS_OFF
118 		     + 16 * ISAKMP_ATTR_VALUE_OFF);
119 	  goto bail_out;
120 	}
121 
122       SET_ISAKMP_TRANSFORM_NO (transform[i], i);
123       SET_ISAKMP_TRANSFORM_ID (transform[i], IPSEC_TRANSFORM_KEY_IKE);
124       SET_ISAKMP_TRANSFORM_RESERVED (transform[i], 0);
125 
126       attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF;
127 
128       if (attribute_set_constant (xf->field, "ENCRYPTION_ALGORITHM",
129 				  ike_encrypt_cst,
130 				  IKE_ATTR_ENCRYPTION_ALGORITHM, &attr))
131 	goto bail_out;
132 
133       if (attribute_set_constant (xf->field, "HASH_ALGORITHM", ike_hash_cst,
134 				  IKE_ATTR_HASH_ALGORITHM, &attr))
135 	goto bail_out;
136 
137       if (attribute_set_constant (xf->field, "AUTHENTICATION_METHOD",
138 				  ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD,
139 				  &attr))
140 	goto bail_out;
141 
142       if (attribute_set_constant (xf->field, "GROUP_DESCRIPTION",
143 				  ike_group_desc_cst,
144 				  IKE_ATTR_GROUP_DESCRIPTION, &attr))
145 	{
146 	  /*
147 	   * If no group description exists, try looking for a user-defined
148 	   * one.
149 	   */
150 	  if (attribute_set_constant (xf->field, "GROUP_TYPE", ike_group_cst,
151 				      IKE_ATTR_GROUP_TYPE, &attr))
152 	    goto bail_out;
153 
154 #if 0
155 	  if (attribute_set_bignum (xf->field, "GROUP_PRIME",
156 				    IKE_ATTR_GROUP_PRIME, &attr))
157 	    goto bail_out;
158 
159 	  if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2",
160 				    IKE_ATTR_GROUP_GENERATOR_2, &attr))
161 	    goto bail_out;
162 
163 	  if (attribute_set_bignum (xf->field, "GROUP_GENERATOR_2",
164 				    IKE_ATTR_GROUP_GENERATOR_2, &attr))
165 	    goto bail_out;
166 
167 	  if (attribute_set_bignum (xf->field, "GROUP_CURVE_A",
168 				    IKE_ATTR_GROUP_CURVE_A, &attr))
169 	    goto bail_out;
170 
171 	  if (attribute_set_bignum (xf->field, "GROUP_CURVE_B",
172 				    IKE_ATTR_GROUP_CURVE_B, &attr))
173 	    goto bail_out;
174 #endif
175 	}
176 
177       /*
178        * Life durations are special, we should be able to specify
179        * several, one per type.
180        */
181       life_conf = conf_get_list (xf->field, "Life");
182       if (life_conf)
183 	{
184 	  for (life = TAILQ_FIRST (&life_conf->fields); life;
185 	       life = TAILQ_NEXT (life, link))
186 	    {
187 	      attribute_set_constant (life->field, "LIFE_TYPE",
188 				      ike_duration_cst, IKE_ATTR_LIFE_TYPE,
189 				      &attr);
190 
191               /* XXX Deals with 16 and 32 bit lifetimes only */
192 	      value = conf_get_num (life->field, "LIFE_DURATION", 0);
193               if (value)
194                 {
195 	          if (value <= 0xffff)
196 		    attr = attribute_set_basic (attr, IKE_ATTR_LIFE_DURATION,
197 						value);
198                   else
199                     {
200                       value = htonl (value);
201 		      attr = attribute_set_var (attr, IKE_ATTR_LIFE_DURATION,
202                                                 (char *)&value, sizeof value);
203                     }
204                 }
205 	    }
206 	  conf_free_list (life_conf);
207 	}
208 
209       attribute_set_constant (xf->field, "PRF", ike_prf_cst, IKE_ATTR_PRF,
210 			      &attr);
211 
212       value = conf_get_num (xf->field, "KEY_LENGTH", 0);
213       if (value)
214 	attr = attribute_set_basic (attr, IKE_ATTR_KEY_LENGTH, value);
215 
216       value = conf_get_num (xf->field, "FIELD_SIZE", 0);
217       if (value)
218 	attr = attribute_set_basic (attr, IKE_ATTR_FIELD_SIZE, value);
219 
220       value = conf_get_num (xf->field, "GROUP_ORDER", 0);
221       if (value)
222 	attr = attribute_set_basic (attr, IKE_ATTR_GROUP_ORDER, value);
223 
224       /* Record the real transform size.  */
225       transforms_len += transform_len[i] = attr - transform[i];
226 
227       /* XXX I don't like exchange-specific stuff in here.  */
228       if (exchange->type == ISAKMP_EXCH_AGGRESSIVE)
229 	{
230 	  /*
231 	   * Make sure that if a group description is specified, it is
232 	   * specified for all transforms equally.
233 	   */
234 	  attr = conf_get_str (xf->field, "GROUP_DESCRIPTION");
235 	  new_group_desc
236 	    = attr ? constant_value (ike_group_desc_cst, attr) : 0;
237 	  if (group_desc == -1)
238 	    group_desc = new_group_desc;
239 	  else if (group_desc != new_group_desc)
240 	    {
241 	      log_print ("ike_phase_1_inititor_send_SA: "
242 			 "differing group descriptions in a proposal");
243 	      goto bail_out;
244 	    }
245 	}
246 
247       /* We need to check that we actually support our configuration.  */
248       if (attribute_map (transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
249 			 transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
250 			 exchange->doi->is_attribute_incompatible, msg))
251 	{
252 	  log_print ("ike_phase_1_initiator_send_SA: "
253 		     "section [%s] has unsupported attribute(s)",
254 		     xf->field);
255 	  goto bail_out;
256 	}
257     }
258 
259   /* XXX I don't like exchange-specific stuff in here.  */
260   if (exchange->type == ISAKMP_EXCH_AGGRESSIVE)
261     ie->group = group_get (group_desc);
262 
263   proposal_len = ISAKMP_PROP_SPI_OFF;
264   proposal = malloc (proposal_len);
265   if (!proposal)
266     {
267       log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed",
268 		 proposal_len);
269       goto bail_out;
270     }
271 
272   SET_ISAKMP_PROP_NO (proposal, 1);
273   SET_ISAKMP_PROP_PROTO (proposal, ISAKMP_PROTO_ISAKMP);
274   SET_ISAKMP_PROP_SPI_SZ (proposal, 0);
275   SET_ISAKMP_PROP_NTRANSFORMS (proposal, conf->cnt);
276 
277   /* XXX I would like to see this factored out.  */
278   proto = calloc (1, sizeof *proto);
279   if (!proto)
280     {
281       log_error ("ike_phase_1_initiator_send_SA: calloc (1, %d) failed",
282 		 sizeof *proto);
283       goto bail_out;
284     }
285 
286   proto->no = 1;
287   proto->proto = ISAKMP_PROTO_ISAKMP;
288   proto->sa = TAILQ_FIRST (&exchange->sa_list);
289   TAILQ_INSERT_TAIL (&TAILQ_FIRST (&exchange->sa_list)->protos, proto,
290 		     link);
291 
292   sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN;
293   sa_buf = malloc (sa_len);
294   if (!sa_buf)
295     {
296       log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed", sa_len);
297       goto bail_out;
298     }
299 
300   SET_ISAKMP_SA_DOI (sa_buf, IPSEC_DOI_IPSEC);
301   SET_IPSEC_SIT_SIT (sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY);
302 
303   /*
304    * Add the payloads.  As this is a SA, we need to recompute the
305    * lengths of the payloads containing others.
306    */
307   if (message_add_payload (msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1))
308     goto bail_out;
309   SET_ISAKMP_GEN_LENGTH (sa_buf,
310 			 sa_len + proposal_len + transforms_len);
311   sa_buf = 0;
312 
313   saved_nextp = msg->nextp;
314   if (message_add_payload (msg, ISAKMP_PAYLOAD_PROPOSAL, proposal,
315 			   proposal_len, 0))
316     goto bail_out;
317   SET_ISAKMP_GEN_LENGTH (proposal, proposal_len + transforms_len);
318   proposal = 0;
319 
320   update_nextp = 0;
321   for (i = 0; i < conf->cnt; i++)
322     {
323       if (message_add_payload (msg, ISAKMP_PAYLOAD_TRANSFORM, transform[i],
324 			       transform_len[i], update_nextp))
325 	goto bail_out;
326       update_nextp = 1;
327       transform[i] = 0;
328     }
329   msg->nextp = saved_nextp;
330 
331   /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len.  */
332   ie->sa_i_b_len = sa_len + proposal_len + transforms_len - ISAKMP_GEN_SZ;
333   ie->sa_i_b = malloc (ie->sa_i_b_len);
334   if (!ie->sa_i_b)
335     {
336       log_error ("ike_phase_1_initiator_send_SA: malloc (%d) failed",
337 		 ie->sa_i_b_len);
338       goto bail_out;
339     }
340   memcpy (ie->sa_i_b,
341 	  TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA])->p + ISAKMP_GEN_SZ,
342 	  sa_len - ISAKMP_GEN_SZ);
343   memcpy (ie->sa_i_b + sa_len - ISAKMP_GEN_SZ,
344 	  TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL])->p,
345 	  proposal_len);
346   transforms_len = 0;
347   for (i = 0, p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
348        i < conf->cnt; i++, p = TAILQ_NEXT (p, link))
349     {
350       memcpy (ie->sa_i_b + sa_len + proposal_len + transforms_len
351 	      - ISAKMP_GEN_SZ,
352 	      p->p, transform_len[i]);
353       transforms_len += transform_len[i];
354     }
355 
356   conf_free_list (conf);
357   free (transform);
358   free (transform_len);
359   return 0;
360 
361  bail_out:
362   if (sa_buf)
363     free (sa_buf);
364   if (proposal)
365     free (proposal);
366   if (transform)
367     {
368       for (i = 0; i < conf->cnt; i++)
369 	if (transform[i])
370 	  free (transform[i]);
371       free (transform);
372     }
373   if (transform_len)
374     free (transform_len);
375   conf_free_list (conf);
376   return -1;
377 }
378 
379 /* Figure out what transform the responder chose.  */
380 int
381 ike_phase_1_initiator_recv_SA (struct message *msg)
382 {
383   struct exchange *exchange = msg->exchange;
384   struct sa *sa = TAILQ_FIRST (&exchange->sa_list);
385   struct ipsec_exch *ie = exchange->data;
386   struct ipsec_sa *isa = sa->data;
387   struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]);
388   struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
389   struct payload *xf = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_TRANSFORM]);
390 
391   /*
392    * IKE requires that only one SA with only one proposal exists and since
393    * we are getting an answer on our transform offer, only one transform.
394    */
395   if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link)
396       || TAILQ_NEXT (xf, link))
397     {
398       log_print ("ike_phase_1_initiator_recv_SA: "
399 		 "multiple SA, proposal or transform payloads in phase 1");
400       /* XXX Is there a better notification type?  */
401       message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
402       return -1;
403     }
404 
405   /* Check that the chosen transform matches an offer.  */
406   if (message_negotiate_sa (msg, ike_phase_1_validate_prop)
407       || !TAILQ_FIRST (&sa->protos))
408     return -1;
409 
410   ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos), xf->p);
411 
412   /* XXX I don't like exchange-specific stuff in here.  */
413   if (exchange->type != ISAKMP_EXCH_AGGRESSIVE)
414     ie->group = group_get (isa->group_desc);
415 
416   /* Mark the SA as handled.  */
417   sa_p->flags |= PL_MARK;
418 
419   return 0;
420 }
421 
422 /* Send our public DH value and a nonce to the responder.  */
423 int
424 ike_phase_1_initiator_send_KE_NONCE (struct message *msg)
425 {
426   struct ipsec_exch *ie = msg->exchange->data;
427 
428   ie->g_x_len = dh_getlen (ie->group);
429 
430   /* XXX I want a better way to specify the nonce's size.  */
431   return ike_phase_1_send_KE_NONCE (msg, 16);
432 }
433 
434 /* Accept responder's public DH value and nonce.  */
435 int
436 ike_phase_1_initiator_recv_KE_NONCE (struct message *msg)
437 {
438   if (ike_phase_1_recv_KE_NONCE (msg))
439     return -1;
440 
441   return ike_phase_1_post_exchange_KE_NONCE (msg);
442 }
443 
444 /*
445  * Accept a set of transforms offered by the initiator and chose one we can
446  * handle.
447  */
448 int
449 ike_phase_1_responder_recv_SA (struct message *msg)
450 {
451   struct exchange *exchange = msg->exchange;
452   struct sa *sa = TAILQ_FIRST (&exchange->sa_list);
453   struct ipsec_sa *isa = sa->data;
454   struct payload *sa_p = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_SA]);
455   struct payload *prop = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_PROPOSAL]);
456   struct ipsec_exch *ie = exchange->data;
457 
458   /* Mark the SA as handled.  */
459   sa_p->flags |= PL_MARK;
460 
461   /* IKE requires that only one SA with only one proposal exists.  */
462   if (TAILQ_NEXT (sa_p, link) || TAILQ_NEXT (prop, link))
463     {
464       log_print ("ike_phase_1_responder_recv_SA: "
465 		 "multiple SA or proposal payloads in phase 1");
466       /* XXX Is there a better notification type?  */
467       message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
468       return -1;
469     }
470 
471   /* Chose a transform from the SA.  */
472   if (message_negotiate_sa (msg, ike_phase_1_validate_prop)
473       || !TAILQ_FIRST (&sa->protos))
474     return -1;
475 
476   /* XXX Move into message_negotiate_sa?  */
477   ipsec_decode_transform (msg, sa, TAILQ_FIRST (&sa->protos),
478 			  TAILQ_FIRST (&sa->protos)->chosen->p);
479 
480   ie->group = group_get (isa->group_desc);
481 
482   /*
483    * Check that the mandatory attributes: encryption, hash, authentication
484    * method and Diffie-Hellman group description, has been supplied.
485    */
486   if (!exchange->crypto || !ie->hash || !ie->ike_auth || !ie->group)
487     {
488       message_drop (msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0);
489       return -1;
490     }
491 
492   /* Save the body for later hash computation.  */
493   ie->sa_i_b_len = GET_ISAKMP_GEN_LENGTH (sa_p->p) - ISAKMP_GEN_SZ;
494   ie->sa_i_b = malloc (ie->sa_i_b_len);
495   if (!ie->sa_i_b)
496     {
497       /* XXX How to notify peer?  */
498       log_error ("ike_phase_1_responder_recv_SA: malloc (%d) failed",
499 		 ie->sa_i_b_len);
500       return -1;
501     }
502   memcpy (ie->sa_i_b, sa_p->p + ISAKMP_GEN_SZ, ie->sa_i_b_len);
503 
504   return 0;
505 }
506 
507 /* Reply with the transform we chose.  */
508 int
509 ike_phase_1_responder_send_SA (struct message *msg)
510 {
511   /* Add the SA payload with the transform that was chosen.  */
512   return message_add_sa_payload (msg);
513 }
514 
515 /* Send our public DH value and a nonce to the peer.  */
516 int
517 ike_phase_1_send_KE_NONCE (struct message *msg, size_t nonce_sz)
518 {
519   /* Public DH key.  */
520   if (ipsec_gen_g_x (msg))
521     {
522       /* XXX How to log and notify peer?  */
523       return -1;
524     }
525 
526   /* Generate a nonce, and add it to the message.  */
527   if (exchange_gen_nonce (msg, nonce_sz))
528     {
529       /* XXX Log?  */
530       return -1;
531     }
532 
533   /* Try to add certificates which are acceptable for the CERTREQs */
534   if (exchange_add_certs (msg))
535     {
536       /* XXX Log? */
537       return -1;
538     }
539 
540   return 0;
541 }
542 
543 /* Receive our peer's public DH value and nonce.  */
544 int
545 ike_phase_1_recv_KE_NONCE (struct message *msg)
546 {
547   /* Copy out the initiator's DH public value.  */
548   if (ipsec_save_g_x (msg))
549     {
550       /* XXX How to log and notify peer?  */
551       return -1;
552     }
553 
554   /* Copy out the initiator's nonce.  */
555   if (exchange_save_nonce (msg))
556     {
557       /* XXX How to log and notify peer?  */
558       return -1;
559     }
560 
561   /* Copy out the initiator's cert requests.  */
562   if (exchange_save_certreq (msg))
563     {
564       /* XXX How to log and notify peer?  */
565       return -1;
566     }
567 
568   return 0;
569 }
570 
571 /*
572  * Compute DH values and key material.  This is done in a post-send function
573  * as that means we can do parallel work in both the initiator and responder
574  * thus speeding up exchanges.
575  */
576 int
577 ike_phase_1_post_exchange_KE_NONCE (struct message *msg)
578 {
579   struct exchange *exchange = msg->exchange;
580   struct ipsec_exch *ie = exchange->data;
581   struct prf *prf;
582   struct hash *hash = ie->hash;
583   enum cryptoerr err;
584 
585   /* Compute Diffie-Hellman shared value.  */
586   ie->g_xy = malloc (ie->g_x_len);
587   if (!ie->g_xy)
588     {
589       /* XXX How to notify peer?  */
590       log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
591 		 ie->g_x_len);
592       return -1;
593     }
594   if (dh_create_shared (ie->group, ie->g_xy,
595 			exchange->initiator ? ie->g_xr : ie->g_xi))
596     {
597       log_print ("ike_phase_1_post_exchange_KE_NONCE: "
598 		 "dh_create_shared failed");
599       return -1;
600     }
601   LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: g^xy",
602 		ie->g_xy, ie->g_x_len));
603 
604   /* Compute the SKEYID depending on the authentication method.  */
605   ie->skeyid = ie->ike_auth->gen_skeyid (exchange, &ie->skeyid_len);
606   if (!ie->skeyid)
607     {
608       /* XXX Log and teardown?  */
609       return -1;
610     }
611   LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID",
612 		ie->skeyid, ie->skeyid_len));
613 
614   /* SKEYID_d.  */
615   ie->skeyid_d = malloc (ie->skeyid_len);
616   if (!ie->skeyid_d)
617     {
618       /* XXX How to notify peer?  */
619       log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
620 		 ie->skeyid_len);
621       return -1;
622     }
623   prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
624   if (!prf)
625     {
626       /* XXX Log and teardown?  */
627       return -1;
628     }
629   prf->Init (prf->prfctx);
630   prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
631   prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
632   prf->Update (prf->prfctx, "\0", 1);
633   prf->Final (ie->skeyid_d, prf->prfctx);
634   LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d",
635 		ie->skeyid_d, ie->skeyid_len));
636 
637   /* SKEYID_a.  */
638   ie->skeyid_a = malloc (ie->skeyid_len);
639   if (!ie->skeyid_a)
640     {
641       log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
642 		 ie->skeyid_len);
643       prf_free (prf);
644       return -1;
645     }
646   prf->Init (prf->prfctx);
647   prf->Update (prf->prfctx, ie->skeyid_d, ie->skeyid_len);
648   prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
649   prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
650   prf->Update (prf->prfctx, "\1", 1);
651   prf->Final (ie->skeyid_a, prf->prfctx);
652   LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a",
653 		ie->skeyid_a, ie->skeyid_len));
654 
655   /* SKEYID_e.  */
656   ie->skeyid_e = malloc (ie->skeyid_len);
657   if (!ie->skeyid_e)
658     {
659       /* XXX How to notify peer?  */
660       log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
661 		 ie->skeyid_len);
662       prf_free (prf);
663       return -1;
664     }
665   prf->Init (prf->prfctx);
666   prf->Update (prf->prfctx, ie->skeyid_a, ie->skeyid_len);
667   prf->Update (prf->prfctx, ie->g_xy, ie->g_x_len);
668   prf->Update (prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN);
669   prf->Update (prf->prfctx, "\2", 1);
670   prf->Final (ie->skeyid_e, prf->prfctx);
671   prf_free (prf);
672   LOG_DBG_BUF ((LOG_MISC, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e",
673 		ie->skeyid_e, ie->skeyid_len));
674 
675   /* Key length determination.  */
676   if (!exchange->key_length)
677     exchange->key_length = exchange->crypto->keymax;
678 
679   /* Derive a longer key from skeyid_e */
680   if (ie->skeyid_len < exchange->key_length)
681     {
682       u_int16_t len, keylen;
683       u_int8_t *key, *p;
684 
685       prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid_e, ie->skeyid_len);
686       if (!prf)
687 	{
688 	  /* XXX - notify peer */
689 	  return -1;
690 	}
691 
692       /* Make keylen a multiple of prf->blocksize */
693       keylen = exchange->key_length;
694       if (keylen % prf->blocksize)
695 	keylen += prf->blocksize - (keylen % prf->blocksize);
696 
697       key = malloc (keylen);
698       if (!key)
699 	{
700 	  /* XXX - Notify peer.  */
701 	  log_error ("ike_phase_1_post_exchange_KE_NONCE: malloc (%d) failed",
702 		     keylen);
703 	  return -1;
704 	}
705 
706       prf->Init (prf->prfctx);
707       prf->Update (prf->prfctx, "\0", 1);
708       prf->Final (key, prf->prfctx);
709 
710       for (len = prf->blocksize, p = key; len < exchange->key_length;
711 	   len += prf->blocksize, p += prf->blocksize)
712 	{
713 	  prf->Init (prf->prfctx);
714 	  prf->Update (prf->prfctx, p, prf->blocksize);
715 	  prf->Final (p + prf->blocksize, prf->prfctx);
716 	}
717       prf_free (prf);
718 
719       /* Setup our keystate using the derived encryption key.  */
720       exchange->keystate
721 	= crypto_init (exchange->crypto, key, exchange->key_length, &err);
722 
723       free (key);
724     }
725   else
726     /* Setup our keystate using the raw skeyid_e.  */
727     exchange->keystate = crypto_init (exchange->crypto, ie->skeyid_e,
728 				      exchange->key_length, &err);
729 
730   /* Special handling for DES weak keys.  */
731   if (!exchange->keystate && err == EWEAKKEY
732       && (exchange->key_length << 1) <= ie->skeyid_len)
733     {
734       log_print ("ike_phase_1_post_exchange_KE_NONCE: "
735 		 "weak key, trying subseq. skeyid_e");
736       exchange->keystate
737 	= crypto_init (exchange->crypto, ie->skeyid_e + exchange->key_length,
738 		       exchange->key_length, &err);
739     }
740 
741   if (!exchange->keystate)
742     {
743       log_print ("ike_phase_1_post_exchange_KE_NONCE: "
744 		 "exchange->crypto->init () failed: %d", err);
745 
746       /*
747        * XXX We really need to know if problems are of transient nature
748        * or fatal (like failed assertions etc.)
749        */
750       return -1;
751     }
752 
753   /* Setup IV.  XXX Only for CBC transforms, no?  */
754   hash->Init (hash->ctx);
755   hash->Update (hash->ctx, ie->g_xi, ie->g_x_len);
756   hash->Update (hash->ctx, ie->g_xr, ie->g_x_len);
757   hash->Final (hash->digest, hash->ctx);
758   crypto_init_iv (exchange->keystate, hash->digest,
759 		  exchange->crypto->blocksize);
760 
761   return 0;
762 }
763 
764 int
765 ike_phase_1_responder_send_ID_AUTH (struct message *msg)
766 {
767   if (ike_phase_1_send_ID (msg))
768     return -1;
769 
770   return ike_phase_1_send_AUTH (msg);
771 }
772 
773 int
774 ike_phase_1_send_ID (struct message *msg)
775 {
776   struct exchange *exchange = msg->exchange;
777   u_int8_t *buf;
778   char header[80];
779   ssize_t sz;
780   struct sockaddr *src;
781   int src_len;
782   int initiator = exchange->initiator;
783   u_int8_t **id;
784   size_t *id_len;
785   char *my_id = 0;
786   u_int8_t id_type;
787 
788   /* Choose the right fields to fill-in.  */
789   id = initiator ? &exchange->id_i : &exchange->id_r;
790   id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len;
791 
792   if (exchange->name)
793     my_id = conf_get_str (exchange->name, "ID");
794 
795   if (!my_id)
796     my_id = conf_get_str ("General", "Default-phase-1-ID");
797 
798   sz = my_id ? ipsec_id_size (my_id, &id_type) : sizeof (in_addr_t);
799   if (sz == -1)
800     return -1;
801 
802   sz += ISAKMP_ID_DATA_OFF;
803   buf = malloc (sz);
804   if (!buf)
805     {
806       log_error ("ike_phase_1_send_ID: malloc (%d) failed", sz);
807       return -1;
808     }
809 
810   SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
811   SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
812   if (my_id)
813     {
814       SET_ISAKMP_ID_TYPE (buf, id_type);
815       switch (id_type)
816 	{
817 	case IPSEC_ID_IPV4_ADDR:
818       	  msg->transport->vtbl->get_src (msg->transport, &src, &src_len);
819 
820       	  /* Already in network byteorder.  */
821       	  memcpy (buf + ISAKMP_ID_DATA_OFF,
822 	      	  &((struct sockaddr_in *)src)->sin_addr.s_addr,
823 	      	  sizeof (in_addr_t));
824 	  break;
825 	case IPSEC_ID_FQDN:
826 	case IPSEC_ID_USER_FQDN:
827 	  memcpy (buf + ISAKMP_ID_DATA_OFF, conf_get_str (my_id, "Name"),
828 		  sz - ISAKMP_ID_DATA_OFF);
829 	  break;
830 	default:
831 	  log_print ("ike_phase_1_send_ID: unsupported ID type %d", id_type);
832 	  free (buf);
833 	  return -1;
834 	}
835     }
836   else
837     {
838       msg->transport->vtbl->get_src (msg->transport, &src, &src_len);
839       /* XXX Assumes IPv4.  */
840       SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
841       /* Already in network byteorder.  */
842       memcpy (buf + ISAKMP_ID_DATA_OFF,
843 	      &((struct sockaddr_in *)src)->sin_addr.s_addr,
844 	      sizeof (in_addr_t));
845     }
846 
847   if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, buf, sz, 1))
848     {
849       free (buf);
850       return -1;
851     }
852   *id_len = sz - ISAKMP_GEN_SZ;
853   *id = malloc (*id_len);
854   if (!*id)
855     {
856       log_error ("ike_phase_1_send_ID: malloc (%d) failed", *id_len);
857       return -1;
858     }
859   memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len);
860   snprintf (header, 80, "ike_phase_1_send_ID: %s",
861 	    constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (buf)));
862   LOG_DBG_BUF ((LOG_MISC, 40, header, buf + ISAKMP_ID_DATA_OFF,
863 		sz - ISAKMP_ID_DATA_OFF));
864 
865   return 0;
866 }
867 
868 int
869 ike_phase_1_send_AUTH (struct message *msg)
870 {
871   struct exchange *exchange = msg->exchange;
872   struct ipsec_exch *ie = exchange->data;
873 
874   if (ie->ike_auth->encode_hash (msg))
875     {
876       /* XXX Log? */
877       return -1;
878     }
879 
880   /*
881    * XXX Many people say the COMMIT flag is just junk, especially in Phase 1.
882    */
883 #ifdef notyet
884   if ((exchange->flags & EXCHANGE_FLAG_COMMITTED) == 0)
885     exchange->flags |= EXCHANGE_FLAG_I_COMMITTED;
886 #endif
887 
888   return 0;
889 }
890 
891 /* Receive ID and HASH and check that the exchange has been consistent.  */
892 int
893 ike_phase_1_recv_ID_AUTH (struct message *msg)
894 {
895   if (ike_phase_1_recv_ID (msg))
896     return -1;
897 
898   return ike_phase_1_recv_AUTH (msg);
899 }
900 
901 /* Receive ID.  */
902 int
903 ike_phase_1_recv_ID (struct message *msg)
904 {
905   struct exchange *exchange = msg->exchange;
906   struct payload *payload;
907   char header[80];
908   int initiator = exchange->initiator;
909   u_int8_t **id;
910   size_t *id_len;
911 
912   /*
913    * XXX Here, we could be checking that the received ID matches what
914    * we expect it to be (if anything). That information is contained
915    * in the [[exchange->name]:Remote-ID] section.
916    */
917 
918   /* Choose the right fields to fill in */
919   id = initiator ? &exchange->id_r : &exchange->id_i;
920   id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len;
921 
922   /* XXX Do I really have to save the ID in the SA?  */
923   payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]);
924   *id_len = GET_ISAKMP_GEN_LENGTH (payload->p) - ISAKMP_GEN_SZ;
925   *id = malloc (*id_len);
926   if (!*id)
927     {
928       log_error ("ike_phase_1_recv_ID: malloc (%d) failed", *id_len);
929       return -1;
930     }
931   memcpy (*id, payload->p + ISAKMP_GEN_SZ, *id_len);
932   snprintf (header, 80, "ike_phase_1_recv_ID: %s",
933 	    constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (payload->p)));
934   LOG_DBG_BUF ((LOG_MISC, 40, header, payload->p + ISAKMP_ID_DATA_OFF,
935 		*id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF));
936   payload->flags |= PL_MARK;
937 
938   return 0;
939 }
940 
941 /* Receive HASH and check that the exchange has been consistent.  */
942 int
943 ike_phase_1_recv_AUTH (struct message *msg)
944 {
945   struct exchange *exchange = msg->exchange;
946   struct ipsec_exch *ie = exchange->data;
947   struct prf *prf;
948   struct hash *hash = ie->hash;
949   char header[80];
950   size_t hashsize = hash->hashsize;
951   int initiator = exchange->initiator;
952   u_int8_t **hash_p, *id;
953   size_t id_len;
954 
955   /* Choose the right fields to fill in */
956   hash_p = initiator ? &ie->hash_r : &ie->hash_i;
957   id = initiator ? exchange->id_r : exchange->id_i;
958   id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
959 
960   /* The decoded hash will be in ie->hash_r or ie->hash_i */
961   if (ie->ike_auth->decode_hash (msg))
962     {
963       message_drop (msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 0);
964       return -1;
965     }
966 
967   /* Allocate the prf and start calculating his HASH.  */
968   prf = prf_alloc (ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
969   if (!prf)
970     {
971       /* XXX Log?  */
972       return -1;
973     }
974   prf->Init (prf->prfctx);
975   prf->Update (prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
976   prf->Update (prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
977   prf->Update (prf->prfctx,
978 	       exchange->cookies
979 	       + (initiator ? ISAKMP_HDR_RCOOKIE_OFF : ISAKMP_HDR_ICOOKIE_OFF),
980 	       ISAKMP_HDR_ICOOKIE_LEN);
981   prf->Update (prf->prfctx,
982 	       exchange->cookies
983 	       + (initiator ? ISAKMP_HDR_ICOOKIE_OFF : ISAKMP_HDR_RCOOKIE_OFF),
984 	       ISAKMP_HDR_ICOOKIE_LEN);
985   prf->Update (prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
986   prf->Update (prf->prfctx, id, id_len);
987   prf->Final (hash->digest, prf->prfctx);
988   prf_free (prf);
989   snprintf (header, 80, "ike_phase_1_recv_AUTH: computed HASH_%c",
990 	    initiator ? 'R' : 'I');
991   LOG_DBG_BUF ((LOG_MISC, 80, header, hash->digest, hashsize));
992 
993   /* Check that the hash we got matches the one we computed.  */
994   if (memcmp (*hash_p, hash->digest, hashsize) != 0)
995     {
996       /* XXX Log?  */
997       return -1;
998     }
999 
1000   return 0;
1001 }
1002 
1003 struct attr_node {
1004   LIST_ENTRY (attr_node) link;
1005   u_int16_t type;
1006 };
1007 
1008 struct validation_state {
1009   struct conf_list_node *xf;
1010   LIST_HEAD (attr_head, attr_node) attrs;
1011   char *life;
1012 };
1013 
1014 /* Validate a proposal inside SA according to EXCHANGE's policy.  */
1015 static int
1016 ike_phase_1_validate_prop (struct exchange *exchange, struct sa *sa,
1017 			   struct sa *isakmp_sa)
1018 {
1019   struct conf_list *conf, *tags;
1020   struct conf_list_node *xf, *tag;
1021   struct proto *proto;
1022   struct validation_state vs;
1023   struct attr_node *node, *next_node;
1024 
1025   /* Get the list of transforms.  */
1026   conf = conf_get_list (exchange->policy, "Transforms");
1027   if (!conf)
1028     return 0;
1029 
1030   for (xf = TAILQ_FIRST (&conf->fields); xf; xf = TAILQ_NEXT (xf, link))
1031     {
1032       for (proto = TAILQ_FIRST (&sa->protos); proto;
1033 	   proto = TAILQ_NEXT (proto, link))
1034 	{
1035 	  /* Mark all attributes in our policy as unseen.  */
1036 	  LIST_INIT (&vs.attrs);
1037 	  vs.xf = xf;
1038 	  vs.life = 0;
1039 	  if (attribute_map (proto->chosen->p + ISAKMP_TRANSFORM_SA_ATTRS_OFF,
1040 			     GET_ISAKMP_GEN_LENGTH (proto->chosen->p)
1041 			     - ISAKMP_TRANSFORM_SA_ATTRS_OFF,
1042 			     attribute_unacceptable, &vs))
1043 	    goto try_next;
1044 
1045 	  /* Sweep over unseen tags in this section.  */
1046 	  tags = conf_get_tag_list (xf->field);
1047 	  if (tags)
1048 	    {
1049 	      for (tag = TAILQ_FIRST (&tags->fields); tag;
1050 		   tag = TAILQ_NEXT (tag, link))
1051 		/*
1052 		 * XXX Should we care about attributes we have, they do not
1053 		 * provide?
1054 		 */
1055 		for (node = LIST_FIRST (&vs.attrs); node;
1056 		     node = next_node)
1057 		  {
1058 		    next_node = LIST_NEXT (node, link);
1059 		    if (node->type
1060 			== constant_value (ike_attr_cst, tag->field))
1061 		      {
1062 			LIST_REMOVE (node, link);
1063 			free (node);
1064 		      }
1065 		  }
1066 	      conf_free_list (tags);
1067 	    }
1068 
1069 	  /* Are there leftover tags in this section?  */
1070 	  node = LIST_FIRST (&vs.attrs);
1071 	  if (node)
1072 	    goto try_next;
1073 	}
1074 
1075       /* All protocols were OK, we succeeded.  */
1076       LOG_DBG ((LOG_MISC, 20, "ike_phase_1_validate_prop: success"));
1077       conf_free_list (conf);
1078       if (vs.life)
1079 	free (vs.life);
1080       return 1;
1081 
1082     try_next:
1083       /* Are there leftover tags in this section?  */
1084       node = LIST_FIRST (&vs.attrs);
1085       while (node)
1086 	{
1087 	  LIST_REMOVE (node, link);
1088 	  free (node);
1089 	  node = LIST_FIRST (&vs.attrs);
1090 	}
1091       if (vs.life)
1092 	free (vs.life);
1093     }
1094 
1095   LOG_DBG ((LOG_MISC, 20, "ike_phase_1_validate_prop: failure"));
1096   conf_free_list (conf);
1097   return 0;
1098 }
1099 
1100 /*
1101  * Look at the attribute of type TYPE, located at VALUE for LEN bytes forward.
1102  * The VVS argument holds a validation state kept across invocations.
1103  * If the attribute is unacceptable to use, return non-zero, otherwise zero.
1104  */
1105 static int
1106 attribute_unacceptable (u_int16_t type, u_int8_t *value, u_int16_t len,
1107 			void *vvs)
1108 {
1109   struct validation_state *vs = vvs;
1110   struct conf_list *life_conf;
1111   struct conf_list_node *xf = vs->xf, *life;
1112   char *tag = constant_lookup (ike_attr_cst, type);
1113   char *str;
1114   struct constant_map *map;
1115   struct attr_node *node;
1116   int rv;
1117 
1118   if (!tag)
1119     {
1120       log_print ("attribute_unacceptable: attribute type %d not known", type);
1121       return 1;
1122     }
1123 
1124   switch (type)
1125     {
1126     case IKE_ATTR_ENCRYPTION_ALGORITHM:
1127     case IKE_ATTR_HASH_ALGORITHM:
1128     case IKE_ATTR_AUTHENTICATION_METHOD:
1129     case IKE_ATTR_GROUP_DESCRIPTION:
1130     case IKE_ATTR_GROUP_TYPE:
1131     case IKE_ATTR_PRF:
1132       str = conf_get_str (xf->field, tag);
1133       if (!str)
1134 	{
1135 	  /* This attribute does not exist in this policy.  */
1136 	  log_print ("attribute_unacceptable: attr %s does not exist in %s",
1137 		     tag, xf->field);
1138 	  return 1;
1139 	}
1140 
1141       map = constant_link_lookup (ike_attr_cst, type);
1142       if (!map)
1143 	return 1;
1144 
1145       if ((constant_value (map, str) == decode_16 (value)) ||
1146 	  (!strcmp (str, "ANY")))
1147 	{
1148 	  /* Mark this attribute as seen.  */
1149 	  node = malloc (sizeof *node);
1150 	  if (!node)
1151 	    {
1152 	      log_error ("attribute_unacceptable: malloc (%d) failed",
1153 			 sizeof *node);
1154 	      return 1;
1155 	    }
1156 	  node->type = type;
1157 	  LIST_INSERT_HEAD (&vs->attrs, node, link);
1158 	  return 0;
1159 	}
1160       log_print ("attribute_unacceptable: %s: got %s, expected %s",
1161 		 tag, constant_lookup (map, decode_16 (value)), str);
1162       return 1;
1163 
1164     case IKE_ATTR_GROUP_PRIME:
1165     case IKE_ATTR_GROUP_GENERATOR_1:
1166     case IKE_ATTR_GROUP_GENERATOR_2:
1167     case IKE_ATTR_GROUP_CURVE_A:
1168     case IKE_ATTR_GROUP_CURVE_B:
1169       /* XXX Bignums not handled yet.  */
1170       return 1;
1171 
1172     case IKE_ATTR_LIFE_TYPE:
1173     case IKE_ATTR_LIFE_DURATION:
1174       life_conf = conf_get_list (xf->field, "Life");
1175       if (life_conf && !strcmp (conf_get_str (xf->field, "Life"), "ANY"))
1176 	return 0;
1177 
1178       rv = 1;
1179       if (!life_conf)
1180 	{
1181 	  /* Life attributes given, but not in our policy.  */
1182 	  log_print ("attribute_unacceptable: "
1183 		     "received unexpected life attribute");
1184 	  return 1;
1185 	}
1186 
1187       /*
1188        * Each lifetime type must match, otherwise we turn the proposal down.
1189        * In order to do this we need to find the specific section of our
1190        * policy's "Life" list and match its duration
1191        */
1192       switch (type)
1193 	{
1194 	case IKE_ATTR_LIFE_TYPE:
1195 	  for (life = TAILQ_FIRST (&life_conf->fields); life;
1196 	       life = TAILQ_NEXT (life, link))
1197 	    {
1198 	      str = conf_get_str (life->field, "LIFE_TYPE");
1199 	      if (!str)
1200 		{
1201 		  log_print ("attribute_unacceptable: "
1202 			     "section [%s] has no LIFE_TYPE", life->field);
1203 		  continue;
1204 		}
1205 
1206 	      /*
1207 	       * If this is the type we are looking at, save a pointer
1208 	       * to this section in vs->life.
1209 	       */
1210 	      if (constant_value (ike_duration_cst, str) == decode_16 (value))
1211 		{
1212 		  vs->life = strdup (life->field);
1213 		  rv = 0;
1214 		  goto bail_out;
1215 		}
1216 	    }
1217 	  log_print ("attribute_unacceptable: unrecognized LIFE_TYPE %d",
1218 		     decode_16 (value));
1219 	  vs->life = 0;
1220 	  break;
1221 
1222 	case IKE_ATTR_LIFE_DURATION:
1223 	  if (!vs->life)
1224 	    {
1225 	      log_print ("attribute_unacceptable: "
1226 			 "LIFE_DURATION without LIFE_TYPE");
1227 	      rv = 1;
1228 	      goto bail_out;
1229 	    }
1230 
1231 	  if (!strcmp (conf_get_str (vs->life, "LIFE_DURATION"), "ANY"))
1232 	    rv = 0;
1233 	  else
1234 	    rv = !conf_match_num (vs->life, "LIFE_DURATION",
1235 				  len == 4 ? decode_32 (value) :
1236 				  decode_16 (value));
1237 	  free (vs->life);
1238 	  vs->life = 0;
1239 	  break;
1240 	}
1241 
1242     bail_out:
1243       conf_free_list (life_conf);
1244       return rv;
1245 
1246     case IKE_ATTR_KEY_LENGTH:
1247     case IKE_ATTR_FIELD_SIZE:
1248     case IKE_ATTR_GROUP_ORDER:
1249       if (conf_match_num (xf->field, tag, decode_16 (value)))
1250 	{
1251 	  /* Mark this attribute as seen.  */
1252 	  node = malloc (sizeof *node);
1253 	  if (!node)
1254 	    {
1255 	      log_error ("attribute_unacceptable: malloc (%d) failed",
1256 			 sizeof *node);
1257 	      return 1;
1258 	    }
1259 	  node->type = type;
1260 	  LIST_INSERT_HEAD (&vs->attrs, node, link);
1261 	  return 0;
1262 	}
1263       return 1;
1264     }
1265   return 1;
1266 }
1267