Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/transform_attribute.c, revision 1.1.1.1

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 <string.h>
                     19: #include <stddef.h>
                     20: #include <stdint.h>
                     21: 
                     22: #include "transform_attribute.h"
                     23: 
                     24: #include <encoding/payloads/encodings.h>
                     25: #include <library.h>
                     26: 
                     27: ENUM(tattr_ph1_names, TATTR_PH1_ENCRYPTION_ALGORITHM, TATTR_PH1_GROUP_ORDER,
                     28:        "ENCRYPTION_ALGORITHM",
                     29:        "HASH_ALGORITHM",
                     30:        "AUTH_METHOD",
                     31:        "GROUP",
                     32:        "GROUP_TYPE",
                     33:        "GROUP_PRIME",
                     34:        "GROUP_GENONE",
                     35:        "GROUP_GENTWO",
                     36:        "GROUP_CURVE_A",
                     37:        "GROUP_CURVE_B",
                     38:        "LIFE_TYPE",
                     39:        "LIFE_DURATION",
                     40:        "PRF",
                     41:        "KEY_LENGTH",
                     42:        "FIELD_SIZE",
                     43:        "GROUP_ORDER",
                     44: );
                     45: 
                     46: ENUM(tattr_ph2_names, TATTR_PH2_SA_LIFE_TYPE, TATTR_PH2_EXT_SEQ_NUMBER,
                     47:        "SA_LIFE_TYPE",
                     48:        "SA_LIFE_DURATION",
                     49:        "GROUP",
                     50:        "ENCAP_MODE",
                     51:        "AUTH_ALGORITHM",
                     52:        "KEY_LENGTH",
                     53:        "KEY_ROUNDS",
                     54:        "COMP_DICT_SIZE",
                     55:        "COMP_PRIV_ALGORITHM",
                     56:        "ECN_TUNNEL",
                     57:        "EXT_SEQ_NUMBER",
                     58: );
                     59: 
                     60: ENUM(tattr_ikev2_names, TATTR_IKEV2_KEY_LENGTH, TATTR_IKEV2_KEY_LENGTH,
                     61:        "KEY_LENGTH",
                     62: );
                     63: 
                     64: 
                     65: typedef struct private_transform_attribute_t private_transform_attribute_t;
                     66: 
                     67: /**
                     68:  * Private data of an transform_attribute_t object.
                     69:  */
                     70: struct private_transform_attribute_t {
                     71: 
                     72:        /**
                     73:         * Public transform_attribute_t interface.
                     74:         */
                     75:        transform_attribute_t public;
                     76: 
                     77:        /**
                     78:         * Attribute Format Flag.
                     79:         *
                     80:         * - TRUE means value is stored in attribute_length_or_value
                     81:         * - FALSE means value is stored in attribute_value
                     82:         */
                     83:        bool attribute_format;
                     84: 
                     85:        /**
                     86:         * Type of the attribute.
                     87:         */
                     88:        uint16_t attribute_type;
                     89: 
                     90:        /**
                     91:         * Attribute Length if attribute_format is 0, attribute Value otherwise.
                     92:         */
                     93:        uint16_t attribute_length_or_value;
                     94: 
                     95:        /**
                     96:         * Attribute value as chunk if attribute_format is 0 (FALSE).
                     97:         */
                     98:        chunk_t attribute_value;
                     99: 
                    100:        /**
                    101:         * Payload type, PLV2_TRANSFORM_ATTRIBUTE or PLV1_TRANSFORM_ATTRIBUTE
                    102:         */
                    103:        payload_type_t type;
                    104: };
                    105: 
                    106: /**
                    107:  * Encoding rules for IKEv1/IKEv2 transform attributes
                    108:  */
                    109: static encoding_rule_t encodings[] = {
                    110:        /* Flag defining the format of this payload */
                    111:        { ATTRIBUTE_FORMAT,                     offsetof(private_transform_attribute_t, attribute_format)                       },
                    112:        /* type of the attribute as 15 bit unsigned integer */
                    113:        { ATTRIBUTE_TYPE,                       offsetof(private_transform_attribute_t, attribute_type)                         },
                    114:        /* Length or value, depending on the attribute format flag */
                    115:        { ATTRIBUTE_LENGTH_OR_VALUE,offsetof(private_transform_attribute_t, attribute_length_or_value)  },
                    116:        /* Value of attribute if attribute format flag is zero */
                    117:        { ATTRIBUTE_VALUE,                      offsetof(private_transform_attribute_t, attribute_value)                        }
                    118: };
                    119: 
                    120: /*
                    121:                           1                   2                   3
                    122:        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
                    123:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    124:       !A!       Attribute Type        !    AF=0  Attribute Length     !
                    125:       !F!                             !    AF=1  Attribute Value      !
                    126:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    127:       !                   AF=0  Attribute Value                       !
                    128:       !                   AF=1  Not Transmitted                       !
                    129:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    130: */
                    131: 
                    132: METHOD(payload_t, verify, status_t,
                    133:        private_transform_attribute_t *this)
                    134: {
                    135:        return SUCCESS;
                    136: }
                    137: 
                    138: METHOD(payload_t, get_encoding_rules, int,
                    139:        private_transform_attribute_t *this, encoding_rule_t **rules)
                    140: {
                    141:        *rules = encodings;
                    142:        return countof(encodings);
                    143: }
                    144: 
                    145: METHOD(payload_t, get_header_length, int,
                    146:        private_transform_attribute_t *this)
                    147: {
                    148:        return 0;
                    149: }
                    150: 
                    151: METHOD(payload_t, get_type, payload_type_t,
                    152:        private_transform_attribute_t *this)
                    153: {
                    154:        return this->type;
                    155: }
                    156: 
                    157: METHOD(payload_t, get_next_type, payload_type_t,
                    158:        private_transform_attribute_t *this)
                    159: {
                    160:        return PL_NONE;
                    161: }
                    162: 
                    163: METHOD(payload_t, set_next_type, void,
                    164:        private_transform_attribute_t *this, payload_type_t type)
                    165: {
                    166: }
                    167: 
                    168: METHOD(payload_t, get_length, size_t,
                    169:        private_transform_attribute_t *this)
                    170: {
                    171:        if (this->attribute_format)
                    172:        {
                    173:                return 4;
                    174:        }
                    175:        return this->attribute_length_or_value + 4;
                    176: }
                    177: 
                    178: METHOD(transform_attribute_t, get_value_chunk, chunk_t,
                    179:        private_transform_attribute_t *this)
                    180: {
                    181:        if (this->attribute_format)
                    182:        {
                    183:                return chunk_from_thing(this->attribute_length_or_value);
                    184:        }
                    185:        return this->attribute_value;
                    186: }
                    187: 
                    188: METHOD(transform_attribute_t, get_value, uint64_t,
                    189:        private_transform_attribute_t *this)
                    190: {
                    191:        uint64_t value = 0;
                    192: 
                    193:        if (this->attribute_format)
                    194:        {
                    195:                return this->attribute_length_or_value;
                    196:        }
                    197:        if (this->attribute_value.len > sizeof(value))
                    198:        {
                    199:                return UINT64_MAX;
                    200:        }
                    201:        memcpy(((char*)&value) + sizeof(value) - this->attribute_value.len,
                    202:                   this->attribute_value.ptr, this->attribute_value.len);
                    203:        return untoh64((char*)&value);
                    204: }
                    205: 
                    206: METHOD(transform_attribute_t, get_attribute_type, uint16_t,
                    207:        private_transform_attribute_t *this)
                    208: {
                    209:        return this->attribute_type;
                    210: }
                    211: 
                    212: METHOD2(payload_t, transform_attribute_t, destroy, void,
                    213:        private_transform_attribute_t *this)
                    214: {
                    215:        free(this->attribute_value.ptr);
                    216:        free(this);
                    217: }
                    218: 
                    219: /*
                    220:  * Described in header.
                    221:  */
                    222: transform_attribute_t *transform_attribute_create(payload_type_t type)
                    223: {
                    224:        private_transform_attribute_t *this;
                    225: 
                    226:        INIT(this,
                    227:                .public = {
                    228:                        .payload_interface = {
                    229:                                .verify = _verify,
                    230:                                .get_encoding_rules = _get_encoding_rules,
                    231:                                .get_header_length = _get_header_length,
                    232:                                .get_length = _get_length,
                    233:                                .get_next_type = _get_next_type,
                    234:                                .set_next_type = _set_next_type,
                    235:                                .get_type = _get_type,
                    236:                                .destroy = _destroy,
                    237:                        },
                    238:                        .get_value_chunk = _get_value_chunk,
                    239:                        .get_value = _get_value,
                    240:                        .get_attribute_type = _get_attribute_type,
                    241:                        .destroy = _destroy,
                    242:                },
                    243:                .attribute_format = FALSE,
                    244:                .type = type,
                    245:        );
                    246:        return &this->public;
                    247: }
                    248: 
                    249: /*
                    250:  * Described in header.
                    251:  */
                    252: transform_attribute_t *transform_attribute_create_value(payload_type_t type,
                    253:                                                        transform_attribute_type_t kind, uint64_t value)
                    254: {
                    255:        private_transform_attribute_t *this;
                    256: 
                    257:        this = (private_transform_attribute_t*)transform_attribute_create(type);
                    258: 
                    259:        this->attribute_type = kind & 0x7FFF;
                    260: 
                    261:        if (value <= UINT16_MAX)
                    262:        {
                    263:                this->attribute_length_or_value = value;
                    264:                this->attribute_format = TRUE;
                    265:        }
                    266:        else if (value <= UINT32_MAX)
                    267:        {
                    268:                uint32_t val32;
                    269: 
                    270:                val32 = htonl(value);
                    271:                this->attribute_value = chunk_clone(chunk_from_thing(val32));
                    272:                this->attribute_length_or_value = sizeof(val32);
                    273:        }
                    274:        else
                    275:        {
                    276:                htoun64(&value, value);
                    277:                this->attribute_value = chunk_clone(chunk_from_thing(value));
                    278:                this->attribute_length_or_value = sizeof(value);
                    279:        }
                    280:        return &this->public;
                    281: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>