Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/proposal_substructure.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012-2020 Tobias Brunner
3: * Copyright (C) 2005-2010 Martin Willi
4: * Copyright (C) 2005 Jan Hutter
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include <stddef.h>
19:
20: #include "proposal_substructure.h"
21:
22: #include <encoding/payloads/encodings.h>
23: #include <encoding/payloads/transform_substructure.h>
24: #include <library.h>
25: #include <collections/linked_list.h>
26: #include <daemon.h>
27:
28: /**
29: * IKEv2 Value for a proposal payload.
30: */
31: #define PROPOSAL_TYPE_VALUE 2
32:
33: typedef struct private_proposal_substructure_t private_proposal_substructure_t;
34:
35: /**
36: * Private data of an proposal_substructure_t object.
37: */
38: struct private_proposal_substructure_t {
39:
40: /**
41: * Public proposal_substructure_t interface.
42: */
43: proposal_substructure_t public;
44:
45: /**
46: * Next payload type.
47: */
48: uint8_t next_payload;
49:
50: /**
51: * reserved byte
52: */
53: uint8_t reserved;
54:
55: /**
56: * Length of this payload.
57: */
58: uint16_t proposal_length;
59:
60: /**
61: * Proposal number.
62: */
63: uint8_t proposal_number;
64:
65: /**
66: * Protocol ID.
67: */
68: uint8_t protocol_id;
69:
70: /**
71: * SPI size of the following SPI.
72: */
73: uint8_t spi_size;
74:
75: /**
76: * Number of transforms.
77: */
78: uint8_t transforms_count;
79:
80: /**
81: * SPI is stored as chunk.
82: */
83: chunk_t spi;
84:
85: /**
86: * Transforms are stored in a linked_list_t.
87: */
88: linked_list_t *transforms;
89:
90: /**
91: * Type of this payload, PLV2_PROPOSAL_SUBSTRUCTURE or PLV1_PROPOSAL_SUBSTRUCTURE
92: */
93: payload_type_t type;
94: };
95:
96: /**
97: * Encoding rules for a IKEv1 Proposal substructure.
98: */
99: static encoding_rule_t encodings_v1[] = {
100: /* 1 Byte next payload type, stored in the field next_payload */
101: { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
102: /* 1 Reserved Byte */
103: { RESERVED_BYTE, offsetof(private_proposal_substructure_t, reserved) },
104: /* Length of the whole proposal substructure payload*/
105: { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
106: /* proposal number is a number of 8 bit */
107: { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
108: /* protocol ID is a number of 8 bit */
109: { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
110: /* SPI Size has its own type */
111: { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
112: /* Number of transforms is a number of 8 bit */
113: { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
114: /* SPI is a chunk of variable size*/
115: { SPI, offsetof(private_proposal_substructure_t, spi) },
116: /* Transforms are stored in a transform substructure list */
117: { PAYLOAD_LIST + PLV1_TRANSFORM_SUBSTRUCTURE,
118: offsetof(private_proposal_substructure_t, transforms) },
119: };
120:
121: /**
122: * Encoding rules for a IKEv2 Proposal substructure.
123: */
124: static encoding_rule_t encodings_v2[] = {
125: /* 1 Byte next payload type, stored in the field next_payload */
126: { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
127: /* 1 Reserved Byte */
128: { RESERVED_BYTE, offsetof(private_proposal_substructure_t, reserved) },
129: /* Length of the whole proposal substructure payload*/
130: { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
131: /* proposal number is a number of 8 bit */
132: { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
133: /* protocol ID is a number of 8 bit */
134: { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
135: /* SPI Size has its own type */
136: { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
137: /* Number of transforms is a number of 8 bit */
138: { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
139: /* SPI is a chunk of variable size*/
140: { SPI, offsetof(private_proposal_substructure_t, spi) },
141: /* Transforms are stored in a transform substructure list */
142: { PAYLOAD_LIST + PLV2_TRANSFORM_SUBSTRUCTURE,
143: offsetof(private_proposal_substructure_t, transforms) },
144: };
145:
146: /*
147: 1 2 3
148: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
149: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150: ! 0 (last) or 2 ! RESERVED ! Proposal Length !
151: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152: ! Proposal # ! Protocol ID ! SPI Size !# of Transforms!
153: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154: ~ SPI (variable) ~
155: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156: ! !
157: ~ <Transforms> ~
158: ! !
159: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160: */
161:
162: /**
163: * Encryption.
164: */
165: typedef enum {
166: IKEV1_ENCR_DES_CBC = 1,
167: IKEV1_ENCR_IDEA_CBC = 2,
168: IKEV1_ENCR_BLOWFISH_CBC = 3,
169: IKEV1_ENCR_RC5_R16_B64_CBC = 4,
170: IKEV1_ENCR_3DES_CBC = 5,
171: IKEV1_ENCR_CAST_CBC = 6,
172: IKEV1_ENCR_AES_CBC = 7,
173: IKEV1_ENCR_CAMELLIA_CBC = 8,
174: /* FreeS/WAN proprietary */
175: IKEV1_ENCR_SERPENT_CBC = 65004,
176: IKEV1_ENCR_TWOFISH_CBC = 65005,
177: } ikev1_encryption_t;
178:
179: /**
180: * IKEv1 hash.
181: */
182: typedef enum {
183: IKEV1_HASH_MD5 = 1,
184: IKEV1_HASH_SHA1 = 2,
185: IKEV1_HASH_TIGER = 3,
186: IKEV1_HASH_SHA2_256 = 4,
187: IKEV1_HASH_SHA2_384 = 5,
188: IKEV1_HASH_SHA2_512 = 6,
189: } ikev1_hash_t;
190:
191: /**
192: * IKEv1 Transform ID IKE.
193: */
194: typedef enum {
195: IKEV1_TRANSID_KEY_IKE = 1,
196: } ikev1_ike_transid_t;
197:
198: /**
199: * IKEv1 Transform ID ESP encryption algorithm.
200: */
201: typedef enum {
202: IKEV1_ESP_ENCR_DES_IV64 = 1,
203: IKEV1_ESP_ENCR_DES = 2,
204: IKEV1_ESP_ENCR_3DES = 3,
205: IKEV1_ESP_ENCR_RC5 = 4,
206: IKEV1_ESP_ENCR_IDEA = 5,
207: IKEV1_ESP_ENCR_CAST = 6,
208: IKEV1_ESP_ENCR_BLOWFISH = 7,
209: IKEV1_ESP_ENCR_3IDEA = 8,
210: IKEV1_ESP_ENCR_DES_IV32 = 9,
211: IKEV1_ESP_ENCR_RC4 = 10,
212: IKEV1_ESP_ENCR_NULL = 11,
213: IKEV1_ESP_ENCR_AES_CBC = 12,
214: IKEV1_ESP_ENCR_AES_CTR = 13,
215: IKEV1_ESP_ENCR_AES_CCM_8 = 14,
216: IKEV1_ESP_ENCR_AES_CCM_12 = 15,
217: IKEV1_ESP_ENCR_AES_CCM_16 = 16,
218: IKEV1_ESP_ENCR_AES_GCM_8 = 18,
219: IKEV1_ESP_ENCR_AES_GCM_12 = 19,
220: IKEV1_ESP_ENCR_AES_GCM_16 = 20,
221: IKEV1_ESP_ENCR_SEED_CBC = 21,
222: IKEV1_ESP_ENCR_CAMELLIA = 22,
223: IKEV1_ESP_ENCR_NULL_AUTH_AES_GMAC = 23,
224: /* FreeS/WAN proprietary */
225: IKEV1_ESP_ENCR_SERPENT = 252,
226: IKEV1_ESP_ENCR_TWOFISH = 253,
227: } ikev1_esp_transid_t;
228:
229: /**
230: * IKEv1 Transform ID AH authentication algorithm.
231: */
232: typedef enum {
233: IKEV1_AH_HMAC_MD5 = 2,
234: IKEV1_AH_HMAC_SHA = 3,
235: IKEV1_AH_DES_MAC = 4,
236: IKEV1_AH_HMAC_SHA2_256 = 5,
237: IKEV1_AH_HMAC_SHA2_384 = 6,
238: IKEV1_AH_HMAC_SHA2_512 = 7,
239: IKEV1_AH_RIPEMD = 8,
240: IKEV1_AH_AES_XCBC_MAC = 9,
241: IKEV1_AH_RSA = 10,
242: IKEV1_AH_AES_128_GMAC = 11,
243: IKEV1_AH_AES_192_GMAC = 12,
244: IKEV1_AH_AES_256_GMAC = 13,
245: } ikev1_ah_transid_t;
246:
247: /**
248: * IKEv1 authentication algorithm.
249: */
250: typedef enum {
251: IKEV1_AUTH_HMAC_MD5 = 1,
252: IKEV1_AUTH_HMAC_SHA = 2,
253: IKEV1_AUTH_DES_MAC = 3,
254: IKEV1_AUTH_KPDK = 4,
255: IKEV1_AUTH_HMAC_SHA2_256 = 5,
256: IKEV1_AUTH_HMAC_SHA2_384 = 6,
257: IKEV1_AUTH_HMAC_SHA2_512 = 7,
258: IKEV1_AUTH_HMAC_RIPEMD = 8,
259: IKEV1_AUTH_AES_XCBC_MAC = 9,
260: IKEV1_AUTH_SIG_RSA = 10,
261: IKEV1_AUTH_AES_128_GMAC = 11,
262: IKEV1_AUTH_AES_192_GMAC = 12,
263: IKEV1_AUTH_AES_256_GMAC = 13,
264: } ikev1_auth_algo_t;
265:
266: /**
267: * IKEv1 ESP Encapsulation mode.
268: */
269: typedef enum {
270: IKEV1_ENCAP_TUNNEL = 1,
271: IKEV1_ENCAP_TRANSPORT = 2,
272: IKEV1_ENCAP_UDP_TUNNEL = 3,
273: IKEV1_ENCAP_UDP_TRANSPORT = 4,
274: IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03 = 61443,
275: IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03 = 61444,
276: } ikev1_esp_encap_t;
277:
278: /**
279: * IKEv1 Life duration types.
280: */
281: typedef enum {
282: IKEV1_LIFE_TYPE_SECONDS = 1,
283: IKEV1_LIFE_TYPE_KILOBYTES = 2,
284: } ikev1_life_type_t;
285:
286: /**
287: * IKEv1 authentication methods
288: */
289: typedef enum {
290: IKEV1_AUTH_PSK = 1,
291: IKEV1_AUTH_DSS_SIG = 2,
292: IKEV1_AUTH_RSA_SIG = 3,
293: IKEV1_AUTH_RSA_ENC = 4,
294: IKEV1_AUTH_RSA_ENC_REV = 5,
295: IKEV1_AUTH_ECDSA_256 = 9,
296: IKEV1_AUTH_ECDSA_384 = 10,
297: IKEV1_AUTH_ECDSA_521 = 11,
298: /* XAuth Modes */
299: IKEV1_AUTH_XAUTH_INIT_PSK = 65001,
300: IKEV1_AUTH_XAUTH_RESP_PSK = 65002,
301: IKEV1_AUTH_XAUTH_INIT_DSS = 65003,
302: IKEV1_AUTH_XAUTH_RESP_DSS = 65004,
303: IKEV1_AUTH_XAUTH_INIT_RSA = 65005,
304: IKEV1_AUTH_XAUTH_RESP_RSA = 65006,
305: IKEV1_AUTH_XAUTH_INIT_RSA_ENC = 65007,
306: IKEV1_AUTH_XAUTH_RESP_RSA_ENC = 65008,
307: IKEV1_AUTH_XAUTH_INIT_RSA_ENC_REV = 65009,
308: IKEV1_AUTH_XAUTH_RESP_RSA_ENC_REV = 65010,
309: /* Hybrid Modes */
310: IKEV1_AUTH_HYBRID_INIT_RSA = 64221,
311: IKEV1_AUTH_HYBRID_RESP_RSA = 64222,
312: IKEV1_AUTH_HYBRID_INIT_DSS = 64223,
313: IKEV1_AUTH_HYBRID_RESP_DSS = 64224,
314: } ikev1_auth_method_t;
315:
316: /**
317: * IKEv1 IPComp transform IDs
318: */
319: typedef enum {
320: IKEV1_IPCOMP_OUI = 1,
321: IKEV1_IPCOMP_DEFLATE = 2,
322: IKEV1_IPCOMP_LZS = 3,
323: } ikev1_ipcomp_transform_t;
324:
325: METHOD(payload_t, verify, status_t,
326: private_proposal_substructure_t *this)
327: {
328: status_t status = SUCCESS;
329: enumerator_t *enumerator;
330: payload_t *current;
331:
332: if (this->next_payload != PL_NONE && this->next_payload != 2)
333: {
334: /* must be 0 or 2 */
335: DBG1(DBG_ENC, "inconsistent next payload");
336: return FAILED;
337: }
338: if (this->transforms_count != this->transforms->get_count(this->transforms))
339: {
340: /* must be the same! */
341: DBG1(DBG_ENC, "transform count invalid");
342: return FAILED;
343: }
344:
345: switch (this->protocol_id)
346: {
347: case PROTO_IPCOMP:
348: if (this->spi.len != 2 && this->spi.len != 4)
349: {
350: DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal");
351: return FAILED;
352: }
353: break;
354: case PROTO_AH:
355: case PROTO_ESP:
356: if (this->spi.len != 4)
357: {
358: DBG1(DBG_ENC, "invalid SPI length in %N proposal",
359: protocol_id_names, this->protocol_id);
360: return FAILED;
361: }
362: break;
363: case PROTO_IKE:
364: if (this->type == PLV1_PROPOSAL_SUBSTRUCTURE)
365: {
366: if (this->spi.len <= 16)
367: { /* according to RFC 2409, section 3.5 anything between
368: * 0 and 16 is fine */
369: break;
370: }
371: }
372: else if (this->spi.len == 0 || this->spi.len == 8)
373: {
374: break;
375: }
376: DBG1(DBG_ENC, "invalid SPI length in IKE proposal");
377: return FAILED;
378: default:
379: break;
380: }
381: enumerator = this->transforms->create_enumerator(this->transforms);
382: while (enumerator->enumerate(enumerator, ¤t))
383: {
384: status = current->verify(current);
385: if (status != SUCCESS)
386: {
387: DBG1(DBG_ENC, "TRANSFORM_SUBSTRUCTURE verification failed");
388: break;
389: }
390: }
391: enumerator->destroy(enumerator);
392:
393: /* proposal number is checked in SA payload */
394: return status;
395: }
396:
397: METHOD(payload_t, get_encoding_rules, int,
398: private_proposal_substructure_t *this, encoding_rule_t **rules)
399: {
400: if (this->type == PLV2_PROPOSAL_SUBSTRUCTURE)
401: {
402: *rules = encodings_v2;
403: return countof(encodings_v2);
404: }
405: *rules = encodings_v1;
406: return countof(encodings_v1);
407: }
408:
409: METHOD(payload_t, get_header_length, int,
410: private_proposal_substructure_t *this)
411: {
412: return 8 + this->spi_size;
413: }
414:
415: METHOD(payload_t, get_type, payload_type_t,
416: private_proposal_substructure_t *this)
417: {
418: return this->type;
419: }
420:
421: METHOD(payload_t, get_next_type, payload_type_t,
422: private_proposal_substructure_t *this)
423: {
424: return this->next_payload;
425: }
426:
427: METHOD(payload_t, set_next_type, void,
428: private_proposal_substructure_t *this, payload_type_t type)
429: {
430: }
431:
432: /**
433: * (re-)compute the length of the payload.
434: */
435: static void compute_length(private_proposal_substructure_t *this)
436: {
437: enumerator_t *enumerator;
438: payload_t *transform;
439:
440: this->transforms_count = 0;
441: this->proposal_length = get_header_length(this);
442: enumerator = this->transforms->create_enumerator(this->transforms);
443: while (enumerator->enumerate(enumerator, &transform))
444: {
445: this->proposal_length += transform->get_length(transform);
446: this->transforms_count++;
447: }
448: enumerator->destroy(enumerator);
449: }
450:
451: METHOD(payload_t, get_length, size_t,
452: private_proposal_substructure_t *this)
453: {
454: return this->proposal_length;
455: }
456:
457: /**
458: * Add a transform substructure to the proposal
459: */
460: static void add_transform_substructure(private_proposal_substructure_t *this,
461: transform_substructure_t *transform)
462: {
463: if (this->transforms->get_count(this->transforms) > 0)
464: {
465: transform_substructure_t *last;
466:
467: this->transforms->get_last(this->transforms, (void **)&last);
468: last->set_is_last_transform(last, FALSE);
469: }
470: transform->set_is_last_transform(transform,TRUE);
471: this->transforms->insert_last(this->transforms, transform);
472: compute_length(this);
473: }
474:
475: METHOD(proposal_substructure_t, set_is_last_proposal, void,
476: private_proposal_substructure_t *this, bool is_last)
477: {
478: this->next_payload = is_last ? 0 : PROPOSAL_TYPE_VALUE;
479: }
480:
481: METHOD(proposal_substructure_t, set_proposal_number, void,
482: private_proposal_substructure_t *this,uint8_t proposal_number)
483: {
484: this->proposal_number = proposal_number;
485: }
486:
487: METHOD(proposal_substructure_t, get_proposal_number, uint8_t,
488: private_proposal_substructure_t *this)
489: {
490: return this->proposal_number;
491: }
492:
493: METHOD(proposal_substructure_t, set_protocol_id, void,
494: private_proposal_substructure_t *this,uint8_t protocol_id)
495: {
496: this->protocol_id = protocol_id;
497: }
498:
499: METHOD(proposal_substructure_t, get_protocol_id, uint8_t,
500: private_proposal_substructure_t *this)
501: {
502: return this->protocol_id;
503: }
504:
505: METHOD(proposal_substructure_t, set_spi, void,
506: private_proposal_substructure_t *this, chunk_t spi)
507: {
508: free(this->spi.ptr);
509: this->spi = chunk_clone(spi);
510: this->spi_size = spi.len;
511: compute_length(this);
512: }
513:
514: METHOD(proposal_substructure_t, get_spi, chunk_t,
515: private_proposal_substructure_t *this)
516: {
517: return this->spi;
518: }
519:
520: METHOD(proposal_substructure_t, get_cpi, bool,
521: private_proposal_substructure_t *this, uint16_t *cpi)
522: {
523:
524: transform_substructure_t *transform;
525: enumerator_t *enumerator;
526:
527: if (this->protocol_id != PROTO_IPCOMP)
528: {
529: return FALSE;
530: }
531:
532: enumerator = this->transforms->create_enumerator(this->transforms);
533: while (enumerator->enumerate(enumerator, &transform))
534: {
535: if (transform->get_transform_id(transform) == IKEV1_IPCOMP_DEFLATE)
536: {
537: if (cpi)
538: {
539: *cpi = htons(untoh16(this->spi.ptr + this->spi.len - 2));
540: }
541: enumerator->destroy(enumerator);
542: return TRUE;
543: }
544: }
545: enumerator->destroy(enumerator);
546: return FALSE;
547: }
548:
549: /**
550: * Add a transform to a proposal for IKEv2
551: */
552: static void add_to_proposal_v2(proposal_t *proposal,
553: transform_substructure_t *transform)
554: {
555: transform_attribute_t *tattr;
556: enumerator_t *enumerator;
557: uint16_t key_length = 0;
558:
559: enumerator = transform->create_attribute_enumerator(transform);
560: while (enumerator->enumerate(enumerator, &tattr))
561: {
562: if (tattr->get_attribute_type(tattr) == TATTR_IKEV2_KEY_LENGTH)
563: {
564: key_length = tattr->get_value(tattr);
565: break;
566: }
567: }
568: enumerator->destroy(enumerator);
569:
570: proposal->add_algorithm(proposal,
571: transform->get_transform_type_or_number(transform),
572: transform->get_transform_id(transform), key_length);
573: }
574:
575: /**
576: * Map IKEv1 to IKEv2 algorithms
577: */
578: typedef struct {
579: uint16_t ikev1;
580: uint16_t ikev2;
581: } algo_map_t;
582:
583: /**
584: * Encryption algorithm mapping
585: */
586: static algo_map_t map_encr[] = {
587: { IKEV1_ENCR_DES_CBC, ENCR_DES },
588: { IKEV1_ENCR_IDEA_CBC, ENCR_IDEA },
589: { IKEV1_ENCR_BLOWFISH_CBC, ENCR_BLOWFISH },
590: { IKEV1_ENCR_3DES_CBC, ENCR_3DES },
591: { IKEV1_ENCR_CAST_CBC, ENCR_CAST },
592: { IKEV1_ENCR_AES_CBC, ENCR_AES_CBC },
593: { IKEV1_ENCR_CAMELLIA_CBC, ENCR_CAMELLIA_CBC },
594: { IKEV1_ENCR_SERPENT_CBC, ENCR_SERPENT_CBC },
595: { IKEV1_ENCR_TWOFISH_CBC, ENCR_TWOFISH_CBC },
596: };
597:
598: /**
599: * Integrity algorithm mapping
600: */
601: static algo_map_t map_integ[] = {
602: { IKEV1_HASH_MD5, AUTH_HMAC_MD5_96 },
603: { IKEV1_HASH_SHA1, AUTH_HMAC_SHA1_96 },
604: { IKEV1_HASH_SHA2_256, AUTH_HMAC_SHA2_256_128 },
605: { IKEV1_HASH_SHA2_384, AUTH_HMAC_SHA2_384_192 },
606: { IKEV1_HASH_SHA2_512, AUTH_HMAC_SHA2_512_256 },
607: };
608:
609: /**
610: * PRF algorithm mapping
611: */
612: static algo_map_t map_prf[] = {
613: { IKEV1_HASH_MD5, PRF_HMAC_MD5 },
614: { IKEV1_HASH_SHA1, PRF_HMAC_SHA1 },
615: { IKEV1_HASH_SHA2_256, PRF_HMAC_SHA2_256 },
616: { IKEV1_HASH_SHA2_384, PRF_HMAC_SHA2_384 },
617: { IKEV1_HASH_SHA2_512, PRF_HMAC_SHA2_512 },
618: };
619:
620: /**
621: * ESP encryption algorithm mapping
622: */
623: static algo_map_t map_esp[] = {
624: { IKEV1_ESP_ENCR_DES_IV64, ENCR_DES_IV64 },
625: { IKEV1_ESP_ENCR_DES, ENCR_DES },
626: { IKEV1_ESP_ENCR_3DES, ENCR_3DES },
627: { IKEV1_ESP_ENCR_RC5, ENCR_RC5 },
628: { IKEV1_ESP_ENCR_IDEA, ENCR_IDEA },
629: { IKEV1_ESP_ENCR_CAST, ENCR_CAST },
630: { IKEV1_ESP_ENCR_BLOWFISH, ENCR_BLOWFISH },
631: { IKEV1_ESP_ENCR_3IDEA, ENCR_3IDEA },
632: { IKEV1_ESP_ENCR_DES_IV32, ENCR_DES_IV32 },
633: { IKEV1_ESP_ENCR_NULL, ENCR_NULL },
634: { IKEV1_ESP_ENCR_AES_CBC, ENCR_AES_CBC },
635: { IKEV1_ESP_ENCR_AES_CTR, ENCR_AES_CTR },
636: { IKEV1_ESP_ENCR_AES_CCM_8, ENCR_AES_CCM_ICV8 },
637: { IKEV1_ESP_ENCR_AES_CCM_12, ENCR_AES_CCM_ICV12 },
638: { IKEV1_ESP_ENCR_AES_CCM_16, ENCR_AES_CCM_ICV16 },
639: { IKEV1_ESP_ENCR_AES_GCM_8, ENCR_AES_GCM_ICV8 },
640: { IKEV1_ESP_ENCR_AES_GCM_12, ENCR_AES_GCM_ICV12 },
641: { IKEV1_ESP_ENCR_AES_GCM_16, ENCR_AES_GCM_ICV16 },
642: { IKEV1_ESP_ENCR_CAMELLIA, ENCR_CAMELLIA_CBC },
643: { IKEV1_ESP_ENCR_NULL_AUTH_AES_GMAC, ENCR_NULL_AUTH_AES_GMAC },
644: { IKEV1_ESP_ENCR_SERPENT, ENCR_SERPENT_CBC },
645: { IKEV1_ESP_ENCR_TWOFISH, ENCR_TWOFISH_CBC },
646: };
647:
648: /**
649: * AH authentication algorithm mapping
650: */
651: static algo_map_t map_ah[] = {
652: { IKEV1_AH_HMAC_MD5, AUTH_HMAC_MD5_96 },
653: { IKEV1_AH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
654: { IKEV1_AH_DES_MAC, AUTH_DES_MAC },
655: { IKEV1_AH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
656: { IKEV1_AH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
657: { IKEV1_AH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
658: { IKEV1_AH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
659: { IKEV1_AH_AES_128_GMAC, AUTH_AES_128_GMAC },
660: { IKEV1_AH_AES_192_GMAC, AUTH_AES_192_GMAC },
661: { IKEV1_AH_AES_256_GMAC, AUTH_AES_256_GMAC },
662: };
663:
664: /**
665: * ESP/AH authentication algorithm mapping
666: */
667: static algo_map_t map_auth[] = {
668: { IKEV1_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 },
669: { IKEV1_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 },
670: { IKEV1_AUTH_DES_MAC, AUTH_DES_MAC },
671: { IKEV1_AUTH_KPDK, AUTH_KPDK_MD5 },
672: { IKEV1_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 },
673: { IKEV1_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 },
674: { IKEV1_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 },
675: { IKEV1_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 },
676: { IKEV1_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC },
677: { IKEV1_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC },
678: { IKEV1_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC },
679: };
680:
681: /**
682: * Map an IKEv1 to an IKEv2 identifier
683: */
684: static uint16_t ikev2_from_ikev1(algo_map_t *map, int count, uint16_t def,
685: uint16_t value)
686: {
687: int i;
688:
689: for (i = 0; i < count; i++)
690: {
691: if (map[i].ikev1 == value)
692: {
693: return map[i].ikev2;
694: }
695: }
696: return def;
697: }
698:
699: /**
700: * Map an IKEv2 to an IKEv1 identifier
701: */
702: static uint16_t ikev1_from_ikev2(algo_map_t *map, int count, uint16_t value)
703: {
704: int i;
705:
706: for (i = 0; i < count; i++)
707: {
708: if (map[i].ikev2 == value)
709: {
710: return map[i].ikev1;
711: }
712: }
713: return 0;
714: }
715:
716: /**
717: * Get IKEv2 algorithm from IKEv1 identifier
718: */
719: static uint16_t get_alg_from_ikev1(transform_type_t type, uint16_t value)
720: {
721: switch (type)
722: {
723: case ENCRYPTION_ALGORITHM:
724: return ikev2_from_ikev1(map_encr, countof(map_encr),
725: ENCR_UNDEFINED, value);
726: case INTEGRITY_ALGORITHM:
727: return ikev2_from_ikev1(map_integ, countof(map_integ),
728: AUTH_UNDEFINED, value);
729: case PSEUDO_RANDOM_FUNCTION:
730: return ikev2_from_ikev1(map_prf, countof(map_prf),
731: PRF_UNDEFINED, value);
732: default:
733: return 0;
734: }
735: }
736:
737: /**
738: * Get IKEv1 algorithm from IKEv2 identifier
739: */
740: static uint16_t get_ikev1_from_alg(transform_type_t type, uint16_t value)
741: {
742: switch (type)
743: {
744: case ENCRYPTION_ALGORITHM:
745: return ikev1_from_ikev2(map_encr, countof(map_encr), value);
746: case INTEGRITY_ALGORITHM:
747: return ikev1_from_ikev2(map_integ, countof(map_integ), value);
748: case PSEUDO_RANDOM_FUNCTION:
749: return ikev1_from_ikev2(map_prf, countof(map_prf), value);
750: default:
751: return 0;
752: }
753: }
754:
755: /**
756: * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID
757: */
758: static uint16_t get_alg_from_ikev1_transid(transform_type_t type,
759: uint16_t value)
760: {
761: switch (type)
762: {
763: case ENCRYPTION_ALGORITHM:
764: return ikev2_from_ikev1(map_esp, countof(map_esp),
765: ENCR_UNDEFINED, value);
766: case INTEGRITY_ALGORITHM:
767: return ikev2_from_ikev1(map_ah, countof(map_ah),
768: AUTH_UNDEFINED, value);
769: default:
770: return 0;
771: }
772: }
773:
774: /**
775: * Get IKEv1 ESP/AH transform ID from IKEv2 identifier
776: */
777: static uint16_t get_ikev1_transid_from_alg(transform_type_t type,
778: uint16_t value)
779: {
780: switch (type)
781: {
782: case ENCRYPTION_ALGORITHM:
783: return ikev1_from_ikev2(map_esp, countof(map_esp), value);
784: case INTEGRITY_ALGORITHM:
785: return ikev1_from_ikev2(map_ah, countof(map_ah), value);
786: default:
787: return 0;
788: }
789: }
790:
791: /**
792: * Get IKEv1 authentication algorithm from IKEv2 identifier
793: */
794: static uint16_t get_alg_from_ikev1_auth(uint16_t value)
795: {
796: return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value);
797: }
798:
799: /**
800: * Get IKEv1 authentication algorithm from IKEv2 identifier
801: */
802: static uint16_t get_ikev1_auth_from_alg(uint16_t value)
803: {
804: return ikev1_from_ikev2(map_auth, countof(map_auth), value);
805: }
806:
807: /**
808: * Get IKEv1 authentication attribute from auth_method_t
809: */
810: static uint16_t get_ikev1_auth(auth_method_t method)
811: {
812: switch (method)
813: {
814: case AUTH_RSA:
815: return IKEV1_AUTH_RSA_SIG;
816: case AUTH_DSS:
817: return IKEV1_AUTH_DSS_SIG;
818: case AUTH_XAUTH_INIT_PSK:
819: return IKEV1_AUTH_XAUTH_INIT_PSK;
820: case AUTH_XAUTH_RESP_PSK:
821: return IKEV1_AUTH_XAUTH_RESP_PSK;
822: case AUTH_XAUTH_INIT_RSA:
823: return IKEV1_AUTH_XAUTH_INIT_RSA;
824: case AUTH_XAUTH_RESP_RSA:
825: return IKEV1_AUTH_XAUTH_RESP_RSA;
826: case AUTH_HYBRID_INIT_RSA:
827: return IKEV1_AUTH_HYBRID_INIT_RSA;
828: case AUTH_HYBRID_RESP_RSA:
829: return IKEV1_AUTH_HYBRID_RESP_RSA;
830: case AUTH_ECDSA_256:
831: return IKEV1_AUTH_ECDSA_256;
832: case AUTH_ECDSA_384:
833: return IKEV1_AUTH_ECDSA_384;
834: case AUTH_ECDSA_521:
835: return IKEV1_AUTH_ECDSA_521;
836: case AUTH_PSK:
837: default:
838: return IKEV1_AUTH_PSK;
839: }
840: }
841:
842: /**
843: * Get IKEv1 encapsulation mode
844: */
845: static uint16_t get_ikev1_mode(ipsec_mode_t mode, encap_t udp)
846: {
847: switch (mode)
848: {
849: case MODE_TUNNEL:
850: switch (udp)
851: {
852: case ENCAP_UDP:
853: return IKEV1_ENCAP_UDP_TUNNEL;
854: case ENCAP_UDP_DRAFT_00_03:
855: return IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03;
856: default:
857: return IKEV1_ENCAP_TUNNEL;
858: }
859: case MODE_TRANSPORT:
860: switch (udp)
861: {
862: case ENCAP_UDP:
863: return IKEV1_ENCAP_UDP_TRANSPORT;
864: case ENCAP_UDP_DRAFT_00_03:
865: return IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03;
866: default:
867: return IKEV1_ENCAP_TRANSPORT;
868: }
869: default:
870: return IKEV1_ENCAP_TUNNEL;
871: }
872: }
873:
874: /**
875: * Add an IKE transform to a proposal for IKEv1
876: */
877: static void add_to_proposal_v1_ike(proposal_t *proposal,
878: transform_substructure_t *transform)
879: {
880: transform_attribute_type_t type;
881: transform_attribute_t *tattr;
882: enumerator_t *enumerator;
883: uint16_t value, key_length = 0;
884: uint16_t encr = ENCR_UNDEFINED;
885:
886: enumerator = transform->create_attribute_enumerator(transform);
887: while (enumerator->enumerate(enumerator, &tattr))
888: {
889: type = tattr->get_attribute_type(tattr);
890: value = tattr->get_value(tattr);
891: switch (type)
892: {
893: case TATTR_PH1_ENCRYPTION_ALGORITHM:
894: encr = get_alg_from_ikev1(ENCRYPTION_ALGORITHM, value);
895: break;
896: case TATTR_PH1_KEY_LENGTH:
897: key_length = value;
898: break;
899: case TATTR_PH1_HASH_ALGORITHM:
900: proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
901: get_alg_from_ikev1(INTEGRITY_ALGORITHM, value), 0);
902: proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION,
903: get_alg_from_ikev1(PSEUDO_RANDOM_FUNCTION, value), 0);
904: break;
905: case TATTR_PH1_GROUP:
906: proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
907: value, 0);
908: break;
909: default:
910: break;
911: }
912: }
913: enumerator->destroy(enumerator);
914:
915: if (encr != ENCR_UNDEFINED)
916: {
917: if (encr == ENCR_AES_CBC && !key_length)
918: { /* some implementations don't send a Key Length attribute for
919: * AES-128, early drafts of RFC 3602 allowed that */
920: key_length = 128;
921: }
922: proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, key_length);
923: }
924: }
925:
926: /**
927: * Add an ESP/AH transform to a proposal for IKEv1
928: */
929: static void add_to_proposal_v1(proposal_t *proposal,
930: transform_substructure_t *transform, protocol_id_t proto)
931: {
932: transform_attribute_type_t type;
933: transform_attribute_t *tattr;
934: enumerator_t *enumerator;
935: uint16_t encr, value, key_length = 0;
936: extended_sequence_numbers_t esn = NO_EXT_SEQ_NUMBERS;
937:
938: enumerator = transform->create_attribute_enumerator(transform);
939: while (enumerator->enumerate(enumerator, &tattr))
940: {
941: type = tattr->get_attribute_type(tattr);
942: value = tattr->get_value(tattr);
943: switch (type)
944: {
945: case TATTR_PH2_KEY_LENGTH:
946: key_length = value;
947: break;
948: case TATTR_PH2_AUTH_ALGORITHM:
949: proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
950: get_alg_from_ikev1_auth(value), 0);
951: break;
952: case TATTR_PH2_GROUP:
953: proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
954: value, 0);
955: break;
956: case TATTR_PH2_EXT_SEQ_NUMBER:
957: esn = EXT_SEQ_NUMBERS;
958: break;
959: default:
960: break;
961: }
962: }
963: enumerator->destroy(enumerator);
964:
965: proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0);
966: if (proto == PROTO_ESP)
967: {
968: encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM,
969: transform->get_transform_id(transform));
970: if (encr)
971: {
972: if (encr == ENCR_AES_CBC && !key_length)
973: { /* some implementations don't send a Key Length attribute for
974: * AES-128, early drafts of RFC 3602 allowed that for IKE, some
975: * also seem to do it for ESP */
976: key_length = 128;
977: }
978: proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr,
979: key_length);
980: }
981: }
982: }
983:
984: METHOD(proposal_substructure_t, get_proposals, void,
985: private_proposal_substructure_t *this, linked_list_t *proposals)
986: {
987: transform_substructure_t *transform;
988: enumerator_t *enumerator;
989: proposal_t *proposal = NULL;
990: uint64_t spi = 0;
991:
992: switch (this->spi.len)
993: {
994: case 4:
995: spi = *((uint32_t*)this->spi.ptr);
996: break;
997: case 8:
998: spi = *((uint64_t*)this->spi.ptr);
999: break;
1000: default:
1001: break;
1002: }
1003:
1004: enumerator = this->transforms->create_enumerator(this->transforms);
1005: while (enumerator->enumerate(enumerator, &transform))
1006: {
1007: if (this->type == PLV2_PROPOSAL_SUBSTRUCTURE)
1008: {
1009: if (!proposal)
1010: {
1011: proposal = proposal_create(this->protocol_id,
1012: this->proposal_number);
1013: proposal->set_spi(proposal, spi);
1014: proposals->insert_last(proposals, proposal);
1015: }
1016: add_to_proposal_v2(proposal, transform);
1017: }
1018: else
1019: {
1020: /* create a new proposal for each transform in IKEv1 */
1021: proposal = proposal_create_v1(
1022: this->protocol_id, this->proposal_number,
1023: transform->get_transform_type_or_number(transform));
1024: proposal->set_spi(proposal, spi);
1025: proposals->insert_last(proposals, proposal);
1026: switch (this->protocol_id)
1027: {
1028: case PROTO_IKE:
1029: add_to_proposal_v1_ike(proposal, transform);
1030: break;
1031: case PROTO_ESP:
1032: case PROTO_AH:
1033: add_to_proposal_v1(proposal, transform, this->protocol_id);
1034: break;
1035: default:
1036: break;
1037: }
1038: }
1039: }
1040: enumerator->destroy(enumerator);
1041: }
1042:
1043: METHOD(proposal_substructure_t, create_substructure_enumerator, enumerator_t*,
1044: private_proposal_substructure_t *this)
1045: {
1046: return this->transforms->create_enumerator(this->transforms);
1047: }
1048:
1049: /**
1050: * Get an attribute from any transform, 0 if not found
1051: */
1052: static uint64_t get_attr(private_proposal_substructure_t *this,
1053: transform_attribute_type_t type)
1054: {
1055: enumerator_t *transforms, *attributes;
1056: transform_substructure_t *transform;
1057: transform_attribute_t *attr;
1058:
1059: transforms = this->transforms->create_enumerator(this->transforms);
1060: while (transforms->enumerate(transforms, &transform))
1061: {
1062: attributes = transform->create_attribute_enumerator(transform);
1063: while (attributes->enumerate(attributes, &attr))
1064: {
1065: if (attr->get_attribute_type(attr) == type)
1066: {
1067: attributes->destroy(attributes);
1068: transforms->destroy(transforms);
1069: return attr->get_value(attr);
1070: }
1071: }
1072: attributes->destroy(attributes);
1073: }
1074: transforms->destroy(transforms);
1075: return 0;
1076: }
1077:
1078: /**
1079: * Look up a lifetime duration of a given kind in all transforms
1080: */
1081: static uint64_t get_life_duration(private_proposal_substructure_t *this,
1082: uint8_t number, transform_attribute_type_t type_attr,
1083: ikev1_life_type_t type, transform_attribute_type_t dur_attr)
1084: {
1085: enumerator_t *transforms, *attributes;
1086: transform_substructure_t *transform;
1087: transform_attribute_t *attr;
1088:
1089: transforms = this->transforms->create_enumerator(this->transforms);
1090: while (transforms->enumerate(transforms, &transform))
1091: {
1092: if (transform->get_transform_type_or_number(transform) != number)
1093: {
1094: continue;
1095: }
1096: attributes = transform->create_attribute_enumerator(transform);
1097: while (attributes->enumerate(attributes, &attr))
1098: {
1099: if (attr->get_attribute_type(attr) == type_attr &&
1100: attr->get_value(attr) == type)
1101: { /* got type attribute, look for duration following next */
1102: while (attributes->enumerate(attributes, &attr))
1103: {
1104: if (attr->get_attribute_type(attr) == dur_attr)
1105: {
1106: attributes->destroy(attributes);
1107: transforms->destroy(transforms);
1108: return attr->get_value(attr);
1109: }
1110: }
1111: }
1112: }
1113: attributes->destroy(attributes);
1114: }
1115: transforms->destroy(transforms);
1116: return 0;
1117: }
1118:
1119: METHOD(proposal_substructure_t, get_lifetime, uint32_t,
1120: private_proposal_substructure_t *this, uint8_t transform)
1121: {
1122: uint32_t duration;
1123:
1124: switch (this->protocol_id)
1125: {
1126: case PROTO_IKE:
1127: return get_life_duration(this, transform, TATTR_PH1_LIFE_TYPE,
1128: IKEV1_LIFE_TYPE_SECONDS, TATTR_PH1_LIFE_DURATION);
1129: case PROTO_ESP:
1130: case PROTO_AH:
1131: duration = get_life_duration(this, transform,
1132: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS,
1133: TATTR_PH2_SA_LIFE_DURATION);
1134: if (!duration)
1135: { /* default to 8 hours, RFC 2407 */
1136: return 28800;
1137: }
1138: return duration;
1139: default:
1140: return 0;
1141: }
1142: }
1143:
1144: METHOD(proposal_substructure_t, get_lifebytes, uint64_t,
1145: private_proposal_substructure_t *this, uint8_t transform)
1146: {
1147: switch (this->protocol_id)
1148: {
1149: case PROTO_ESP:
1150: case PROTO_AH:
1151: return 1000 * get_life_duration(this, transform,
1152: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES,
1153: TATTR_PH2_SA_LIFE_DURATION);
1154: case PROTO_IKE:
1155: default:
1156: return 0;
1157: }
1158: }
1159:
1160: METHOD(proposal_substructure_t, get_auth_method, auth_method_t,
1161: private_proposal_substructure_t *this)
1162: {
1163: switch (get_attr(this, TATTR_PH1_AUTH_METHOD))
1164: {
1165: case IKEV1_AUTH_PSK:
1166: return AUTH_PSK;
1167: case IKEV1_AUTH_RSA_SIG:
1168: return AUTH_RSA;
1169: case IKEV1_AUTH_DSS_SIG:
1170: return AUTH_DSS;
1171: case IKEV1_AUTH_XAUTH_INIT_PSK:
1172: return AUTH_XAUTH_INIT_PSK;
1173: case IKEV1_AUTH_XAUTH_RESP_PSK:
1174: return AUTH_XAUTH_RESP_PSK;
1175: case IKEV1_AUTH_XAUTH_INIT_RSA:
1176: return AUTH_XAUTH_INIT_RSA;
1177: case IKEV1_AUTH_XAUTH_RESP_RSA:
1178: return AUTH_XAUTH_RESP_RSA;
1179: case IKEV1_AUTH_HYBRID_INIT_RSA:
1180: return AUTH_HYBRID_INIT_RSA;
1181: case IKEV1_AUTH_HYBRID_RESP_RSA:
1182: return AUTH_HYBRID_RESP_RSA;
1183: case IKEV1_AUTH_ECDSA_256:
1184: return AUTH_ECDSA_256;
1185: case IKEV1_AUTH_ECDSA_384:
1186: return AUTH_ECDSA_384;
1187: case IKEV1_AUTH_ECDSA_521:
1188: return AUTH_ECDSA_521;
1189: default:
1190: return AUTH_NONE;
1191: }
1192: }
1193:
1194: METHOD(proposal_substructure_t, get_encap_mode, ipsec_mode_t,
1195: private_proposal_substructure_t *this, bool *udp)
1196: {
1197: *udp = FALSE;
1198: switch (get_attr(this, TATTR_PH2_ENCAP_MODE))
1199: {
1200: case IKEV1_ENCAP_TRANSPORT:
1201: return MODE_TRANSPORT;
1202: case IKEV1_ENCAP_TUNNEL:
1203: return MODE_TUNNEL;
1204: case IKEV1_ENCAP_UDP_TRANSPORT:
1205: case IKEV1_ENCAP_UDP_TRANSPORT_DRAFT_00_03:
1206: *udp = TRUE;
1207: return MODE_TRANSPORT;
1208: case IKEV1_ENCAP_UDP_TUNNEL:
1209: case IKEV1_ENCAP_UDP_TUNNEL_DRAFT_00_03:
1210: *udp = TRUE;
1211: return MODE_TUNNEL;
1212: default:
1213: /* default to TUNNEL, RFC 2407 says implementation specific */
1214: return MODE_TUNNEL;
1215: }
1216: }
1217:
1218: METHOD2(payload_t, proposal_substructure_t, destroy, void,
1219: private_proposal_substructure_t *this)
1220: {
1221: this->transforms->destroy_offset(this->transforms,
1222: offsetof(payload_t, destroy));
1223: chunk_free(&this->spi);
1224: free(this);
1225: }
1226:
1227: /*
1228: * Described in header.
1229: */
1230: proposal_substructure_t *proposal_substructure_create(payload_type_t type)
1231: {
1232: private_proposal_substructure_t *this;
1233:
1234: INIT(this,
1235: .public = {
1236: .payload_interface = {
1237: .verify = _verify,
1238: .get_encoding_rules = _get_encoding_rules,
1239: .get_header_length = _get_header_length,
1240: .get_length = _get_length,
1241: .get_next_type = _get_next_type,
1242: .set_next_type = _set_next_type,
1243: .get_type = _get_type,
1244: .destroy = _destroy,
1245: },
1246: .set_proposal_number = _set_proposal_number,
1247: .get_proposal_number = _get_proposal_number,
1248: .set_protocol_id = _set_protocol_id,
1249: .get_protocol_id = _get_protocol_id,
1250: .set_is_last_proposal = _set_is_last_proposal,
1251: .get_proposals = _get_proposals,
1252: .create_substructure_enumerator = _create_substructure_enumerator,
1253: .set_spi = _set_spi,
1254: .get_spi = _get_spi,
1255: .get_cpi = _get_cpi,
1256: .get_lifetime = _get_lifetime,
1257: .get_lifebytes = _get_lifebytes,
1258: .get_auth_method = _get_auth_method,
1259: .get_encap_mode = _get_encap_mode,
1260: .destroy = _destroy,
1261: },
1262: .next_payload = PL_NONE,
1263: .transforms = linked_list_create(),
1264: .type = type,
1265: );
1266: compute_length(this);
1267:
1268: return &this->public;
1269: }
1270:
1271: /**
1272: * Add an IKEv1 IKE proposal to the substructure
1273: */
1274: static void set_from_proposal_v1_ike(private_proposal_substructure_t *this,
1275: proposal_t *proposal, uint32_t lifetime,
1276: auth_method_t method, int number)
1277: {
1278: transform_substructure_t *transform;
1279: uint16_t alg, key_size;
1280: enumerator_t *enumerator;
1281:
1282: transform = transform_substructure_create_type(PLV1_TRANSFORM_SUBSTRUCTURE,
1283: number, IKEV1_TRANSID_KEY_IKE);
1284:
1285: enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
1286: while (enumerator->enumerate(enumerator, &alg, &key_size))
1287: {
1288: alg = get_ikev1_from_alg(ENCRYPTION_ALGORITHM, alg);
1289: if (alg)
1290: {
1291: transform->add_transform_attribute(transform,
1292: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1293: TATTR_PH1_ENCRYPTION_ALGORITHM, alg));
1294: if (key_size)
1295: {
1296: transform->add_transform_attribute(transform,
1297: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1298: TATTR_PH1_KEY_LENGTH, key_size));
1299: }
1300: break;
1301: }
1302: }
1303: enumerator->destroy(enumerator);
1304:
1305: /* encode the integrity algorithm as hash and assume use the same PRF */
1306: enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
1307: while (enumerator->enumerate(enumerator, &alg, &key_size))
1308: {
1309: alg = get_ikev1_from_alg(INTEGRITY_ALGORITHM, alg);
1310: if (alg)
1311: {
1312: transform->add_transform_attribute(transform,
1313: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1314: TATTR_PH1_HASH_ALGORITHM, alg));
1315: break;
1316: }
1317: }
1318: enumerator->destroy(enumerator);
1319:
1320: enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP);
1321: if (enumerator->enumerate(enumerator, &alg, &key_size))
1322: {
1323: transform->add_transform_attribute(transform,
1324: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1325: TATTR_PH1_GROUP, alg));
1326: }
1327: enumerator->destroy(enumerator);
1328:
1329: transform->add_transform_attribute(transform,
1330: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1331: TATTR_PH1_AUTH_METHOD, get_ikev1_auth(method)));
1332: transform->add_transform_attribute(transform,
1333: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1334: TATTR_PH1_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS));
1335: transform->add_transform_attribute(transform,
1336: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1337: TATTR_PH1_LIFE_DURATION, lifetime));
1338:
1339: add_transform_substructure(this, transform);
1340: }
1341:
1342: /**
1343: * Add an IKEv1 ESP/AH proposal to the substructure
1344: */
1345: static void set_from_proposal_v1(private_proposal_substructure_t *this,
1346: proposal_t *proposal, uint32_t lifetime, uint64_t lifebytes,
1347: ipsec_mode_t mode, encap_t udp, int number)
1348: {
1349: transform_substructure_t *transform = NULL;
1350: uint16_t alg, transid, key_size;
1351: enumerator_t *enumerator;
1352:
1353: enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
1354: if (enumerator->enumerate(enumerator, &alg, &key_size))
1355: {
1356: transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg);
1357: if (transid)
1358: {
1359: transform = transform_substructure_create_type(
1360: PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
1361: if (key_size)
1362: {
1363: transform->add_transform_attribute(transform,
1364: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1365: TATTR_PH2_KEY_LENGTH, key_size));
1366: }
1367: }
1368: }
1369: enumerator->destroy(enumerator);
1370:
1371: enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
1372: if (enumerator->enumerate(enumerator, &alg, &key_size))
1373: {
1374: transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
1375: alg = get_ikev1_auth_from_alg(alg);
1376: if (alg)
1377: {
1378: if (!transform && transid)
1379: {
1380: transform = transform_substructure_create_type(
1381: PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
1382: }
1383: if (transform)
1384: {
1385: transform->add_transform_attribute(transform,
1386: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1387: TATTR_PH2_AUTH_ALGORITHM, alg));
1388: }
1389: }
1390: }
1391: enumerator->destroy(enumerator);
1392:
1393: if (!transform)
1394: {
1395: return;
1396: }
1397:
1398: enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP);
1399: if (enumerator->enumerate(enumerator, &alg, &key_size))
1400: {
1401: transform->add_transform_attribute(transform,
1402: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1403: TATTR_PH2_GROUP, alg));
1404: }
1405: enumerator->destroy(enumerator);
1406:
1407: transform->add_transform_attribute(transform,
1408: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1409: TATTR_PH2_ENCAP_MODE, get_ikev1_mode(mode, udp)));
1410: if (lifetime)
1411: {
1412: transform->add_transform_attribute(transform,
1413: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1414: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS));
1415: transform->add_transform_attribute(transform,
1416: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1417: TATTR_PH2_SA_LIFE_DURATION, lifetime));
1418: }
1419: if (lifebytes)
1420: {
1421: transform->add_transform_attribute(transform,
1422: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1423: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES));
1424: transform->add_transform_attribute(transform,
1425: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1426: TATTR_PH2_SA_LIFE_DURATION, lifebytes / 1000));
1427: }
1428:
1429: enumerator = proposal->create_enumerator(proposal,
1430: EXTENDED_SEQUENCE_NUMBERS);
1431: while (enumerator->enumerate(enumerator, &alg, NULL))
1432: {
1433: if (alg == EXT_SEQ_NUMBERS)
1434: {
1435: transform->add_transform_attribute(transform,
1436: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1437: TATTR_PH2_EXT_SEQ_NUMBER, alg));
1438: }
1439: }
1440: enumerator->destroy(enumerator);
1441: add_transform_substructure(this, transform);
1442: }
1443:
1444: /**
1445: * Add an IKEv2 proposal to the substructure
1446: */
1447: static void set_from_proposal_v2(private_proposal_substructure_t *this,
1448: proposal_t *proposal)
1449: {
1450: transform_substructure_t *transform;
1451: uint16_t alg, key_size;
1452: enumerator_t *enumerator;
1453:
1454: /* encryption algorithm is only available in ESP */
1455: enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
1456: while (enumerator->enumerate(enumerator, &alg, &key_size))
1457: {
1458: transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE,
1459: ENCRYPTION_ALGORITHM, alg);
1460: if (key_size)
1461: {
1462: transform->add_transform_attribute(transform,
1463: transform_attribute_create_value(PLV2_TRANSFORM_ATTRIBUTE,
1464: TATTR_IKEV2_KEY_LENGTH, key_size));
1465: }
1466: add_transform_substructure(this, transform);
1467: }
1468: enumerator->destroy(enumerator);
1469:
1470: /* integrity algorithms */
1471: enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
1472: while (enumerator->enumerate(enumerator, &alg, &key_size))
1473: {
1474: transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE,
1475: INTEGRITY_ALGORITHM, alg);
1476: add_transform_substructure(this, transform);
1477: }
1478: enumerator->destroy(enumerator);
1479:
1480: /* prf algorithms */
1481: enumerator = proposal->create_enumerator(proposal, PSEUDO_RANDOM_FUNCTION);
1482: while (enumerator->enumerate(enumerator, &alg, &key_size))
1483: {
1484: transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE,
1485: PSEUDO_RANDOM_FUNCTION, alg);
1486: add_transform_substructure(this, transform);
1487: }
1488: enumerator->destroy(enumerator);
1489:
1490: /* dh groups */
1491: enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP);
1492: while (enumerator->enumerate(enumerator, &alg, NULL))
1493: {
1494: transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE,
1495: DIFFIE_HELLMAN_GROUP, alg);
1496: add_transform_substructure(this, transform);
1497: }
1498: enumerator->destroy(enumerator);
1499:
1500: /* extended sequence numbers */
1501: enumerator = proposal->create_enumerator(proposal, EXTENDED_SEQUENCE_NUMBERS);
1502: while (enumerator->enumerate(enumerator, &alg, NULL))
1503: {
1504: transform = transform_substructure_create_type(PLV2_TRANSFORM_SUBSTRUCTURE,
1505: EXTENDED_SEQUENCE_NUMBERS, alg);
1506: add_transform_substructure(this, transform);
1507: }
1508: enumerator->destroy(enumerator);
1509: }
1510:
1511: /**
1512: * Set SPI and other data from proposal, compute length
1513: */
1514: static void set_data(private_proposal_substructure_t *this, proposal_t *proposal)
1515: {
1516: uint64_t spi64;
1517: uint32_t spi32;
1518:
1519: /* add SPI, if necessary */
1520: switch (proposal->get_protocol(proposal))
1521: {
1522: case PROTO_AH:
1523: case PROTO_ESP:
1524: spi32 = proposal->get_spi(proposal);
1525: this->spi = chunk_clone(chunk_from_thing(spi32));
1526: this->spi_size = this->spi.len;
1527: break;
1528: case PROTO_IKE:
1529: spi64 = proposal->get_spi(proposal);
1530: if (spi64)
1531: { /* IKE only uses SPIS when rekeying, but on initial setup */
1532: this->spi = chunk_clone(chunk_from_thing(spi64));
1533: this->spi_size = this->spi.len;
1534: }
1535: break;
1536: default:
1537: break;
1538: }
1539: /* default to 1 if no number is set (mainly for IKEv1, for IKEv2 the numbers
1540: * are explicitly set when proposals are added to the SA payload) */
1541: this->proposal_number = proposal->get_number(proposal) ?: 1;
1542: this->protocol_id = proposal->get_protocol(proposal);
1543: compute_length(this);
1544: }
1545:
1546: /*
1547: * Described in header.
1548: */
1549: proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
1550: proposal_t *proposal)
1551: {
1552: private_proposal_substructure_t *this;
1553:
1554: this = (private_proposal_substructure_t*)
1555: proposal_substructure_create(PLV2_PROPOSAL_SUBSTRUCTURE);
1556: set_from_proposal_v2(this, proposal);
1557: set_data(this, proposal);
1558:
1559: return &this->public;
1560: }
1561:
1562: /**
1563: * Creates an IKEv1 proposal_substructure_t from a proposal_t.
1564: */
1565: static proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
1566: proposal_t *proposal, uint32_t lifetime, uint64_t lifebytes,
1567: auth_method_t auth, ipsec_mode_t mode, encap_t udp, uint8_t number)
1568: {
1569: private_proposal_substructure_t *this;
1570:
1571: this = (private_proposal_substructure_t*)
1572: proposal_substructure_create(PLV1_PROPOSAL_SUBSTRUCTURE);
1573: switch (proposal->get_protocol(proposal))
1574: {
1575: case PROTO_IKE:
1576: set_from_proposal_v1_ike(this, proposal, lifetime, auth, number);
1577: break;
1578: case PROTO_ESP:
1579: case PROTO_AH:
1580: set_from_proposal_v1(this, proposal, lifetime,
1581: lifebytes, mode, udp, number);
1582: break;
1583: default:
1584: break;
1585: }
1586: set_data(this, proposal);
1587:
1588: return &this->public;
1589: }
1590:
1591: /**
1592: * See header.
1593: */
1594: proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
1595: linked_list_t *proposals, uint32_t lifetime, uint64_t lifebytes,
1596: auth_method_t auth, ipsec_mode_t mode, encap_t udp)
1597: {
1598: private_proposal_substructure_t *this = NULL;
1599: enumerator_t *enumerator;
1600: proposal_t *proposal;
1601: int number = 1;
1602:
1603: enumerator = proposals->create_enumerator(proposals);
1604: while (enumerator->enumerate(enumerator, &proposal))
1605: {
1606: if (!this)
1607: { /* as responder the transform number is set and we only have a
1608: * single proposal, start with 1 otherwise */
1609: this = (private_proposal_substructure_t*)
1610: proposal_substructure_create_from_proposal_v1(
1611: proposal, lifetime, lifebytes, auth, mode, udp,
1612: proposal->get_transform_number(proposal) ?: number);
1613: }
1614: else
1615: {
1616: switch (proposal->get_protocol(proposal))
1617: {
1618: case PROTO_IKE:
1619: set_from_proposal_v1_ike(this, proposal, lifetime,
1620: auth, ++number);
1621: break;
1622: case PROTO_ESP:
1623: case PROTO_AH:
1624: set_from_proposal_v1(this, proposal, lifetime,
1625: lifebytes, mode, udp, ++number);
1626: break;
1627: default:
1628: break;
1629: }
1630: }
1631: }
1632: enumerator->destroy(enumerator);
1633:
1634: return &this->public;
1635: }
1636:
1637: /**
1638: * See header.
1639: */
1640: proposal_substructure_t *proposal_substructure_create_for_ipcomp_v1(
1641: uint32_t lifetime, uint64_t lifebytes, uint16_t cpi,
1642: ipsec_mode_t mode, encap_t udp, uint8_t proposal_number)
1643: {
1644: private_proposal_substructure_t *this;
1645: transform_substructure_t *transform;
1646:
1647:
1648: this = (private_proposal_substructure_t*)
1649: proposal_substructure_create(PLV1_PROPOSAL_SUBSTRUCTURE);
1650:
1651: /* we currently support DEFLATE only */
1652: transform = transform_substructure_create_type(PLV1_TRANSFORM_SUBSTRUCTURE,
1653: 1, IKEV1_IPCOMP_DEFLATE);
1654:
1655: transform->add_transform_attribute(transform,
1656: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1657: TATTR_PH2_ENCAP_MODE, get_ikev1_mode(mode, udp)));
1658: if (lifetime)
1659: {
1660: transform->add_transform_attribute(transform,
1661: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1662: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS));
1663: transform->add_transform_attribute(transform,
1664: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1665: TATTR_PH2_SA_LIFE_DURATION, lifetime));
1666: }
1667: if (lifebytes)
1668: {
1669: transform->add_transform_attribute(transform,
1670: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1671: TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES));
1672: transform->add_transform_attribute(transform,
1673: transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,
1674: TATTR_PH2_SA_LIFE_DURATION, lifebytes / 1000));
1675: }
1676:
1677: add_transform_substructure(this, transform);
1678:
1679: this->spi = chunk_clone(chunk_from_thing(cpi));
1680: this->spi_size = this->spi.len;
1681: this->protocol_id = PROTO_IPCOMP;
1682: this->proposal_number = proposal_number;
1683:
1684: compute_length(this);
1685:
1686: return &this->public;
1687: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>