Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/notify_payload.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2006-2018 Tobias Brunner
        !             3:  * Copyright (C) 2005-2010 Martin Willi
        !             4:  * Copyright (C) 2010 revosec AG
        !             5:  * Copyright (C) 2006 Daniel Roethlisberger
        !             6:  * Copyright (C) 2005 Jan Hutter
        !             7:  * HSR Hochschule fuer Technik Rapperswil
        !             8:  *
        !             9:  * This program is free software; you can redistribute it and/or modify it
        !            10:  * under the terms of the GNU General Public License as published by the
        !            11:  * Free Software Foundation; either version 2 of the License, or (at your
        !            12:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            13:  *
        !            14:  * This program is distributed in the hope that it will be useful, but
        !            15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            16:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            17:  * for more details.
        !            18:  */
        !            19: 
        !            20: #include <stddef.h>
        !            21: 
        !            22: #include "notify_payload.h"
        !            23: 
        !            24: #include <daemon.h>
        !            25: #include <encoding/payloads/encodings.h>
        !            26: #include <crypto/hashers/hasher.h>
        !            27: 
        !            28: ENUM_BEGIN(notify_type_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
        !            29:        "UNSUPPORTED_CRITICAL_PAYLOAD");
        !            30: ENUM_NEXT(notify_type_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
        !            31:        "INVALID_IKE_SPI",
        !            32:        "INVALID_MAJOR_VERSION");
        !            33: ENUM_NEXT(notify_type_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
        !            34:        "INVALID_SYNTAX");
        !            35: ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
        !            36:        "INVALID_MESSAGE_ID");
        !            37: ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
        !            38:        "INVALID_SPI");
        !            39: ENUM_NEXT(notify_type_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
        !            40:        "ATTRIBUTES_NOT_SUPPORTED",
        !            41:        "NO_PROPOSAL_CHOSEN");
        !            42: ENUM_NEXT(notify_type_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
        !            43:        "PAYLOAD_MALFORMED",
        !            44:        "INVALID_KE_PAYLOAD",
        !            45:        "INVALID_ID_INFORMATION",
        !            46:        "INVALID_CERT_ENCODING",
        !            47:        "INVALID_CERTIFICATE",
        !            48:        "CERT_TYPE_UNSUPPORTED",
        !            49:        "INVALID_CERT_AUTHORITY",
        !            50:        "INVALID_HASH_INFORMATION",
        !            51:        "AUTHENTICATION_FAILED");
        !            52: ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
        !            53:        "SINGLE_PAIR_REQUIRED",
        !            54:        "NO_ADDITIONAL_SAS",
        !            55:        "INTERNAL_ADDRESS_FAILURE",
        !            56:        "FAILED_CP_REQUIRED",
        !            57:        "TS_UNACCEPTABLE",
        !            58:        "INVALID_SELECTORS",
        !            59:        "UNACCEPTABLE_ADDRESSES",
        !            60:        "UNEXPECTED_NAT_DETECTED",
        !            61:        "USE_ASSIGNED_HoA",
        !            62:        "TEMPORARY_FAILURE",
        !            63:        "CHILD_SA_NOT_FOUND");
        !            64: ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
        !            65:        "ME_CONNECT_FAILED");
        !            66: ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
        !            67:        "MS_NOTIFY_STATUS");
        !            68: ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
        !            69:        "INITIAL_CONTACT",
        !            70:        "SET_WINDOW_SIZE",
        !            71:        "ADDITIONAL_TS_POSSIBLE",
        !            72:        "IPCOMP_SUPPORTED",
        !            73:        "NAT_DETECTION_SOURCE_IP",
        !            74:        "NAT_DETECTION_DESTINATION_IP",
        !            75:        "COOKIE",
        !            76:        "USE_TRANSPORT_MODE",
        !            77:        "HTTP_CERT_LOOKUP_SUPPORTED",
        !            78:        "REKEY_SA",
        !            79:        "ESP_TFC_PADDING_NOT_SUPPORTED",
        !            80:        "NON_FIRST_FRAGMENTS_ALSO",
        !            81:        "MOBIKE_SUPPORTED",
        !            82:        "ADDITIONAL_IP4_ADDRESS",
        !            83:        "ADDITIONAL_IP6_ADDRESS",
        !            84:        "NO_ADDITIONAL_ADDRESSES",
        !            85:        "UPDATE_SA_ADDRESSES",
        !            86:        "COOKIE2",
        !            87:        "NO_NATS_ALLOWED",
        !            88:        "AUTH_LIFETIME",
        !            89:        "MULTIPLE_AUTH_SUPPORTED",
        !            90:        "ANOTHER_AUTH_FOLLOWS",
        !            91:        "REDIRECT_SUPPORTED",
        !            92:        "REDIRECT",
        !            93:        "REDIRECTED_FROM",
        !            94:        "TICKET_LT_OPAQUE",
        !            95:        "TICKET_REQUEST",
        !            96:        "TICKET_ACK",
        !            97:        "TICKET_NACK",
        !            98:        "TICKET_OPAQUE",
        !            99:        "LINK_ID",
        !           100:        "USE_WESP_MODE",
        !           101:        "ROHC_SUPPORTED",
        !           102:        "EAP_ONLY_AUTHENTICATION",
        !           103:        "CHILDLESS_IKEV2_SUPPORTED",
        !           104:        "QUICK_CRASH_DETECTION",
        !           105:        "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
        !           106:        "IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED",
        !           107:        "IKEV2_MESSAGE_ID_SYNC",
        !           108:        "IPSEC_REPLAY_COUNTER_SYNC",
        !           109:        "SECURE PASSWORD_METHOD",
        !           110:        "PSK_PERSIST",
        !           111:        "PSK_CONFIRM",
        !           112:        "ERX_SUPPORTED",
        !           113:        "IFOM_CAPABILITY",
        !           114:        "SENDER_REQUEST_ID",
        !           115:        "FRAGMENTATION_SUPPORTED",
        !           116:        "SIGNATURE_HASH_ALGORITHMS");
        !           117: ENUM_NEXT(notify_type_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
        !           118:        "USE_PPK",
        !           119:        "PPK_IDENTITY",
        !           120:        "NO_PPK_AUTH");
        !           121: ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
        !           122:        "INITIAL_CONTACT");
        !           123: ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
        !           124:        "DPD_R_U_THERE",
        !           125:        "DPD_R_U_THERE_ACK");
        !           126: ENUM_NEXT(notify_type_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
        !           127:        "UNITY_LOAD_BALANCE");
        !           128: ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
        !           129:        "USE_BEET_MODE");
        !           130: ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
        !           131:        "ME_MEDIATION",
        !           132:        "ME_ENDPOINT",
        !           133:        "ME_CALLBACK",
        !           134:        "ME_CONNECTID",
        !           135:        "ME_CONNECTKEY",
        !           136:        "ME_CONNECTAUTH",
        !           137:        "ME_RESPONSE",
        !           138:        "RADIUS_ATTRIBUTE");
        !           139: ENUM_END(notify_type_names, RADIUS_ATTRIBUTE);
        !           140: 
        !           141: 
        !           142: ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
        !           143:        "CRIT");
        !           144: ENUM_NEXT(notify_type_short_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
        !           145:        "INVAL_IKE_SPI",
        !           146:        "INVAL_MAJOR");
        !           147: ENUM_NEXT(notify_type_short_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
        !           148:        "INVAL_SYN");
        !           149: ENUM_NEXT(notify_type_short_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
        !           150:        "INVAL_MID");
        !           151: ENUM_NEXT(notify_type_short_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
        !           152:        "INVAL_SPI");
        !           153: ENUM_NEXT(notify_type_short_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
        !           154:        "ATTR_UNSUP",
        !           155:        "NO_PROP");
        !           156: ENUM_NEXT(notify_type_short_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
        !           157:        "PLD_MAL",
        !           158:        "INVAL_KE",
        !           159:        "INVAL_ID",
        !           160:        "INVAL_CERTEN",
        !           161:        "INVAL_CERT",
        !           162:        "CERT_UNSUP",
        !           163:        "INVAL_CA",
        !           164:        "INVAL_HASH",
        !           165:        "AUTH_FAILED");
        !           166: ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
        !           167:        "SINGLE_PAIR",
        !           168:        "NO_ADD_SAS",
        !           169:        "INT_ADDR_FAIL",
        !           170:        "FAIL_CP_REQ",
        !           171:        "TS_UNACCEPT",
        !           172:        "INVAL_SEL",
        !           173:        "UNACCEPT_ADDR",
        !           174:        "UNEXPECT_NAT",
        !           175:        "ASSIGNED_HoA",
        !           176:        "TEMP_FAIL",
        !           177:        "NO_CHILD_SA");
        !           178: ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
        !           179:        "ME_CONN_FAIL");
        !           180: ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
        !           181:        "MS_STATUS");
        !           182: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
        !           183:        "INIT_CONTACT",
        !           184:        "SET_WINSIZE",
        !           185:        "ADD_TS_POSS",
        !           186:        "IPCOMP_SUP",
        !           187:        "NATD_S_IP",
        !           188:        "NATD_D_IP",
        !           189:        "COOKIE",
        !           190:        "USE_TRANSP",
        !           191:        "HTTP_CERT_LOOK",
        !           192:        "REKEY_SA",
        !           193:        "ESP_TFC_PAD_N",
        !           194:        "NON_FIRST_FRAG",
        !           195:        "MOBIKE_SUP",
        !           196:        "ADD_4_ADDR",
        !           197:        "ADD_6_ADDR",
        !           198:        "NO_ADD_ADDR",
        !           199:        "UPD_SA_ADDR",
        !           200:        "COOKIE2",
        !           201:        "NO_NATS",
        !           202:        "AUTH_LFT",
        !           203:        "MULT_AUTH",
        !           204:        "AUTH_FOLLOWS",
        !           205:        "REDIR_SUP",
        !           206:        "REDIR",
        !           207:        "REDIR_FROM",
        !           208:        "TKT_LT_OPAK",
        !           209:        "TKT_REQ",
        !           210:        "TKT_ACK",
        !           211:        "TKT_NACK",
        !           212:        "TKT_OPAK",
        !           213:        "LINK_ID",
        !           214:        "WESP_MODE",
        !           215:        "ROHC_SUP",
        !           216:        "EAP_ONLY",
        !           217:        "CHDLESS_SUP",
        !           218:        "CRASH_DET",
        !           219:        "MSG_ID_SYN_SUP",
        !           220:        "RPL_CTR_SYN_SUP",
        !           221:        "MSG_ID_SYN",
        !           222:        "RPL_CTR_SYN",
        !           223:        "SEC_PASSWD",
        !           224:        "PSK_PST",
        !           225:        "PSK_CFM",
        !           226:        "ERX_SUP",
        !           227:        "IFOM_CAP",
        !           228:        "SENDER_REQ_ID",
        !           229:        "FRAG_SUP",
        !           230:        "HASH_ALG");
        !           231: ENUM_NEXT(notify_type_short_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
        !           232:        "USE_PPK",
        !           233:        "PPK_ID",
        !           234:        "NO_PPK");
        !           235: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
        !           236:        "INITIAL_CONTACT");
        !           237: ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
        !           238:        "DPD",
        !           239:        "DPD_ACK");
        !           240: ENUM_NEXT(notify_type_short_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
        !           241:        "UNITY_LB");
        !           242: ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
        !           243:        "BEET_MODE");
        !           244: ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
        !           245:        "ME_MED",
        !           246:        "ME_EP",
        !           247:        "ME_CB",
        !           248:        "ME_CID",
        !           249:        "ME_CKEY",
        !           250:        "ME_CAUTH",
        !           251:        "ME_R",
        !           252:        "RADIUS");
        !           253: ENUM_END(notify_type_short_names, RADIUS_ATTRIBUTE);
        !           254: 
        !           255: 
        !           256: typedef struct private_notify_payload_t private_notify_payload_t;
        !           257: 
        !           258: /**
        !           259:  * Private data of an notify_payload_t object.
        !           260:  */
        !           261: struct private_notify_payload_t {
        !           262: 
        !           263:        /**
        !           264:         * Public notify_payload_t interface.
        !           265:         */
        !           266:        notify_payload_t public;
        !           267: 
        !           268:        /**
        !           269:         * Next payload type.
        !           270:         */
        !           271:        uint8_t  next_payload;
        !           272: 
        !           273:        /**
        !           274:         * Critical flag.
        !           275:         */
        !           276:        bool critical;
        !           277: 
        !           278:        /**
        !           279:         * reserved bits
        !           280:         */
        !           281:        bool reserved[8];
        !           282: 
        !           283:        /**
        !           284:         * Length of this payload.
        !           285:         */
        !           286:        uint16_t payload_length;
        !           287: 
        !           288:        /**
        !           289:         * Domain of interpretation, IKEv1 only.
        !           290:         */
        !           291:        uint32_t doi;
        !           292: 
        !           293:        /**
        !           294:         * Protocol id.
        !           295:         */
        !           296:        uint8_t protocol_id;
        !           297: 
        !           298:        /**
        !           299:         * Spi size.
        !           300:         */
        !           301:        uint8_t spi_size;
        !           302: 
        !           303:        /**
        !           304:         * Notify message type.
        !           305:         */
        !           306:        uint16_t notify_type;
        !           307: 
        !           308:        /**
        !           309:         * Security parameter index (spi).
        !           310:         */
        !           311:        chunk_t spi;
        !           312: 
        !           313:        /**
        !           314:         * Notification data.
        !           315:         */
        !           316:        chunk_t notify_data;
        !           317: 
        !           318:        /**
        !           319:         * Type of payload, PLV2_NOTIFY or PLV1_NOTIFY
        !           320:         */
        !           321:        payload_type_t type;
        !           322: };
        !           323: 
        !           324: /**
        !           325:  * Encoding rules for an IKEv2 notification payload
        !           326:  */
        !           327: static encoding_rule_t encodings_v2[] = {
        !           328:        /* 1 Byte next payload type, stored in the field next_payload */
        !           329:        { U_INT_8,                      offsetof(private_notify_payload_t, next_payload)        },
        !           330:        /* the critical bit */
        !           331:        { FLAG,                         offsetof(private_notify_payload_t, critical)            },
        !           332:        /* 7 Bit reserved bits, nowhere stored */
        !           333:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[0])         },
        !           334:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[1])         },
        !           335:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[2])         },
        !           336:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[3])         },
        !           337:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[4])         },
        !           338:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[5])         },
        !           339:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[6])         },
        !           340:        /* Length of the whole payload*/
        !           341:        { PAYLOAD_LENGTH,       offsetof(private_notify_payload_t, payload_length)      },
        !           342:        /* Protocol ID as 8 bit field*/
        !           343:        { U_INT_8,                      offsetof(private_notify_payload_t, protocol_id)         },
        !           344:        /* SPI Size as 8 bit field*/
        !           345:        { SPI_SIZE,                     offsetof(private_notify_payload_t, spi_size)            },
        !           346:        /* Notify message type as 16 bit field*/
        !           347:        { U_INT_16,                     offsetof(private_notify_payload_t, notify_type)         },
        !           348:        /* SPI as variable length field*/
        !           349:        { SPI,                          offsetof(private_notify_payload_t, spi)                         },
        !           350:        /* Key Exchange Data is from variable size */
        !           351:        { CHUNK_DATA,           offsetof(private_notify_payload_t, notify_data)         },
        !           352: };
        !           353: 
        !           354: /*
        !           355:                            1                   2                   3
        !           356:        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
        !           357:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           358:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
        !           359:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           360:       !  Protocol ID  !   SPI Size    !      Notify Message Type      !
        !           361:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           362:       !                                                               !
        !           363:       ~                Security Parameter Index (SPI)                 ~
        !           364:       !                                                               !
        !           365:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           366:       !                                                               !
        !           367:       ~                       Notification Data                       ~
        !           368:       !                                                               !
        !           369:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           370: */
        !           371: /**
        !           372:  * Encoding rules for an IKEv1 notification payload
        !           373:  */
        !           374: static encoding_rule_t encodings_v1[] = {
        !           375:        /* 1 Byte next payload type, stored in the field next_payload */
        !           376:        { U_INT_8,                      offsetof(private_notify_payload_t, next_payload)        },
        !           377:        /* 8 reserved bits */
        !           378:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[0])         },
        !           379:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[1])         },
        !           380:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[2])         },
        !           381:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[3])         },
        !           382:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[4])         },
        !           383:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[5])         },
        !           384:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[6])         },
        !           385:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[7])         },
        !           386:        /* Length of the whole payload*/
        !           387:        { PAYLOAD_LENGTH,       offsetof(private_notify_payload_t, payload_length)      },
        !           388:        /* DOI as  32 bit field*/
        !           389:        { U_INT_32,                     offsetof(private_notify_payload_t, doi)                         },
        !           390:        /* Protocol ID as 8 bit field*/
        !           391:        { U_INT_8,                      offsetof(private_notify_payload_t, protocol_id)         },
        !           392:        /* SPI Size as 8 bit field*/
        !           393:        { SPI_SIZE,                     offsetof(private_notify_payload_t, spi_size)            },
        !           394:        /* Notify message type as 16 bit field*/
        !           395:        { U_INT_16,                     offsetof(private_notify_payload_t, notify_type)         },
        !           396:        /* SPI as variable length field*/
        !           397:        { SPI,                          offsetof(private_notify_payload_t, spi)                         },
        !           398:        /* Key Exchange Data is from variable size */
        !           399:        { CHUNK_DATA,           offsetof(private_notify_payload_t, notify_data)         },
        !           400: };
        !           401: 
        !           402: /*
        !           403:                            1                   2                   3
        !           404:        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
        !           405:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           406:       ! Next Payload  !    RESERVED   !         Payload Length        !
        !           407:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           408:       !                             DOI                               !
        !           409:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           410:       !  Protocol ID  !   SPI Size    !      Notify Message Type      !
        !           411:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           412:       !                                                               !
        !           413:       ~                Security Parameter Index (SPI)                 ~
        !           414:       !                                                               !
        !           415:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           416:       !                                                               !
        !           417:       ~                       Notification Data                       ~
        !           418:       !                                                               !
        !           419:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           420: */
        !           421: 
        !           422: 
        !           423: METHOD(payload_t, verify, status_t,
        !           424:        private_notify_payload_t *this)
        !           425: {
        !           426:        bool bad_length = FALSE;
        !           427: 
        !           428:        switch (this->protocol_id)
        !           429:        {
        !           430:                case PROTO_NONE:
        !           431:                case PROTO_IKE:
        !           432:                case PROTO_AH:
        !           433:                case PROTO_ESP:
        !           434:                        break;
        !           435:                default:
        !           436:                        DBG1(DBG_ENC, "Unknown protocol (%d)", this->protocol_id);
        !           437:                        return FAILED;
        !           438:        }
        !           439: 
        !           440:        switch (this->notify_type)
        !           441:        {
        !           442:                case INVALID_KE_PAYLOAD:
        !           443:                {
        !           444:                        if (this->type == PLV2_NOTIFY && this->notify_data.len != 2)
        !           445:                        {
        !           446:                                bad_length = TRUE;
        !           447:                        }
        !           448:                        break;
        !           449:                }
        !           450:                case NAT_DETECTION_SOURCE_IP:
        !           451:                case NAT_DETECTION_DESTINATION_IP:
        !           452:                case ME_CONNECTAUTH:
        !           453:                {
        !           454:                        if (this->notify_data.len != HASH_SIZE_SHA1)
        !           455:                        {
        !           456:                                bad_length = TRUE;
        !           457:                        }
        !           458:                        break;
        !           459:                }
        !           460:                case INVALID_SYNTAX:
        !           461:                case INVALID_MAJOR_VERSION:
        !           462:                case NO_PROPOSAL_CHOSEN:
        !           463:                {
        !           464:                        if (this->type == PLV2_NOTIFY && this->notify_data.len != 0)
        !           465:                        {
        !           466:                                bad_length = TRUE;
        !           467:                        }
        !           468:                        break;
        !           469:                }
        !           470:                case COOKIE:
        !           471:                {
        !           472:                        if (this->notify_data.len < 1 || this->notify_data.len > 64)
        !           473:                        {
        !           474:                                bad_length = TRUE;
        !           475:                        }
        !           476:                        break;
        !           477:                }
        !           478:                case ADDITIONAL_IP4_ADDRESS:
        !           479:                {
        !           480:                        if (this->notify_data.len != 4)
        !           481:                        {
        !           482:                                bad_length = TRUE;
        !           483:                        }
        !           484:                        break;
        !           485:                }
        !           486:                case ADDITIONAL_IP6_ADDRESS:
        !           487:                {
        !           488:                        if (this->notify_data.len != 16)
        !           489:                        {
        !           490:                                bad_length = TRUE;
        !           491:                        }
        !           492:                        break;
        !           493:                }
        !           494:                case SIGNATURE_HASH_ALGORITHMS:
        !           495:                {
        !           496:                        if (this->notify_data.len % 2)
        !           497:                        {
        !           498:                                bad_length = TRUE;
        !           499:                        }
        !           500:                        break;
        !           501:                }
        !           502:                case AUTH_LIFETIME:
        !           503:                {
        !           504:                        if (this->notify_data.len != 4)
        !           505:                        {
        !           506:                                bad_length = TRUE;
        !           507:                        }
        !           508:                        break;
        !           509:                }
        !           510:                case IPCOMP_SUPPORTED:
        !           511:                {
        !           512:                        if (this->notify_data.len != 3)
        !           513:                        {
        !           514:                                bad_length = TRUE;
        !           515:                        }
        !           516:                        break;
        !           517:                }
        !           518:                case ME_ENDPOINT:
        !           519:                        if (this->notify_data.len != 8 &&
        !           520:                                this->notify_data.len != 12 &&
        !           521:                                this->notify_data.len != 24)
        !           522:                        {
        !           523:                                bad_length = TRUE;
        !           524:                        }
        !           525:                        break;
        !           526:                case ME_CONNECTID:
        !           527:                        if (this->notify_data.len < 4 ||
        !           528:                                this->notify_data.len > 16)
        !           529:                        {
        !           530:                                bad_length = TRUE;
        !           531:                        }
        !           532:                        break;
        !           533:                case ME_CONNECTKEY:
        !           534:                        if (this->notify_data.len < 16 ||
        !           535:                                this->notify_data.len > 32)
        !           536:                        {
        !           537:                                bad_length = TRUE;
        !           538:                        }
        !           539:                        break;
        !           540:                case DPD_R_U_THERE:
        !           541:                case DPD_R_U_THERE_ACK:
        !           542:                        if (this->notify_data.len != 4)
        !           543:                        {
        !           544:                                bad_length = TRUE;
        !           545:                        }
        !           546:                        break;
        !           547:                default:
        !           548:                        /* TODO: verify */
        !           549:                        break;
        !           550:        }
        !           551:        if (bad_length)
        !           552:        {
        !           553:                DBG1(DBG_ENC, "invalid notify data length for %N (%d)",
        !           554:                         notify_type_names, this->notify_type,
        !           555:                         this->notify_data.len);
        !           556:                return FAILED;
        !           557:        }
        !           558:        return SUCCESS;
        !           559: }
        !           560: 
        !           561: METHOD(payload_t, get_encoding_rules, int,
        !           562:        private_notify_payload_t *this, encoding_rule_t **rules)
        !           563: {
        !           564:        if (this->type == PLV2_NOTIFY)
        !           565:        {
        !           566:                *rules = encodings_v2;
        !           567:                return countof(encodings_v2);
        !           568:        }
        !           569:        *rules = encodings_v1;
        !           570:        return countof(encodings_v1);
        !           571: }
        !           572: 
        !           573: METHOD(payload_t, get_header_length, int,
        !           574:        private_notify_payload_t *this)
        !           575: {
        !           576:        if (this->type == PLV2_NOTIFY)
        !           577:        {
        !           578:                return 8 + this->spi_size;
        !           579:        }
        !           580:        return 12 + this->spi_size;
        !           581: }
        !           582: 
        !           583: METHOD(payload_t, get_type, payload_type_t,
        !           584:        private_notify_payload_t *this)
        !           585: {
        !           586:        return this->type;
        !           587: }
        !           588: 
        !           589: METHOD(payload_t, get_next_type, payload_type_t,
        !           590:        private_notify_payload_t *this)
        !           591: {
        !           592:        return this->next_payload;
        !           593: }
        !           594: 
        !           595: METHOD(payload_t, set_next_type, void,
        !           596:        private_notify_payload_t *this, payload_type_t type)
        !           597: {
        !           598:        this->next_payload = type;
        !           599: }
        !           600: 
        !           601: /**
        !           602:  * recompute the payloads length.
        !           603:  */
        !           604: static void compute_length(private_notify_payload_t *this)
        !           605: {
        !           606:        this->payload_length = get_header_length(this) + this->notify_data.len;
        !           607: }
        !           608: 
        !           609: METHOD(payload_t, get_length, size_t,
        !           610:        private_notify_payload_t *this)
        !           611: {
        !           612:        return this->payload_length;
        !           613: }
        !           614: 
        !           615: METHOD(notify_payload_t, get_protocol_id, uint8_t,
        !           616:        private_notify_payload_t *this)
        !           617: {
        !           618:        return this->protocol_id;
        !           619: }
        !           620: 
        !           621: METHOD(notify_payload_t, set_protocol_id, void,
        !           622:        private_notify_payload_t *this, uint8_t protocol_id)
        !           623: {
        !           624:        this->protocol_id = protocol_id;
        !           625: }
        !           626: 
        !           627: METHOD(notify_payload_t, get_notify_type, notify_type_t,
        !           628:        private_notify_payload_t *this)
        !           629: {
        !           630:        return this->notify_type;
        !           631: }
        !           632: 
        !           633: METHOD(notify_payload_t, set_notify_type, void,
        !           634:        private_notify_payload_t *this, notify_type_t notify_type)
        !           635: {
        !           636:        this->notify_type = notify_type;
        !           637: }
        !           638: 
        !           639: METHOD(notify_payload_t, get_spi, uint32_t,
        !           640:        private_notify_payload_t *this)
        !           641: {
        !           642:        switch (this->protocol_id)
        !           643:        {
        !           644:                case PROTO_AH:
        !           645:                case PROTO_ESP:
        !           646:                        if (this->spi.len == 4)
        !           647:                        {
        !           648:                                return *((uint32_t*)this->spi.ptr);
        !           649:                        }
        !           650:                default:
        !           651:                        break;
        !           652:        }
        !           653:        return 0;
        !           654: }
        !           655: 
        !           656: METHOD(notify_payload_t, set_spi, void,
        !           657:        private_notify_payload_t *this, uint32_t spi)
        !           658: {
        !           659:        chunk_free(&this->spi);
        !           660:        switch (this->protocol_id)
        !           661:        {
        !           662:                case PROTO_AH:
        !           663:                case PROTO_ESP:
        !           664:                        this->spi = chunk_alloc(4);
        !           665:                        *((uint32_t*)this->spi.ptr) = spi;
        !           666:                        break;
        !           667:                default:
        !           668:                        break;
        !           669:        }
        !           670:        this->spi_size = this->spi.len;
        !           671:        compute_length(this);
        !           672: }
        !           673: 
        !           674: METHOD(notify_payload_t, get_spi_data, chunk_t,
        !           675:        private_notify_payload_t *this)
        !           676: {
        !           677:        switch (this->protocol_id)
        !           678:        {
        !           679:                case PROTO_IKE:
        !           680:                        if (this->spi.len == 16)
        !           681:                        {
        !           682:                                return this->spi;
        !           683:                        }
        !           684:                default:
        !           685:                        break;
        !           686:        }
        !           687:        return chunk_empty;
        !           688: }
        !           689: 
        !           690: METHOD(notify_payload_t, set_spi_data, void,
        !           691:        private_notify_payload_t *this, chunk_t spi)
        !           692: {
        !           693:        chunk_free(&this->spi);
        !           694:        switch (this->protocol_id)
        !           695:        {
        !           696:                case PROTO_IKE:
        !           697:                        this->spi = chunk_clone(spi);
        !           698:                default:
        !           699:                        break;
        !           700:        }
        !           701:        this->spi_size = this->spi.len;
        !           702:        compute_length(this);
        !           703: }
        !           704: 
        !           705: METHOD(notify_payload_t, get_notification_data, chunk_t,
        !           706:        private_notify_payload_t *this)
        !           707: {
        !           708:        return this->notify_data;
        !           709: }
        !           710: 
        !           711: METHOD(notify_payload_t, set_notification_data, void,
        !           712:        private_notify_payload_t *this, chunk_t data)
        !           713: {
        !           714:        free(this->notify_data.ptr);
        !           715:        this->notify_data = chunk_clone(data);
        !           716:        compute_length(this);
        !           717: }
        !           718: 
        !           719: METHOD2(payload_t, notify_payload_t, destroy, void,
        !           720:        private_notify_payload_t *this)
        !           721: {
        !           722:        free(this->notify_data.ptr);
        !           723:        free(this->spi.ptr);
        !           724:        free(this);
        !           725: }
        !           726: 
        !           727: /*
        !           728:  * Described in header
        !           729:  */
        !           730: notify_payload_t *notify_payload_create(payload_type_t type)
        !           731: {
        !           732:        private_notify_payload_t *this;
        !           733: 
        !           734:        INIT(this,
        !           735:                .public = {
        !           736:                        .payload_interface = {
        !           737:                                .verify = _verify,
        !           738:                                .get_encoding_rules = _get_encoding_rules,
        !           739:                                .get_header_length = _get_header_length,
        !           740:                                .get_length = _get_length,
        !           741:                                .get_next_type = _get_next_type,
        !           742:                                .set_next_type = _set_next_type,
        !           743:                                .get_type = _get_type,
        !           744:                                .destroy = _destroy,
        !           745:                        },
        !           746:                        .get_protocol_id = _get_protocol_id,
        !           747:                        .set_protocol_id  = _set_protocol_id,
        !           748:                        .get_notify_type = _get_notify_type,
        !           749:                        .set_notify_type = _set_notify_type,
        !           750:                        .get_spi = _get_spi,
        !           751:                        .set_spi = _set_spi,
        !           752:                        .get_spi_data = _get_spi_data,
        !           753:                        .set_spi_data = _set_spi_data,
        !           754:                        .get_notification_data = _get_notification_data,
        !           755:                        .set_notification_data = _set_notification_data,
        !           756:                        .destroy = _destroy,
        !           757:                },
        !           758:                .doi = IKEV1_DOI_IPSEC,
        !           759:                .next_payload = PL_NONE,
        !           760:                .type = type,
        !           761:        );
        !           762:        compute_length(this);
        !           763:        return &this->public;
        !           764: }
        !           765: 
        !           766: /*
        !           767:  * Described in header.
        !           768:  */
        !           769: notify_payload_t *notify_payload_create_from_protocol_and_type(
        !           770:                        payload_type_t type, protocol_id_t protocol, notify_type_t notify)
        !           771: {
        !           772:        notify_payload_t *this = notify_payload_create(type);
        !           773: 
        !           774:        this->set_notify_type(this, notify);
        !           775:        this->set_protocol_id(this, protocol);
        !           776: 
        !           777:        return this;
        !           778: }

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