Return to ke_payload.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / encoding / payloads |
1.1 misho 1: /* 2: * Copyright (C) 2005-2010 Martin Willi 3: * Copyright (C) 2010 revosec AG 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 "ke_payload.h" 21: 22: #include <encoding/payloads/encodings.h> 23: 24: typedef struct private_ke_payload_t private_ke_payload_t; 25: 26: /** 27: * Private data of an ke_payload_t object. 28: */ 29: struct private_ke_payload_t { 30: 31: /** 32: * Public ke_payload_t interface. 33: */ 34: ke_payload_t public; 35: 36: /** 37: * Next payload type. 38: */ 39: uint8_t next_payload; 40: 41: /** 42: * Critical flag. 43: */ 44: bool critical; 45: 46: /** 47: * Reserved bits 48: */ 49: bool reserved_bit[7]; 50: 51: /** 52: * Reserved bytes 53: */ 54: uint8_t reserved_byte[2]; 55: 56: /** 57: * Length of this payload. 58: */ 59: uint16_t payload_length; 60: 61: /** 62: * DH Group Number. 63: */ 64: uint16_t dh_group_number; 65: 66: /** 67: * Key Exchange Data of this KE payload. 68: */ 69: chunk_t key_exchange_data; 70: 71: /** 72: * Payload type, PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE 73: */ 74: payload_type_t type; 75: }; 76: 77: /** 78: * Encoding rules for IKEv2 key exchange payload. 79: */ 80: static encoding_rule_t encodings_v2[] = { 81: /* 1 Byte next payload type, stored in the field next_payload */ 82: { U_INT_8, offsetof(private_ke_payload_t, next_payload) }, 83: /* the critical bit */ 84: { FLAG, offsetof(private_ke_payload_t, critical) }, 85: /* 7 Bit reserved bits */ 86: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[0]) }, 87: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[1]) }, 88: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[2]) }, 89: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[3]) }, 90: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[4]) }, 91: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[5]) }, 92: { RESERVED_BIT, offsetof(private_ke_payload_t, reserved_bit[6]) }, 93: /* Length of the whole payload*/ 94: { PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) }, 95: /* DH Group number as 16 bit field*/ 96: { U_INT_16, offsetof(private_ke_payload_t, dh_group_number) }, 97: /* 2 reserved bytes */ 98: { RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[0])}, 99: { RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[1])}, 100: /* Key Exchange Data is from variable size */ 101: { CHUNK_DATA, offsetof(private_ke_payload_t, key_exchange_data)}, 102: }; 103: 104: /* 105: 1 2 3 106: 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 107: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 108: ! Next Payload !C! RESERVED ! Payload Length ! 109: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 110: ! DH Group # ! RESERVED ! 111: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 112: ! ! 113: ~ Key Exchange Data ~ 114: ! ! 115: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 116: */ 117: 118: static encoding_rule_t encodings_v1[] = { 119: /* 1 Byte next payload type, stored in the field next_payload */ 120: { U_INT_8, offsetof(private_ke_payload_t, next_payload) }, 121: /* Reserved Byte */ 122: { RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[0])}, 123: /* Length of the whole payload*/ 124: { PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) }, 125: /* Key Exchange Data is from variable size */ 126: { CHUNK_DATA, offsetof(private_ke_payload_t, key_exchange_data)}, 127: }; 128: 129: /* 130: 1 2 3 131: 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 132: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 133: ! Next Payload ! RESERVED ! Payload Length ! 134: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 135: ! ! 136: ~ Key Exchange Data ~ 137: ! ! 138: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 139: */ 140: 141: 142: METHOD(payload_t, verify, status_t, 143: private_ke_payload_t *this) 144: { 145: return SUCCESS; 146: } 147: 148: METHOD(payload_t, get_encoding_rules, int, 149: private_ke_payload_t *this, encoding_rule_t **rules) 150: { 151: if (this->type == PLV2_KEY_EXCHANGE) 152: { 153: *rules = encodings_v2; 154: return countof(encodings_v2); 155: } 156: *rules = encodings_v1; 157: return countof(encodings_v1); 158: } 159: 160: METHOD(payload_t, get_header_length, int, 161: private_ke_payload_t *this) 162: { 163: if (this->type == PLV2_KEY_EXCHANGE) 164: { 165: return 8; 166: } 167: return 4; 168: } 169: 170: METHOD(payload_t, get_type, payload_type_t, 171: private_ke_payload_t *this) 172: { 173: return this->type; 174: } 175: 176: METHOD(payload_t, get_next_type, payload_type_t, 177: private_ke_payload_t *this) 178: { 179: return this->next_payload; 180: } 181: 182: METHOD(payload_t, set_next_type, void, 183: private_ke_payload_t *this,payload_type_t type) 184: { 185: this->next_payload = type; 186: } 187: 188: METHOD(payload_t, get_length, size_t, 189: private_ke_payload_t *this) 190: { 191: return this->payload_length; 192: } 193: 194: METHOD(ke_payload_t, get_key_exchange_data, chunk_t, 195: private_ke_payload_t *this) 196: { 197: return this->key_exchange_data; 198: } 199: 200: METHOD(ke_payload_t, get_dh_group_number, diffie_hellman_group_t, 201: private_ke_payload_t *this) 202: { 203: return this->dh_group_number; 204: } 205: 206: METHOD2(payload_t, ke_payload_t, destroy, void, 207: private_ke_payload_t *this) 208: { 209: free(this->key_exchange_data.ptr); 210: free(this); 211: } 212: 213: /* 214: * Described in header 215: */ 216: ke_payload_t *ke_payload_create(payload_type_t type) 217: { 218: private_ke_payload_t *this; 219: 220: INIT(this, 221: .public = { 222: .payload_interface = { 223: .verify = _verify, 224: .get_encoding_rules = _get_encoding_rules, 225: .get_header_length = _get_header_length, 226: .get_length = _get_length, 227: .get_next_type = _get_next_type, 228: .set_next_type = _set_next_type, 229: .get_type = _get_type, 230: .destroy = _destroy, 231: }, 232: .get_key_exchange_data = _get_key_exchange_data, 233: .get_dh_group_number = _get_dh_group_number, 234: .destroy = _destroy, 235: }, 236: .next_payload = PL_NONE, 237: .dh_group_number = MODP_NONE, 238: .type = type, 239: ); 240: this->payload_length = get_header_length(this); 241: return &this->public; 242: } 243: 244: /* 245: * Described in header 246: */ 247: ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type, 248: diffie_hellman_t *dh) 249: { 250: private_ke_payload_t *this; 251: chunk_t value; 252: 253: if (!dh->get_my_public_value(dh, &value)) 254: { 255: return NULL; 256: } 257: this = (private_ke_payload_t*)ke_payload_create(type); 258: this->key_exchange_data = value; 259: this->dh_group_number = dh->get_dh_group(dh); 260: this->payload_length += this->key_exchange_data.len; 261: 262: return &this->public; 263: }