Annotation of embedaddon/strongswan/src/libcharon/encoding/message.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 <stdlib.h>
        !            21: #include <string.h>
        !            22: 
        !            23: #include "message.h"
        !            24: 
        !            25: #include <library.h>
        !            26: #include <bio/bio_writer.h>
        !            27: #include <collections/array.h>
        !            28: #include <daemon.h>
        !            29: #include <sa/ikev1/keymat_v1.h>
        !            30: #include <encoding/generator.h>
        !            31: #include <encoding/parser.h>
        !            32: #include <encoding/payloads/encodings.h>
        !            33: #include <encoding/payloads/payload.h>
        !            34: #include <encoding/payloads/hash_payload.h>
        !            35: #include <encoding/payloads/encrypted_payload.h>
        !            36: #include <encoding/payloads/encrypted_fragment_payload.h>
        !            37: #include <encoding/payloads/unknown_payload.h>
        !            38: #include <encoding/payloads/cp_payload.h>
        !            39: #include <encoding/payloads/fragment_payload.h>
        !            40: 
        !            41: /**
        !            42:  * Max number of notify payloads per IKEv2 message
        !            43:  */
        !            44: #define MAX_NOTIFY_PAYLOADS 20
        !            45: 
        !            46: /**
        !            47:  * Max number of delete payloads per IKEv2 message
        !            48:  */
        !            49: #define MAX_DELETE_PAYLOADS 20
        !            50: 
        !            51: /**
        !            52:  * Max number of certificate payloads per IKEv2 message
        !            53:  */
        !            54: #define MAX_CERT_PAYLOADS 8
        !            55: 
        !            56: /**
        !            57:  * Max number of vendor ID payloads per IKEv2 message
        !            58:  */
        !            59: #define MAX_VID_PAYLOADS 20
        !            60: 
        !            61: /**
        !            62:  * Max number of certificate request payloads per IKEv1 message
        !            63:  */
        !            64: #define MAX_CERTREQ_PAYLOADS 20
        !            65: 
        !            66: /**
        !            67:  * Max number of NAT-D payloads per IKEv1 message
        !            68:  */
        !            69: #define MAX_NAT_D_PAYLOADS 10
        !            70: 
        !            71: /**
        !            72:  * A payload rule defines the rules for a payload
        !            73:  * in a specific message rule. It defines if and how
        !            74:  * many times a payload must/can occur in a message
        !            75:  * and if it must be encrypted.
        !            76:  */
        !            77: typedef struct {
        !            78:        /* Payload type */
        !            79:         payload_type_t type;
        !            80:        /* Minimal occurrence of this payload. */
        !            81:        size_t min_occurrence;
        !            82:        /* Max occurrence of this payload. */
        !            83:        size_t max_occurrence;
        !            84:        /* TRUE if payload must be encrypted */
        !            85:        bool encrypted;
        !            86:        /* If payload occurs, the message rule is fulfilled */
        !            87:        bool sufficient;
        !            88: } payload_rule_t;
        !            89: 
        !            90: /**
        !            91:  * payload ordering structure allows us to reorder payloads according to RFC.
        !            92:  */
        !            93: typedef struct {
        !            94:        /** payload type */
        !            95:        payload_type_t type;
        !            96:        /** notify type, if payload == PLV2_NOTIFY */
        !            97:        notify_type_t notify;
        !            98: } payload_order_t;
        !            99: 
        !           100: /**
        !           101:  * A message rule defines the kind of a message,
        !           102:  * if it has encrypted contents and a list
        !           103:  * of payload ordering rules and payload parsing rules.
        !           104:  */
        !           105: typedef struct {
        !           106:        /** Type of message. */
        !           107:        exchange_type_t exchange_type;
        !           108:        /** Is message a request or response. */
        !           109:        bool is_request;
        !           110:        /** Message contains encrypted payloads. */
        !           111:        bool encrypted;
        !           112:        /** Number of payload rules which will follow */
        !           113:        int rule_count;
        !           114:        /** Pointer to first payload rule */
        !           115:        payload_rule_t *rules;
        !           116:        /** Number of payload order rules */
        !           117:        int order_count;
        !           118:        /** payload ordering rules */
        !           119:        payload_order_t *order;
        !           120: } message_rule_t;
        !           121: 
        !           122: /**
        !           123:  * Message rule for IKE_SA_INIT from initiator.
        !           124:  */
        !           125: static payload_rule_t ike_sa_init_i_rules[] = {
        !           126: /*     payload type                                    min     max                                             encr    suff */
        !           127:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           128:        {PLV2_SECURITY_ASSOCIATION,             1,      1,                                              FALSE,  FALSE},
        !           129:        {PLV2_KEY_EXCHANGE,                             1,      1,                                              FALSE,  FALSE},
        !           130:        {PLV2_NONCE,                                    1,      1,                                              FALSE,  FALSE},
        !           131:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           132: };
        !           133: 
        !           134: /**
        !           135:  * payload order for IKE_SA_INIT initiator
        !           136:  */
        !           137: static payload_order_t ike_sa_init_i_order[] = {
        !           138: /*     payload type                                    notify type */
        !           139:        {PLV2_NOTIFY,                                   COOKIE},
        !           140:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           141:        {PLV2_KEY_EXCHANGE,                             0},
        !           142:        {PLV2_NONCE,                                    0},
        !           143:        {PLV2_NOTIFY,                                   NAT_DETECTION_SOURCE_IP},
        !           144:        {PLV2_NOTIFY,                                   NAT_DETECTION_DESTINATION_IP},
        !           145:        {PLV2_NOTIFY,                                   0},
        !           146:        {PLV2_VENDOR_ID,                                0},
        !           147: };
        !           148: 
        !           149: /**
        !           150:  * Message rule for IKE_SA_INIT from responder.
        !           151:  */
        !           152: static payload_rule_t ike_sa_init_r_rules[] = {
        !           153: /*     payload type                                    min     max                                             encr    suff */
        !           154:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  TRUE},
        !           155:        {PLV2_SECURITY_ASSOCIATION,             1,      1,                                              FALSE,  FALSE},
        !           156:        {PLV2_KEY_EXCHANGE,                             1,      1,                                              FALSE,  FALSE},
        !           157:        {PLV2_NONCE,                                    1,      1,                                              FALSE,  FALSE},
        !           158:        {PLV2_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   FALSE,  FALSE},
        !           159:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           160: };
        !           161: 
        !           162: /**
        !           163:  * payload order for IKE_SA_INIT responder
        !           164:  */
        !           165: static payload_order_t ike_sa_init_r_order[] = {
        !           166: /*     payload type                                    notify type */
        !           167:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           168:        {PLV2_KEY_EXCHANGE,                             0},
        !           169:        {PLV2_NONCE,                                    0},
        !           170:        {PLV2_NOTIFY,                                   NAT_DETECTION_SOURCE_IP},
        !           171:        {PLV2_NOTIFY,                                   NAT_DETECTION_DESTINATION_IP},
        !           172:        {PLV2_NOTIFY,                                   HTTP_CERT_LOOKUP_SUPPORTED},
        !           173:        {PLV2_CERTREQ,                                  0},
        !           174:        {PLV2_NOTIFY,                                   0},
        !           175:        {PLV2_VENDOR_ID,                                0},
        !           176: };
        !           177: 
        !           178: /**
        !           179:  * Message rule for IKE_AUTH from initiator.
        !           180:  */
        !           181: static payload_rule_t ike_auth_i_rules[] = {
        !           182: /*     payload type                                    min     max                                             encr    suff */
        !           183:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           184:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           185:        {PLV2_EAP,                                              0,      1,                                              TRUE,   TRUE},
        !           186:        {PLV2_AUTH,                                             0,      1,                                              TRUE,   TRUE},
        !           187:        {PLV2_ID_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           188:        {PLV2_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              TRUE,   FALSE},
        !           189:        {PLV2_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   TRUE,   FALSE},
        !           190:        {PLV2_ID_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           191: #ifdef ME
        !           192:        {PLV2_SECURITY_ASSOCIATION,             0,      1,                                              TRUE,   FALSE},
        !           193:        {PLV2_TS_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           194:        {PLV2_TS_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           195: #else
        !           196:        {PLV2_SECURITY_ASSOCIATION,             0,      1,                                              TRUE,   FALSE},
        !           197:        {PLV2_TS_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           198:        {PLV2_TS_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           199: #endif /* ME */
        !           200:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           201:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           202: };
        !           203: 
        !           204: /**
        !           205:  * payload order for IKE_AUTH initiator
        !           206:  */
        !           207: static payload_order_t ike_auth_i_order[] = {
        !           208: /*     payload type                                    notify type */
        !           209:        {PLV2_ID_INITIATOR,                             0},
        !           210:        {PLV2_CERTIFICATE,                              0},
        !           211:        {PLV2_NOTIFY,                                   INITIAL_CONTACT},
        !           212:        {PLV2_NOTIFY,                                   HTTP_CERT_LOOKUP_SUPPORTED},
        !           213:        {PLV2_CERTREQ,                                  0},
        !           214:        {PLV2_ID_RESPONDER,                             0},
        !           215:        {PLV2_AUTH,                                             0},
        !           216:        {PLV2_EAP,                                              0},
        !           217:        {PLV2_CONFIGURATION,                    0},
        !           218:        {PLV2_NOTIFY,                                   IPCOMP_SUPPORTED},
        !           219:        {PLV2_NOTIFY,                                   USE_TRANSPORT_MODE},
        !           220:        {PLV2_NOTIFY,                                   ESP_TFC_PADDING_NOT_SUPPORTED},
        !           221:        {PLV2_NOTIFY,                                   NON_FIRST_FRAGMENTS_ALSO},
        !           222:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           223:        {PLV2_TS_INITIATOR,                             0},
        !           224:        {PLV2_TS_RESPONDER,                             0},
        !           225:        {PLV2_NOTIFY,                                   MOBIKE_SUPPORTED},
        !           226:        {PLV2_NOTIFY,                                   ADDITIONAL_IP4_ADDRESS},
        !           227:        {PLV2_NOTIFY,                                   ADDITIONAL_IP6_ADDRESS},
        !           228:        {PLV2_NOTIFY,                                   NO_ADDITIONAL_ADDRESSES},
        !           229:        {PLV2_NOTIFY,                                   0},
        !           230:        {PLV2_VENDOR_ID,                                0},
        !           231:        {PLV2_FRAGMENT,                                 0},
        !           232: };
        !           233: 
        !           234: /**
        !           235:  * Message rule for IKE_AUTH from responder.
        !           236:  */
        !           237: static payload_rule_t ike_auth_r_rules[] = {
        !           238: /*     payload type                                    min     max                                             encr    suff */
        !           239:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           240:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
        !           241:        {PLV2_EAP,                                              0,      1,                                              TRUE,   TRUE},
        !           242:        {PLV2_AUTH,                                             0,      1,                                              TRUE,   TRUE},
        !           243:        {PLV2_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              TRUE,   FALSE},
        !           244:        {PLV2_ID_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           245:        {PLV2_SECURITY_ASSOCIATION,             0,      1,                                              TRUE,   FALSE},
        !           246:        {PLV2_TS_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           247:        {PLV2_TS_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           248:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           249:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           250: };
        !           251: 
        !           252: /**
        !           253:  * payload order for IKE_AUTH responder
        !           254:  */
        !           255: static payload_order_t ike_auth_r_order[] = {
        !           256: /*     payload type                                    notify type */
        !           257:        {PLV2_ID_RESPONDER,                             0},
        !           258:        {PLV2_CERTIFICATE,                              0},
        !           259:        {PLV2_AUTH,                                             0},
        !           260:        {PLV2_EAP,                                              0},
        !           261:        {PLV2_CONFIGURATION,                    0},
        !           262:        {PLV2_NOTIFY,                                   IPCOMP_SUPPORTED},
        !           263:        {PLV2_NOTIFY,                                   USE_TRANSPORT_MODE},
        !           264:        {PLV2_NOTIFY,                                   ESP_TFC_PADDING_NOT_SUPPORTED},
        !           265:        {PLV2_NOTIFY,                                   NON_FIRST_FRAGMENTS_ALSO},
        !           266:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           267:        {PLV2_TS_INITIATOR,                             0},
        !           268:        {PLV2_TS_RESPONDER,                             0},
        !           269:        {PLV2_NOTIFY,                                   AUTH_LIFETIME},
        !           270:        {PLV2_NOTIFY,                                   MOBIKE_SUPPORTED},
        !           271:        {PLV2_NOTIFY,                                   ADDITIONAL_IP4_ADDRESS},
        !           272:        {PLV2_NOTIFY,                                   ADDITIONAL_IP6_ADDRESS},
        !           273:        {PLV2_NOTIFY,                                   NO_ADDITIONAL_ADDRESSES},
        !           274:        {PLV2_NOTIFY,                                   0},
        !           275:        {PLV2_VENDOR_ID,                                0},
        !           276:        {PLV2_FRAGMENT,                                 0},
        !           277: };
        !           278: 
        !           279: /**
        !           280:  * Message rule for INFORMATIONAL from initiator.
        !           281:  */
        !           282: static payload_rule_t informational_i_rules[] = {
        !           283: /*     payload type                                    min     max                                             encr    suff */
        !           284:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           285:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           286:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           287:        {PLV2_DELETE,                                   0,      MAX_DELETE_PAYLOADS,    TRUE,   FALSE},
        !           288:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           289: };
        !           290: 
        !           291: /**
        !           292:  * payload order for INFORMATIONAL initiator
        !           293:  */
        !           294: static payload_order_t informational_i_order[] = {
        !           295: /*     payload type                                    notify type */
        !           296:        {PLV2_NOTIFY,                                   UPDATE_SA_ADDRESSES},
        !           297:        {PLV2_NOTIFY,                                   NAT_DETECTION_SOURCE_IP},
        !           298:        {PLV2_NOTIFY,                                   NAT_DETECTION_DESTINATION_IP},
        !           299:        {PLV2_NOTIFY,                                   COOKIE2},
        !           300:        {PLV2_NOTIFY,                                   0},
        !           301:        {PLV2_DELETE,                                   0},
        !           302:        {PLV2_CONFIGURATION,                    0},
        !           303:        {PLV2_FRAGMENT,                                 0},
        !           304: };
        !           305: 
        !           306: /**
        !           307:  * Message rule for INFORMATIONAL from responder.
        !           308:  */
        !           309: static payload_rule_t informational_r_rules[] = {
        !           310: /*     payload type                                    min     max                                             encr    suff */
        !           311:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           312:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           313:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           314:        {PLV2_DELETE,                                   0,      MAX_DELETE_PAYLOADS,    TRUE,   FALSE},
        !           315:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           316: };
        !           317: 
        !           318: /**
        !           319:  * payload order for INFORMATIONAL responder
        !           320:  */
        !           321: static payload_order_t informational_r_order[] = {
        !           322: /*     payload type                                    notify type */
        !           323:        {PLV2_NOTIFY,                                   UPDATE_SA_ADDRESSES},
        !           324:        {PLV2_NOTIFY,                                   NAT_DETECTION_SOURCE_IP},
        !           325:        {PLV2_NOTIFY,                                   NAT_DETECTION_DESTINATION_IP},
        !           326:        {PLV2_NOTIFY,                                   COOKIE2},
        !           327:        {PLV2_NOTIFY,                                   0},
        !           328:        {PLV2_DELETE,                                   0},
        !           329:        {PLV2_CONFIGURATION,                    0},
        !           330:        {PLV2_FRAGMENT,                                 0},
        !           331: };
        !           332: 
        !           333: /**
        !           334:  * Message rule for CREATE_CHILD_SA from initiator.
        !           335:  */
        !           336: static payload_rule_t create_child_sa_i_rules[] = {
        !           337: /*     payload type                                    min     max                                             encr    suff */
        !           338:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           339:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           340:        {PLV2_SECURITY_ASSOCIATION,             1,      1,                                              TRUE,   FALSE},
        !           341:        {PLV2_NONCE,                                    1,      1,                                              TRUE,   FALSE},
        !           342:        {PLV2_KEY_EXCHANGE,                             0,      1,                                              TRUE,   FALSE},
        !           343:        {PLV2_TS_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           344:        {PLV2_TS_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           345:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           346:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           347: };
        !           348: 
        !           349: /**
        !           350:  * payload order for CREATE_CHILD_SA from initiator.
        !           351:  */
        !           352: static payload_order_t create_child_sa_i_order[] = {
        !           353: /*     payload type                                    notify type */
        !           354:        {PLV2_NOTIFY,                                   REKEY_SA},
        !           355:        {PLV2_NOTIFY,                                   IPCOMP_SUPPORTED},
        !           356:        {PLV2_NOTIFY,                                   USE_TRANSPORT_MODE},
        !           357:        {PLV2_NOTIFY,                                   ESP_TFC_PADDING_NOT_SUPPORTED},
        !           358:        {PLV2_NOTIFY,                                   NON_FIRST_FRAGMENTS_ALSO},
        !           359:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           360:        {PLV2_NONCE,                                    0},
        !           361:        {PLV2_KEY_EXCHANGE,                             0},
        !           362:        {PLV2_TS_INITIATOR,                             0},
        !           363:        {PLV2_TS_RESPONDER,                             0},
        !           364:        {PLV2_NOTIFY,                                   0},
        !           365:        {PLV2_FRAGMENT,                                 0},
        !           366: };
        !           367: 
        !           368: /**
        !           369:  * Message rule for CREATE_CHILD_SA from responder.
        !           370:  */
        !           371: static payload_rule_t create_child_sa_r_rules[] = {
        !           372: /*     payload type                                    min     max                                             encr    suff */
        !           373:        {PLV2_FRAGMENT,                                 0,      1,                                              TRUE,   TRUE},
        !           374:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
        !           375:        {PLV2_SECURITY_ASSOCIATION,             1,      1,                                              TRUE,   FALSE},
        !           376:        {PLV2_NONCE,                                    1,      1,                                              TRUE,   FALSE},
        !           377:        {PLV2_KEY_EXCHANGE,                             0,      1,                                              TRUE,   FALSE},
        !           378:        {PLV2_TS_INITIATOR,                             0,      1,                                              TRUE,   FALSE},
        !           379:        {PLV2_TS_RESPONDER,                             0,      1,                                              TRUE,   FALSE},
        !           380:        {PLV2_CONFIGURATION,                    0,      1,                                              TRUE,   FALSE},
        !           381:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           382: };
        !           383: 
        !           384: /**
        !           385:  * payload order for CREATE_CHILD_SA from responder.
        !           386:  */
        !           387: static payload_order_t create_child_sa_r_order[] = {
        !           388: /*     payload type                                    notify type */
        !           389:        {PLV2_NOTIFY,                                   IPCOMP_SUPPORTED},
        !           390:        {PLV2_NOTIFY,                                   USE_TRANSPORT_MODE},
        !           391:        {PLV2_NOTIFY,                                   ESP_TFC_PADDING_NOT_SUPPORTED},
        !           392:        {PLV2_NOTIFY,                                   NON_FIRST_FRAGMENTS_ALSO},
        !           393:        {PLV2_SECURITY_ASSOCIATION,             0},
        !           394:        {PLV2_NONCE,                                    0},
        !           395:        {PLV2_KEY_EXCHANGE,                             0},
        !           396:        {PLV2_TS_INITIATOR,                             0},
        !           397:        {PLV2_TS_RESPONDER,                             0},
        !           398:        {PLV2_NOTIFY,                                   ADDITIONAL_TS_POSSIBLE},
        !           399:        {PLV2_NOTIFY,                                   0},
        !           400:        {PLV2_FRAGMENT,                                 0},
        !           401: };
        !           402: 
        !           403: #ifdef ME
        !           404: /**
        !           405:  * Message rule for ME_CONNECT from initiator.
        !           406:  */
        !           407: static payload_rule_t me_connect_i_rules[] = {
        !           408: /*     payload type                                    min     max                                             encr    suff */
        !           409:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
        !           410:        {PLV2_ID_PEER,                                  1,      1,                                              TRUE,   FALSE},
        !           411:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE}
        !           412: };
        !           413: 
        !           414: /**
        !           415:  * payload order for ME_CONNECT from initiator.
        !           416:  */
        !           417: static payload_order_t me_connect_i_order[] = {
        !           418: /*     payload type                                    notify type */
        !           419:        {PLV2_NOTIFY,                                   0},
        !           420:        {PLV2_ID_PEER,                                  0},
        !           421:        {PLV2_VENDOR_ID,                                0},
        !           422: };
        !           423: 
        !           424: /**
        !           425:  * Message rule for ME_CONNECT from responder.
        !           426:  */
        !           427: static payload_rule_t me_connect_r_rules[] = {
        !           428: /*     payload type                                    min     max                                             encr    suff */
        !           429:        {PLV2_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
        !           430:        {PLV2_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE}
        !           431: };
        !           432: 
        !           433: /**
        !           434:  * payload order for ME_CONNECT from responder.
        !           435:  */
        !           436: static payload_order_t me_connect_r_order[] = {
        !           437: /*     payload type                                    notify type */
        !           438:        {PLV2_NOTIFY,                                   0},
        !           439:        {PLV2_VENDOR_ID,                                0},
        !           440: };
        !           441: #endif /* ME */
        !           442: 
        !           443: #ifdef USE_IKEV1
        !           444: /**
        !           445:  * Message rule for ID_PROT from initiator.
        !           446:  */
        !           447: static payload_rule_t id_prot_i_rules[] = {
        !           448: /*     payload type                                    min     max                                             encr    suff */
        !           449:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           450:        {PLV1_SECURITY_ASSOCIATION,             0,      1,                                              FALSE,  FALSE},
        !           451:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              FALSE,  FALSE},
        !           452:        {PLV1_NONCE,                                    0,      1,                                              FALSE,  FALSE},
        !           453:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           454:        {PLV1_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   FALSE,  FALSE},
        !           455:        {PLV1_NAT_D,                                    0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           456:        {PLV1_NAT_D_DRAFT_00_03,                0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           457:        {PLV1_ID,                                               0,      1,                                              TRUE,   FALSE},
        !           458:        {PLV1_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              TRUE,   FALSE},
        !           459:        {PLV1_SIGNATURE,                                0,      1,                                              TRUE,   FALSE},
        !           460:        {PLV1_HASH,                                             0,      1,                                              TRUE,   FALSE},
        !           461:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           462: };
        !           463: 
        !           464: /**
        !           465:  * payload order for ID_PROT from initiator.
        !           466:  */
        !           467: static payload_order_t id_prot_i_order[] = {
        !           468: /*     payload type                                    notify type */
        !           469:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           470:        {PLV1_KEY_EXCHANGE,                             0},
        !           471:        {PLV1_NONCE,                                    0},
        !           472:        {PLV1_ID,                                               0},
        !           473:        {PLV1_CERTIFICATE,                              0},
        !           474:        {PLV1_SIGNATURE,                                0},
        !           475:        {PLV1_HASH,                                             0},
        !           476:        {PLV1_CERTREQ,                                  0},
        !           477:        {PLV1_NOTIFY,                                   0},
        !           478:        {PLV1_VENDOR_ID,                                0},
        !           479:        {PLV1_NAT_D,                                    0},
        !           480:        {PLV1_NAT_D_DRAFT_00_03,                0},
        !           481:        {PLV1_FRAGMENT,                                 0},
        !           482: };
        !           483: 
        !           484: /**
        !           485:  * Message rule for ID_PROT from responder.
        !           486:  */
        !           487: static payload_rule_t id_prot_r_rules[] = {
        !           488: /*     payload type                                    min     max                                             encr    suff */
        !           489:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           490:        {PLV1_SECURITY_ASSOCIATION,             0,      1,                                              FALSE,  FALSE},
        !           491:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              FALSE,  FALSE},
        !           492:        {PLV1_NONCE,                                    0,      1,                                              FALSE,  FALSE},
        !           493:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           494:        {PLV1_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   FALSE,  FALSE},
        !           495:        {PLV1_NAT_D,                                    0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           496:        {PLV1_NAT_D_DRAFT_00_03,                0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           497:        {PLV1_ID,                                               0,      1,                                              TRUE,   FALSE},
        !           498:        {PLV1_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              TRUE,   FALSE},
        !           499:        {PLV1_SIGNATURE,                                0,      1,                                              TRUE,   FALSE},
        !           500:        {PLV1_HASH,                                             0,      1,                                              TRUE,   FALSE},
        !           501:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           502: };
        !           503: 
        !           504: /**
        !           505:  * payload order for ID_PROT from responder.
        !           506:  */
        !           507: static payload_order_t id_prot_r_order[] = {
        !           508: /*     payload type                                    notify type */
        !           509:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           510:        {PLV1_KEY_EXCHANGE,                             0},
        !           511:        {PLV1_NONCE,                                    0},
        !           512:        {PLV1_ID,                                               0},
        !           513:        {PLV1_CERTIFICATE,                              0},
        !           514:        {PLV1_SIGNATURE,                                0},
        !           515:        {PLV1_HASH,                                             0},
        !           516:        {PLV1_CERTREQ,                                  0},
        !           517:        {PLV1_NOTIFY,                                   0},
        !           518:        {PLV1_VENDOR_ID,                                0},
        !           519:        {PLV1_NAT_D,                                    0},
        !           520:        {PLV1_NAT_D_DRAFT_00_03,                0},
        !           521:        {PLV1_FRAGMENT,                                 0},
        !           522: };
        !           523: 
        !           524: /**
        !           525:  * Message rule for AGGRESSIVE from initiator.
        !           526:  */
        !           527: static payload_rule_t aggressive_i_rules[] = {
        !           528: /*     payload type                                    min     max                                             encr    suff */
        !           529:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           530:        {PLV1_SECURITY_ASSOCIATION,             0,      1,                                              FALSE,  FALSE},
        !           531:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              FALSE,  FALSE},
        !           532:        {PLV1_NONCE,                                    0,      1,                                              FALSE,  FALSE},
        !           533:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           534:        {PLV1_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   FALSE,  FALSE},
        !           535:        {PLV1_NAT_D,                                    0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           536:        {PLV1_NAT_D_DRAFT_00_03,                0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           537:        {PLV1_ID,                                               0,      1,                                              FALSE,  FALSE},
        !           538:        {PLV1_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              TRUE,   FALSE},
        !           539:        {PLV1_SIGNATURE,                                0,      1,                                              TRUE,   FALSE},
        !           540:        {PLV1_HASH,                                             0,      1,                                              TRUE,   FALSE},
        !           541:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           542: };
        !           543: 
        !           544: /**
        !           545:  * payload order for AGGRESSIVE from initiator.
        !           546:  */
        !           547: static payload_order_t aggressive_i_order[] = {
        !           548: /*     payload type                                    notify type */
        !           549:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           550:        {PLV1_KEY_EXCHANGE,                             0},
        !           551:        {PLV1_NONCE,                                    0},
        !           552:        {PLV1_ID,                                               0},
        !           553:        {PLV1_CERTIFICATE,                              0},
        !           554:        {PLV1_CERTREQ,                                  0},
        !           555:        {PLV1_NOTIFY,                                   0},
        !           556:        {PLV1_VENDOR_ID,                                0},
        !           557:        {PLV1_HASH,                                             0},
        !           558:        {PLV1_NAT_D,                                    0},
        !           559:        {PLV1_NAT_D_DRAFT_00_03,                0},
        !           560:        {PLV1_SIGNATURE,                                0},
        !           561:        {PLV1_FRAGMENT,                                 0},
        !           562: };
        !           563: 
        !           564: /**
        !           565:  * Message rule for AGGRESSIVE from responder.
        !           566:  */
        !           567: static payload_rule_t aggressive_r_rules[] = {
        !           568: /*     payload type                                    min     max                                             encr    suff */
        !           569:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           570:        {PLV1_SECURITY_ASSOCIATION,             0,      1,                                              FALSE,  FALSE},
        !           571:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              FALSE,  FALSE},
        !           572:        {PLV1_NONCE,                                    0,      1,                                              FALSE,  FALSE},
        !           573:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               FALSE,  FALSE},
        !           574:        {PLV1_CERTREQ,                                  0,      MAX_CERTREQ_PAYLOADS,   FALSE,  FALSE},
        !           575:        {PLV1_NAT_D,                                    0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           576:        {PLV1_NAT_D_DRAFT_00_03,                0,      MAX_NAT_D_PAYLOADS,             FALSE,  FALSE},
        !           577:        {PLV1_ID,                                               0,      1,                                              FALSE,  FALSE},
        !           578:        {PLV1_CERTIFICATE,                              0,      MAX_CERT_PAYLOADS,              FALSE,  FALSE},
        !           579:        {PLV1_SIGNATURE,                                0,      1,                                              FALSE,  FALSE},
        !           580:        {PLV1_HASH,                                             0,      1,                                              FALSE,  FALSE},
        !           581:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           582: };
        !           583: 
        !           584: /**
        !           585:  * payload order for AGGRESSIVE from responder.
        !           586:  */
        !           587: static payload_order_t aggressive_r_order[] = {
        !           588: /*     payload type                                    notify type */
        !           589:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           590:        {PLV1_KEY_EXCHANGE,                             0},
        !           591:        {PLV1_NONCE,                                    0},
        !           592:        {PLV1_ID,                                               0},
        !           593:        {PLV1_CERTIFICATE,                              0},
        !           594:        {PLV1_CERTREQ,                                  0},
        !           595:        {PLV1_NOTIFY,                                   0},
        !           596:        {PLV1_VENDOR_ID,                                0},
        !           597:        {PLV1_NAT_D,                                    0},
        !           598:        {PLV1_NAT_D_DRAFT_00_03,                0},
        !           599:        {PLV1_SIGNATURE,                                0},
        !           600:        {PLV1_HASH,                                             0},
        !           601:        {PLV1_FRAGMENT,                                 0},
        !           602: };
        !           603: 
        !           604: /**
        !           605:  * Message rule for INFORMATIONAL_V1 from initiator.
        !           606:  */
        !           607: static payload_rule_t informational_i_rules_v1[] = {
        !           608: /*     payload type                                    min     max                                             encr    suff */
        !           609:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           610:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           611:        {PLV1_DELETE,                                   0,      MAX_DELETE_PAYLOADS,    TRUE,   FALSE},
        !           612:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           613: };
        !           614: 
        !           615: /**
        !           616:  * payload order for INFORMATIONAL_V1 from initiator.
        !           617:  */
        !           618: static payload_order_t informational_i_order_v1[] = {
        !           619: /*     payload type                                    notify type */
        !           620:        {PLV1_NOTIFY,                                   0},
        !           621:        {PLV1_DELETE,                                   0},
        !           622:        {PLV1_VENDOR_ID,                                0},
        !           623: };
        !           624: 
        !           625: /**
        !           626:  * Message rule for INFORMATIONAL_V1 from responder.
        !           627:  */
        !           628: static payload_rule_t informational_r_rules_v1[] = {
        !           629: /*     payload type                                    min     max                                             encr    suff */
        !           630:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    FALSE,  FALSE},
        !           631:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           632:        {PLV1_DELETE,                                   0,      MAX_DELETE_PAYLOADS,    TRUE,   FALSE},
        !           633:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           634: };
        !           635: 
        !           636: /**
        !           637:  * payload order for INFORMATIONAL_V1 from responder.
        !           638:  */
        !           639: static payload_order_t informational_r_order_v1[] = {
        !           640: /*     payload type                                    notify type */
        !           641:        {PLV1_NOTIFY,                                   0},
        !           642:        {PLV1_DELETE,                                   0},
        !           643:        {PLV1_VENDOR_ID,                                0},
        !           644: };
        !           645: 
        !           646: /**
        !           647:  * Message rule for QUICK_MODE from initiator.
        !           648:  */
        !           649: static payload_rule_t quick_mode_i_rules[] = {
        !           650: /*     payload type                                    min     max                                             encr    suff */
        !           651:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           652:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           653:        {PLV1_HASH,                                             0,      1,                                              TRUE,   FALSE},
        !           654:        {PLV1_SECURITY_ASSOCIATION,             0,      2,                                              TRUE,   FALSE},
        !           655:        {PLV1_NONCE,                                    0,      1,                                              TRUE,   FALSE},
        !           656:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              TRUE,   FALSE},
        !           657:        {PLV1_ID,                                               0,      2,                                              TRUE,   FALSE},
        !           658:        {PLV1_NAT_OA,                                   0,      2,                                              TRUE,   FALSE},
        !           659:        {PLV1_NAT_OA_DRAFT_00_03,               0,      2,                                              TRUE,   FALSE},
        !           660:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           661: };
        !           662: 
        !           663: /**
        !           664:  * payload order for QUICK_MODE from initiator.
        !           665:  */
        !           666: static payload_order_t quick_mode_i_order[] = {
        !           667: /*     payload type                                    notify type */
        !           668:        {PLV1_NOTIFY,                                   0},
        !           669:        {PLV1_VENDOR_ID,                                0},
        !           670:        {PLV1_HASH,                                             0},
        !           671:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           672:        {PLV1_NONCE,                                    0},
        !           673:        {PLV1_KEY_EXCHANGE,                             0},
        !           674:        {PLV1_ID,                                               0},
        !           675:        {PLV1_NAT_OA,                                   0},
        !           676:        {PLV1_NAT_OA_DRAFT_00_03,               0},
        !           677:        {PLV1_FRAGMENT,                                 0},
        !           678: };
        !           679: 
        !           680: /**
        !           681:  * Message rule for QUICK_MODE from responder.
        !           682:  */
        !           683: static payload_rule_t quick_mode_r_rules[] = {
        !           684: /*     payload type                                    min     max                                             encr    suff */
        !           685:        {PLV1_NOTIFY,                                   0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        !           686:        {PLV1_VENDOR_ID,                                0,      MAX_VID_PAYLOADS,               TRUE,   FALSE},
        !           687:        {PLV1_HASH,                                             0,      1,                                              TRUE,   FALSE},
        !           688:        {PLV1_SECURITY_ASSOCIATION,             0,      2,                                              TRUE,   FALSE},
        !           689:        {PLV1_NONCE,                                    0,      1,                                              TRUE,   FALSE},
        !           690:        {PLV1_KEY_EXCHANGE,                             0,      1,                                              TRUE,   FALSE},
        !           691:        {PLV1_ID,                                               0,      2,                                              TRUE,   FALSE},
        !           692:        {PLV1_NAT_OA,                                   0,      2,                                              TRUE,   FALSE},
        !           693:        {PLV1_NAT_OA_DRAFT_00_03,               0,      2,                                              TRUE,   FALSE},
        !           694:        {PLV1_FRAGMENT,                                 0,      1,                                              FALSE,  TRUE},
        !           695: };
        !           696: 
        !           697: /**
        !           698:  * payload order for QUICK_MODE from responder.
        !           699:  */
        !           700: static payload_order_t quick_mode_r_order[] = {
        !           701: /*     payload type                                    notify type */
        !           702:        {PLV1_NOTIFY,                                   0},
        !           703:        {PLV1_VENDOR_ID,                                0},
        !           704:        {PLV1_HASH,                                             0},
        !           705:        {PLV1_SECURITY_ASSOCIATION,             0},
        !           706:        {PLV1_NONCE,                                    0},
        !           707:        {PLV1_KEY_EXCHANGE,                             0},
        !           708:        {PLV1_ID,                                               0},
        !           709:        {PLV1_NAT_OA,                                   0},
        !           710:        {PLV1_NAT_OA_DRAFT_00_03,               0},
        !           711:        {PLV1_FRAGMENT,                                 0},
        !           712: };
        !           713: 
        !           714: /**
        !           715:  * Message rule for TRANSACTION.
        !           716:  */
        !           717: static payload_rule_t transaction_payload_rules_v1[] = {
        !           718: /*     payload type                                    min     max     encr    suff */
        !           719:        {PLV1_HASH,                                             0,      1,      TRUE,   FALSE},
        !           720:        {PLV1_CONFIGURATION,                    1,      1,      FALSE,  FALSE},
        !           721: };
        !           722: 
        !           723: /**
        !           724:  * Payload order for TRANSACTION.
        !           725:  */
        !           726: static payload_order_t transaction_payload_order_v1[] = {
        !           727: /*     payload type                                    notify type */
        !           728:        {PLV1_HASH,                                             0},
        !           729:        {PLV1_CONFIGURATION,                    0},
        !           730: };
        !           731: 
        !           732: #endif /* USE_IKEV1 */
        !           733: 
        !           734: /**
        !           735:  * Message rules, defines allowed payloads.
        !           736:  */
        !           737: static message_rule_t message_rules[] = {
        !           738:        {IKE_SA_INIT,           TRUE,   FALSE,
        !           739:                countof(ike_sa_init_i_rules), ike_sa_init_i_rules,
        !           740:                countof(ike_sa_init_i_order), ike_sa_init_i_order,
        !           741:        },
        !           742:        {IKE_SA_INIT,           FALSE,  FALSE,
        !           743:                countof(ike_sa_init_r_rules), ike_sa_init_r_rules,
        !           744:                countof(ike_sa_init_r_order), ike_sa_init_r_order,
        !           745:        },
        !           746:        {IKE_AUTH,                      TRUE,   TRUE,
        !           747:                countof(ike_auth_i_rules), ike_auth_i_rules,
        !           748:                countof(ike_auth_i_order), ike_auth_i_order,
        !           749:        },
        !           750:        {IKE_AUTH,                      FALSE,  TRUE,
        !           751:                countof(ike_auth_r_rules), ike_auth_r_rules,
        !           752:                countof(ike_auth_r_order), ike_auth_r_order,
        !           753:        },
        !           754:        {INFORMATIONAL,         TRUE,   TRUE,
        !           755:                countof(informational_i_rules), informational_i_rules,
        !           756:                countof(informational_i_order), informational_i_order,
        !           757:        },
        !           758:        {INFORMATIONAL,         FALSE,  TRUE,
        !           759:                countof(informational_r_rules), informational_r_rules,
        !           760:                countof(informational_r_order), informational_r_order,
        !           761:        },
        !           762:        {CREATE_CHILD_SA,       TRUE,   TRUE,
        !           763:                countof(create_child_sa_i_rules), create_child_sa_i_rules,
        !           764:                countof(create_child_sa_i_order), create_child_sa_i_order,
        !           765:        },
        !           766:        {CREATE_CHILD_SA,       FALSE,  TRUE,
        !           767:                countof(create_child_sa_r_rules), create_child_sa_r_rules,
        !           768:                countof(create_child_sa_r_order), create_child_sa_r_order,
        !           769:        },
        !           770: #ifdef ME
        !           771:        {ME_CONNECT,            TRUE,   TRUE,
        !           772:                countof(me_connect_i_rules), me_connect_i_rules,
        !           773:                countof(me_connect_i_order), me_connect_i_order,
        !           774:        },
        !           775:        {ME_CONNECT,            FALSE,  TRUE,
        !           776:                countof(me_connect_r_rules), me_connect_r_rules,
        !           777:                countof(me_connect_r_order), me_connect_r_order,
        !           778:        },
        !           779: #endif /* ME */
        !           780: #ifdef USE_IKEV1
        !           781:        {ID_PROT,                       TRUE,   FALSE,
        !           782:                countof(id_prot_i_rules), id_prot_i_rules,
        !           783:                countof(id_prot_i_order), id_prot_i_order,
        !           784:        },
        !           785:        {ID_PROT,                       FALSE,  FALSE,
        !           786:                countof(id_prot_r_rules), id_prot_r_rules,
        !           787:                countof(id_prot_r_order), id_prot_r_order,
        !           788:        },
        !           789:        {AGGRESSIVE,            TRUE,   FALSE,
        !           790:                countof(aggressive_i_rules), aggressive_i_rules,
        !           791:                countof(aggressive_i_order), aggressive_i_order,
        !           792:        },
        !           793:        {AGGRESSIVE,            FALSE,  FALSE,
        !           794:                countof(aggressive_r_rules), aggressive_r_rules,
        !           795:                countof(aggressive_r_order), aggressive_r_order,
        !           796:        },
        !           797:        {INFORMATIONAL_V1,      TRUE,   TRUE,
        !           798:                countof(informational_i_rules_v1), informational_i_rules_v1,
        !           799:                countof(informational_i_order_v1), informational_i_order_v1,
        !           800:        },
        !           801:        {INFORMATIONAL_V1,      FALSE,  TRUE,
        !           802:                countof(informational_r_rules_v1), informational_r_rules_v1,
        !           803:                countof(informational_r_order_v1), informational_r_order_v1,
        !           804:        },
        !           805:        {QUICK_MODE,            TRUE,   TRUE,
        !           806:                countof(quick_mode_i_rules), quick_mode_i_rules,
        !           807:                countof(quick_mode_i_order), quick_mode_i_order,
        !           808:        },
        !           809:        {QUICK_MODE,            FALSE,  TRUE,
        !           810:                countof(quick_mode_r_rules), quick_mode_r_rules,
        !           811:                countof(quick_mode_r_order), quick_mode_r_order,
        !           812:        },
        !           813:        {TRANSACTION,           TRUE,   TRUE,
        !           814:                countof(transaction_payload_rules_v1), transaction_payload_rules_v1,
        !           815:                countof(transaction_payload_order_v1), transaction_payload_order_v1,
        !           816:        },
        !           817:        {TRANSACTION,           FALSE,  TRUE,
        !           818:                countof(transaction_payload_rules_v1), transaction_payload_rules_v1,
        !           819:                countof(transaction_payload_order_v1), transaction_payload_order_v1,
        !           820:        },
        !           821:        /* TODO-IKEv1: define rules for other exchanges */
        !           822: #endif /* USE_IKEV1 */
        !           823: };
        !           824: 
        !           825: /**
        !           826:  * Data for fragment reassembly.
        !           827:  */
        !           828: typedef struct {
        !           829: 
        !           830:        /**
        !           831:         * For IKEv1 the number of the last fragment (in case we receive them out
        !           832:         * of order), since the first one starts with 1 this defines the number of
        !           833:         * fragments we expect.
        !           834:         * For IKEv2 we store the total number of fragment we received last.
        !           835:         */
        !           836:        uint16_t last;
        !           837: 
        !           838:        /**
        !           839:         * Length of all currently received fragments.
        !           840:         */
        !           841:        size_t len;
        !           842: 
        !           843:        /**
        !           844:         * Maximum length of a fragmented packet.
        !           845:         */
        !           846:        size_t max_packet;
        !           847: 
        !           848: } fragment_data_t;
        !           849: 
        !           850: typedef struct private_message_t private_message_t;
        !           851: 
        !           852: /**
        !           853:  * Private data of an message_t object.
        !           854:  */
        !           855: struct private_message_t {
        !           856: 
        !           857:        /**
        !           858:         * Public part of a message_t object.
        !           859:         */
        !           860:        message_t public;
        !           861: 
        !           862:        /**
        !           863:         * Minor version of message.
        !           864:         */
        !           865:        uint8_t major_version;
        !           866: 
        !           867:        /**
        !           868:         * Major version of message.
        !           869:         */
        !           870:        uint8_t minor_version;
        !           871: 
        !           872:        /**
        !           873:         * First Payload in message.
        !           874:         */
        !           875:        payload_type_t first_payload;
        !           876: 
        !           877:        /**
        !           878:         * Assigned exchange type.
        !           879:         */
        !           880:        exchange_type_t exchange_type;
        !           881: 
        !           882:        /**
        !           883:         * TRUE if message is a request, FALSE if a reply.
        !           884:         */
        !           885:        bool is_request;
        !           886: 
        !           887:        /**
        !           888:         * The message is encrypted (IKEv1)
        !           889:         */
        !           890:        bool is_encrypted;
        !           891: 
        !           892:        /**
        !           893:         * Higher version supported?
        !           894:         */
        !           895:        bool version_flag;
        !           896: 
        !           897:        /**
        !           898:         * Reserved bits in IKE header
        !           899:         */
        !           900:        bool reserved[2];
        !           901: 
        !           902:        /**
        !           903:         * Sorting of message disabled?
        !           904:         */
        !           905:        bool sort_disabled;
        !           906: 
        !           907:        /**
        !           908:         * Message ID of this message.
        !           909:         */
        !           910:        uint32_t message_id;
        !           911: 
        !           912:        /**
        !           913:         * ID of assigned IKE_SA.
        !           914:         */
        !           915:        ike_sa_id_t *ike_sa_id;
        !           916: 
        !           917:        /**
        !           918:         * Assigned UDP packet, stores incoming packet or last generated one.
        !           919:         */
        !           920:        packet_t *packet;
        !           921: 
        !           922:        /**
        !           923:         * Array of generated fragments (if any), as packet_t*.
        !           924:         * If defragmenting (i.e. frag != NULL) this contains fragment_t*
        !           925:         */
        !           926:        array_t *fragments;
        !           927: 
        !           928:        /**
        !           929:         * Linked List where payload data are stored in.
        !           930:         */
        !           931:        linked_list_t *payloads;
        !           932: 
        !           933:         /**
        !           934:          * Assigned parser to parse Header and Body of this message.
        !           935:          */
        !           936:        parser_t *parser;
        !           937: 
        !           938:        /**
        !           939:         * The message rule for this message instance
        !           940:         */
        !           941:        message_rule_t *rule;
        !           942: 
        !           943:        /**
        !           944:         * Data used to reassemble a fragmented message
        !           945:         */
        !           946:        fragment_data_t *frag;
        !           947: };
        !           948: 
        !           949: /**
        !           950:  * Maximum number of fragments we will handle
        !           951:  */
        !           952: #define MAX_FRAGMENTS 255
        !           953: 
        !           954: /**
        !           955:  * A single fragment within a fragmented message
        !           956:  */
        !           957: typedef struct {
        !           958: 
        !           959:        /** fragment number */
        !           960:        uint8_t num;
        !           961: 
        !           962:        /** fragment data */
        !           963:        chunk_t data;
        !           964: 
        !           965: } fragment_t;
        !           966: 
        !           967: static void fragment_destroy(fragment_t *this)
        !           968: {
        !           969:        chunk_free(&this->data);
        !           970:        free(this);
        !           971: }
        !           972: 
        !           973: static void reset_defrag(private_message_t *this)
        !           974: {
        !           975:        array_destroy_function(this->fragments, (void*)fragment_destroy, NULL);
        !           976:        this->fragments = NULL;
        !           977:        this->frag->last = 0;
        !           978:        this->frag->len = 0;
        !           979: }
        !           980: 
        !           981: /**
        !           982:  * Get the message rule that applies to this message
        !           983:  */
        !           984: static message_rule_t* get_message_rule(private_message_t *this)
        !           985: {
        !           986:        int i;
        !           987: 
        !           988:        for (i = 0; i < countof(message_rules); i++)
        !           989:        {
        !           990:                if ((this->exchange_type == message_rules[i].exchange_type) &&
        !           991:                        (this->is_request == message_rules[i].is_request))
        !           992:                {
        !           993:                        return &message_rules[i];
        !           994:                }
        !           995:        }
        !           996:        return NULL;
        !           997: }
        !           998: 
        !           999: /**
        !          1000:  * Look up a payload rule
        !          1001:  */
        !          1002: static payload_rule_t* get_payload_rule(private_message_t *this,
        !          1003:                                                                                payload_type_t type)
        !          1004: {
        !          1005:        int i;
        !          1006: 
        !          1007:        for (i = 0; i < this->rule->rule_count;i++)
        !          1008:        {
        !          1009:                if (this->rule->rules[i].type == type)
        !          1010:                {
        !          1011:                        return &this->rule->rules[i];
        !          1012:                }
        !          1013:        }
        !          1014:        return NULL;
        !          1015: }
        !          1016: 
        !          1017: METHOD(message_t, set_ike_sa_id, void,
        !          1018:        private_message_t *this,ike_sa_id_t *ike_sa_id)
        !          1019: {
        !          1020:        DESTROY_IF(this->ike_sa_id);
        !          1021:        this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
        !          1022: }
        !          1023: 
        !          1024: METHOD(message_t, get_ike_sa_id, ike_sa_id_t*,
        !          1025:        private_message_t *this)
        !          1026: {
        !          1027:        return this->ike_sa_id;
        !          1028: }
        !          1029: 
        !          1030: METHOD(message_t, set_message_id, void,
        !          1031:        private_message_t *this,uint32_t message_id)
        !          1032: {
        !          1033:        this->message_id = message_id;
        !          1034: }
        !          1035: 
        !          1036: METHOD(message_t, get_message_id, uint32_t,
        !          1037:        private_message_t *this)
        !          1038: {
        !          1039:        return this->message_id;
        !          1040: }
        !          1041: 
        !          1042: METHOD(message_t, get_initiator_spi, uint64_t,
        !          1043:        private_message_t *this)
        !          1044: {
        !          1045:        return (this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
        !          1046: }
        !          1047: 
        !          1048: METHOD(message_t, get_responder_spi, uint64_t,
        !          1049:        private_message_t *this)
        !          1050: {
        !          1051:        return (this->ike_sa_id->get_responder_spi(this->ike_sa_id));
        !          1052: }
        !          1053: 
        !          1054: METHOD(message_t, set_major_version, void,
        !          1055:        private_message_t *this, uint8_t major_version)
        !          1056: {
        !          1057:        this->major_version = major_version;
        !          1058: }
        !          1059: 
        !          1060: METHOD(message_t, get_major_version, uint8_t,
        !          1061:        private_message_t *this)
        !          1062: {
        !          1063:        return this->major_version;
        !          1064: }
        !          1065: 
        !          1066: METHOD(message_t, set_minor_version, void,
        !          1067:        private_message_t *this,uint8_t minor_version)
        !          1068: {
        !          1069:        this->minor_version = minor_version;
        !          1070: }
        !          1071: 
        !          1072: METHOD(message_t, get_minor_version, uint8_t,
        !          1073:        private_message_t *this)
        !          1074: {
        !          1075:        return this->minor_version;
        !          1076: }
        !          1077: 
        !          1078: METHOD(message_t, set_exchange_type, void,
        !          1079:        private_message_t *this, exchange_type_t exchange_type)
        !          1080: {
        !          1081:        this->exchange_type = exchange_type;
        !          1082: }
        !          1083: 
        !          1084: METHOD(message_t, get_exchange_type, exchange_type_t,
        !          1085:        private_message_t *this)
        !          1086: {
        !          1087:        return this->exchange_type;
        !          1088: }
        !          1089: 
        !          1090: METHOD(message_t, get_first_payload_type, payload_type_t,
        !          1091:        private_message_t *this)
        !          1092: {
        !          1093:        return this->first_payload;
        !          1094: }
        !          1095: 
        !          1096: METHOD(message_t, set_request, void,
        !          1097:        private_message_t *this, bool request)
        !          1098: {
        !          1099:        this->is_request = request;
        !          1100: }
        !          1101: 
        !          1102: METHOD(message_t, get_request, bool,
        !          1103:        private_message_t *this)
        !          1104: {
        !          1105:        return this->is_request;
        !          1106: }
        !          1107: 
        !          1108: METHOD(message_t, set_version_flag, void,
        !          1109:        private_message_t *this)
        !          1110: {
        !          1111:        this->version_flag = TRUE;
        !          1112: }
        !          1113: 
        !          1114: METHOD(message_t, get_reserved_header_bit, bool,
        !          1115:        private_message_t *this, u_int nr)
        !          1116: {
        !          1117:        if (nr < countof(this->reserved))
        !          1118:        {
        !          1119:                return this->reserved[nr];
        !          1120:        }
        !          1121:        return FALSE;
        !          1122: }
        !          1123: 
        !          1124: METHOD(message_t, set_reserved_header_bit, void,
        !          1125:        private_message_t *this, u_int nr)
        !          1126: {
        !          1127:        if (nr < countof(this->reserved))
        !          1128:        {
        !          1129:                this->reserved[nr] = TRUE;
        !          1130:        }
        !          1131: }
        !          1132: 
        !          1133: METHOD(message_t, is_encoded, bool,
        !          1134:        private_message_t *this)
        !          1135: {
        !          1136:        return this->packet->get_data(this->packet).ptr != NULL;
        !          1137: }
        !          1138: 
        !          1139: METHOD(message_t, is_fragmented, bool,
        !          1140:        private_message_t *this)
        !          1141: {
        !          1142:        return array_count(this->fragments) > 0;
        !          1143: }
        !          1144: 
        !          1145: METHOD(message_t, add_payload, void,
        !          1146:        private_message_t *this, payload_t *payload)
        !          1147: {
        !          1148:        payload_t *last_payload;
        !          1149: 
        !          1150:        if (this->payloads->get_count(this->payloads) > 0)
        !          1151:        {
        !          1152:                this->payloads->get_last(this->payloads, (void **)&last_payload);
        !          1153:                last_payload->set_next_type(last_payload, payload->get_type(payload));
        !          1154:        }
        !          1155:        else
        !          1156:        {
        !          1157:                this->first_payload = payload->get_type(payload);
        !          1158:        }
        !          1159:        payload->set_next_type(payload, PL_NONE);
        !          1160:        this->payloads->insert_last(this->payloads, payload);
        !          1161: 
        !          1162:        DBG2(DBG_ENC ,"added payload of type %N to message",
        !          1163:                 payload_type_names, payload->get_type(payload));
        !          1164: }
        !          1165: 
        !          1166: METHOD(message_t, add_notify, void,
        !          1167:        private_message_t *this, bool flush, notify_type_t type, chunk_t data)
        !          1168: {
        !          1169:        notify_payload_t *notify;
        !          1170:        payload_t *payload;
        !          1171: 
        !          1172:        if (flush)
        !          1173:        {
        !          1174:                while (this->payloads->remove_last(this->payloads,
        !          1175:                                                                                                (void**)&payload) == SUCCESS)
        !          1176:                {
        !          1177:                        payload->destroy(payload);
        !          1178:                }
        !          1179:        }
        !          1180:        if (this->major_version == IKEV2_MAJOR_VERSION)
        !          1181:        {
        !          1182:                notify = notify_payload_create(PLV2_NOTIFY);
        !          1183:        }
        !          1184:        else
        !          1185:        {
        !          1186:                notify = notify_payload_create(PLV1_NOTIFY);
        !          1187:        }
        !          1188:        notify->set_notify_type(notify, type);
        !          1189:        notify->set_notification_data(notify, data);
        !          1190:        add_payload(this, (payload_t*)notify);
        !          1191: }
        !          1192: 
        !          1193: METHOD(message_t, set_source, void,
        !          1194:        private_message_t *this, host_t *host)
        !          1195: {
        !          1196:        this->packet->set_source(this->packet, host);
        !          1197: }
        !          1198: 
        !          1199: METHOD(message_t, set_destination, void,
        !          1200:        private_message_t *this, host_t *host)
        !          1201: {
        !          1202:        this->packet->set_destination(this->packet, host);
        !          1203: }
        !          1204: 
        !          1205: METHOD(message_t, get_source, host_t*,
        !          1206:        private_message_t *this)
        !          1207: {
        !          1208:        return this->packet->get_source(this->packet);
        !          1209: }
        !          1210: 
        !          1211: METHOD(message_t, get_destination, host_t*,
        !          1212:        private_message_t *this)
        !          1213: {
        !          1214:        return this->packet->get_destination(this->packet);
        !          1215: }
        !          1216: 
        !          1217: METHOD(message_t, create_payload_enumerator, enumerator_t*,
        !          1218:        private_message_t *this)
        !          1219: {
        !          1220:        return this->payloads->create_enumerator(this->payloads);
        !          1221: }
        !          1222: 
        !          1223: METHOD(message_t, remove_payload_at, void,
        !          1224:        private_message_t *this, enumerator_t *enumerator)
        !          1225: {
        !          1226:        this->payloads->remove_at(this->payloads, enumerator);
        !          1227: }
        !          1228: 
        !          1229: METHOD(message_t, get_payload, payload_t*,
        !          1230:        private_message_t *this, payload_type_t type)
        !          1231: {
        !          1232:        payload_t *current, *found = NULL;
        !          1233:        enumerator_t *enumerator;
        !          1234: 
        !          1235:        enumerator = create_payload_enumerator(this);
        !          1236:        while (enumerator->enumerate(enumerator, &current))
        !          1237:        {
        !          1238:                if (current->get_type(current) == type)
        !          1239:                {
        !          1240:                        found = current;
        !          1241:                        break;
        !          1242:                }
        !          1243:        }
        !          1244:        enumerator->destroy(enumerator);
        !          1245:        return found;
        !          1246: }
        !          1247: 
        !          1248: METHOD(message_t, get_notify, notify_payload_t*,
        !          1249:        private_message_t *this, notify_type_t type)
        !          1250: {
        !          1251:        enumerator_t *enumerator;
        !          1252:        notify_payload_t *notify = NULL;
        !          1253:        payload_t *payload;
        !          1254: 
        !          1255:        enumerator = create_payload_enumerator(this);
        !          1256:        while (enumerator->enumerate(enumerator, &payload))
        !          1257:        {
        !          1258:                if (payload->get_type(payload) == PLV2_NOTIFY ||
        !          1259:                        payload->get_type(payload) == PLV1_NOTIFY)
        !          1260:                {
        !          1261:                        notify = (notify_payload_t*)payload;
        !          1262:                        if (notify->get_notify_type(notify) == type)
        !          1263:                        {
        !          1264:                                break;
        !          1265:                        }
        !          1266:                        notify = NULL;
        !          1267:                }
        !          1268:        }
        !          1269:        enumerator->destroy(enumerator);
        !          1270:        return notify;
        !          1271: }
        !          1272: 
        !          1273: /**
        !          1274:  * get a string representation of the message
        !          1275:  */
        !          1276: static char* get_string(private_message_t *this, char *buf, int len)
        !          1277: {
        !          1278:        enumerator_t *enumerator;
        !          1279:        payload_t *payload;
        !          1280:        int written;
        !          1281:        char *pos = buf;
        !          1282: 
        !          1283:        memset(buf, 0, len);
        !          1284:        len--;
        !          1285: 
        !          1286:        written = snprintf(pos, len, "%N %s %u [",
        !          1287:                                           exchange_type_names, this->exchange_type,
        !          1288:                                           this->is_request ? "request" : "response",
        !          1289:                                           this->message_id);
        !          1290:        if (written >= len || written < 0)
        !          1291:        {
        !          1292:                return "";
        !          1293:        }
        !          1294:        pos += written;
        !          1295:        len -= written;
        !          1296: 
        !          1297:        enumerator = create_payload_enumerator(this);
        !          1298:        while (enumerator->enumerate(enumerator, &payload))
        !          1299:        {
        !          1300:                written = snprintf(pos, len, " %N", payload_type_short_names,
        !          1301:                                                   payload->get_type(payload));
        !          1302:                if (written >= len || written < 0)
        !          1303:                {
        !          1304:                        return buf;
        !          1305:                }
        !          1306:                pos += written;
        !          1307:                len -= written;
        !          1308:                if (payload->get_type(payload) == PLV2_NOTIFY ||
        !          1309:                        payload->get_type(payload) == PLV1_NOTIFY)
        !          1310:                {
        !          1311:                        notify_payload_t *notify;
        !          1312:                        notify_type_t type;
        !          1313:                        chunk_t data;
        !          1314: 
        !          1315:                        notify = (notify_payload_t*)payload;
        !          1316:                        type = notify->get_notify_type(notify);
        !          1317:                        data = notify->get_notification_data(notify);
        !          1318:                        if (type == MS_NOTIFY_STATUS && data.len == 4)
        !          1319:                        {
        !          1320:                                written = snprintf(pos, len, "(%N(%d))", notify_type_short_names,
        !          1321:                                                                   type, untoh32(data.ptr));
        !          1322:                        }
        !          1323:                        else
        !          1324:                        {
        !          1325:                                written = snprintf(pos, len, "(%N)", notify_type_short_names,
        !          1326:                                                                   type);
        !          1327:                        }
        !          1328:                        if (written >= len || written < 0)
        !          1329:                        {
        !          1330:                                return buf;
        !          1331:                        }
        !          1332:                        pos += written;
        !          1333:                        len -= written;
        !          1334:                }
        !          1335:                if (payload->get_type(payload) == PLV2_EAP)
        !          1336:                {
        !          1337:                        eap_payload_t *eap = (eap_payload_t*)payload;
        !          1338:                        uint32_t vendor;
        !          1339:                        eap_type_t type;
        !          1340:                        char method[64] = "";
        !          1341: 
        !          1342:                        type = eap->get_type(eap, &vendor);
        !          1343:                        if (type)
        !          1344:                        {
        !          1345:                                if (vendor)
        !          1346:                                {
        !          1347:                                        snprintf(method, sizeof(method), "/%d-%d", type, vendor);
        !          1348:                                }
        !          1349:                                else
        !          1350:                                {
        !          1351:                                        snprintf(method, sizeof(method), "/%N",
        !          1352:                                                         eap_type_short_names, type);
        !          1353:                                }
        !          1354:                        }
        !          1355:                        written = snprintf(pos, len, "/%N%s", eap_code_short_names,
        !          1356:                                                           eap->get_code(eap), method);
        !          1357:                        if (written >= len || written < 0)
        !          1358:                        {
        !          1359:                                return buf;
        !          1360:                        }
        !          1361:                        pos += written;
        !          1362:                        len -= written;
        !          1363:                }
        !          1364:                if (payload->get_type(payload) == PLV2_CONFIGURATION ||
        !          1365:                        payload->get_type(payload) == PLV1_CONFIGURATION)
        !          1366:                {
        !          1367:                        cp_payload_t *cp = (cp_payload_t*)payload;
        !          1368:                        enumerator_t *attributes;
        !          1369:                        configuration_attribute_t *attribute;
        !          1370:                        bool first = TRUE;
        !          1371:                        char *pfx;
        !          1372: 
        !          1373:                        switch (cp->get_type(cp))
        !          1374:                        {
        !          1375:                                case CFG_REQUEST:
        !          1376:                                        pfx = "RQ(";
        !          1377:                                        break;
        !          1378:                                case CFG_REPLY:
        !          1379:                                        pfx = "RP(";
        !          1380:                                        break;
        !          1381:                                case CFG_SET:
        !          1382:                                        pfx = "S(";
        !          1383:                                        break;
        !          1384:                                case CFG_ACK:
        !          1385:                                        pfx = "A(";
        !          1386:                                        break;
        !          1387:                                default:
        !          1388:                                        pfx = "(";
        !          1389:                                        break;
        !          1390:                        }
        !          1391: 
        !          1392:                        attributes = cp->create_attribute_enumerator(cp);
        !          1393:                        while (attributes->enumerate(attributes, &attribute))
        !          1394:                        {
        !          1395:                                written = snprintf(pos, len, "%s%N", first ? pfx : " ",
        !          1396:                                                                   configuration_attribute_type_short_names,
        !          1397:                                                                   attribute->get_type(attribute));
        !          1398:                                if (written >= len || written < 0)
        !          1399:                                {
        !          1400:                                        return buf;
        !          1401:                                }
        !          1402:                                pos += written;
        !          1403:                                len -= written;
        !          1404:                                first = FALSE;
        !          1405:                        }
        !          1406:                        attributes->destroy(attributes);
        !          1407:                        if (!first)
        !          1408:                        {
        !          1409:                                written = snprintf(pos, len, ")");
        !          1410:                                if (written >= len || written < 0)
        !          1411:                                {
        !          1412:                                        return buf;
        !          1413:                                }
        !          1414:                                pos += written;
        !          1415:                                len -= written;
        !          1416:                        }
        !          1417:                }
        !          1418:                if (payload->get_type(payload) == PLV1_FRAGMENT)
        !          1419:                {
        !          1420:                        fragment_payload_t *frag;
        !          1421: 
        !          1422:                        frag = (fragment_payload_t*)payload;
        !          1423:                        if (frag->is_last(frag))
        !          1424:                        {
        !          1425:                                written = snprintf(pos, len, "(%u/%u)",
        !          1426:                                                        frag->get_number(frag), frag->get_number(frag));
        !          1427:                        }
        !          1428:                        else
        !          1429:                        {
        !          1430:                                written = snprintf(pos, len, "(%u)", frag->get_number(frag));
        !          1431:                        }
        !          1432:                        if (written >= len || written < 0)
        !          1433:                        {
        !          1434:                                return buf;
        !          1435:                        }
        !          1436:                        pos += written;
        !          1437:                        len -= written;
        !          1438:                }
        !          1439:                if (payload->get_type(payload) == PLV2_FRAGMENT)
        !          1440:                {
        !          1441:                        encrypted_fragment_payload_t *frag;
        !          1442: 
        !          1443:                        frag = (encrypted_fragment_payload_t*)payload;
        !          1444:                        written = snprintf(pos, len, "(%u/%u)",
        !          1445:                                                           frag->get_fragment_number(frag),
        !          1446:                                                           frag->get_total_fragments(frag));
        !          1447:                        if (written >= len || written < 0)
        !          1448:                        {
        !          1449:                                return buf;
        !          1450:                        }
        !          1451:                        pos += written;
        !          1452:                        len -= written;
        !          1453:                }
        !          1454:                if (payload->get_type(payload) == PL_UNKNOWN)
        !          1455:                {
        !          1456:                        unknown_payload_t *unknown;
        !          1457: 
        !          1458:                        unknown = (unknown_payload_t*)payload;
        !          1459:                        written = snprintf(pos, len, "(%d)", unknown->get_type(unknown));
        !          1460:                        if (written >= len || written < 0)
        !          1461:                        {
        !          1462:                                return buf;
        !          1463:                        }
        !          1464:                        pos += written;
        !          1465:                        len -= written;
        !          1466:                }
        !          1467:        }
        !          1468:        enumerator->destroy(enumerator);
        !          1469: 
        !          1470:        /* remove last space */
        !          1471:        snprintf(pos, len, " ]");
        !          1472:        return buf;
        !          1473: }
        !          1474: 
        !          1475: METHOD(message_t, disable_sort, void,
        !          1476:        private_message_t *this)
        !          1477: {
        !          1478:        this->sort_disabled = TRUE;
        !          1479: }
        !          1480: 
        !          1481: /**
        !          1482:  * reorder payloads depending on reordering rules
        !          1483:  */
        !          1484: static void order_payloads(private_message_t *this)
        !          1485: {
        !          1486:        linked_list_t *list;
        !          1487:        payload_t *payload;
        !          1488:        int i;
        !          1489: 
        !          1490:        DBG2(DBG_ENC, "order payloads in message");
        !          1491: 
        !          1492:        /* move to temp list */
        !          1493:        list = linked_list_create();
        !          1494:        while (this->payloads->remove_last(this->payloads,
        !          1495:                                                                           (void**)&payload) == SUCCESS)
        !          1496:        {
        !          1497:                list->insert_first(list, payload);
        !          1498:        }
        !          1499:        /* for each rule, ... */
        !          1500:        for (i = 0; i < this->rule->order_count; i++)
        !          1501:        {
        !          1502:                enumerator_t *enumerator;
        !          1503:                notify_payload_t *notify;
        !          1504:                payload_order_t order;
        !          1505: 
        !          1506:                order = this->rule->order[i];
        !          1507: 
        !          1508:                /* ... find all payload ... */
        !          1509:                enumerator = list->create_enumerator(list);
        !          1510:                while (enumerator->enumerate(enumerator, &payload))
        !          1511:                {
        !          1512:                        /* ... with that type ... */
        !          1513:                        if (payload->get_type(payload) == order.type)
        !          1514:                        {
        !          1515:                                notify = (notify_payload_t*)payload;
        !          1516: 
        !          1517:                                /**... and check notify for type. */
        !          1518:                                if (order.type != PLV2_NOTIFY || order.notify == 0 ||
        !          1519:                                        order.notify == notify->get_notify_type(notify))
        !          1520:                                {
        !          1521:                                        list->remove_at(list, enumerator);
        !          1522:                                        add_payload(this, payload);
        !          1523:                                }
        !          1524:                        }
        !          1525:                }
        !          1526:                enumerator->destroy(enumerator);
        !          1527:        }
        !          1528:        /* append all payloads without a rule to the end */
        !          1529:        while (list->remove_last(list, (void**)&payload) == SUCCESS)
        !          1530:        {
        !          1531:                /* do not complain about payloads in private use space */
        !          1532:                if (payload->get_type(payload) < 128)
        !          1533:                {
        !          1534:                        DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s",
        !          1535:                                 payload_type_names, payload->get_type(payload),
        !          1536:                                 exchange_type_names, this->rule->exchange_type,
        !          1537:                                 this->rule->is_request ? "request" : "response");
        !          1538:                }
        !          1539:                add_payload(this, payload);
        !          1540:        }
        !          1541:        list->destroy(list);
        !          1542: }
        !          1543: 
        !          1544: /**
        !          1545:  * Wrap payloads in an encrypted payload
        !          1546:  */
        !          1547: static encrypted_payload_t* wrap_payloads(private_message_t *this)
        !          1548: {
        !          1549:        encrypted_payload_t *encrypted = NULL;
        !          1550:        linked_list_t *payloads;
        !          1551:        payload_t *current;
        !          1552: 
        !          1553:        /* move all payloads to a temporary list */
        !          1554:        payloads = linked_list_create();
        !          1555:        while (this->payloads->remove_first(this->payloads,
        !          1556:                                                                                (void**)&current) == SUCCESS)
        !          1557:        {
        !          1558:                if (current->get_type(current) == PLV2_FRAGMENT)
        !          1559:                {       /* treat encrypted fragment payload as encrypted payload */
        !          1560:                        encrypted = (encrypted_payload_t*)current;
        !          1561:                }
        !          1562:                else
        !          1563:                {
        !          1564:                        payloads->insert_last(payloads, current);
        !          1565:                }
        !          1566:        }
        !          1567:        if (encrypted)
        !          1568:        {       /* simply adopt all the unencrypted payloads */
        !          1569:                this->payloads->destroy(this->payloads);
        !          1570:                this->payloads = payloads;
        !          1571:                return encrypted;
        !          1572:        }
        !          1573: 
        !          1574:        if (this->is_encrypted)
        !          1575:        {
        !          1576:                encrypted = encrypted_payload_create(PLV1_ENCRYPTED);
        !          1577:        }
        !          1578:        else
        !          1579:        {
        !          1580:                encrypted = encrypted_payload_create(PLV2_ENCRYPTED);
        !          1581:        }
        !          1582:        while (payloads->remove_first(payloads, (void**)&current) == SUCCESS)
        !          1583:        {
        !          1584:                payload_rule_t *rule;
        !          1585:                payload_type_t type;
        !          1586:                bool encrypt = TRUE;
        !          1587: 
        !          1588:                type = current->get_type(current);
        !          1589:                rule = get_payload_rule(this, type);
        !          1590:                if (rule)
        !          1591:                {
        !          1592:                        encrypt = rule->encrypted;
        !          1593:                }
        !          1594:                if (encrypt || this->is_encrypted)
        !          1595:                {       /* encryption is forced for IKEv1 */
        !          1596:                        DBG2(DBG_ENC, "insert payload %N into encrypted payload",
        !          1597:                                 payload_type_names, type);
        !          1598:                        encrypted->add_payload(encrypted, current);
        !          1599:                }
        !          1600:                else
        !          1601:                {
        !          1602:                        DBG2(DBG_ENC, "insert payload %N unencrypted",
        !          1603:                                 payload_type_names, type);
        !          1604:                        add_payload(this, current);
        !          1605:                }
        !          1606:        }
        !          1607:        payloads->destroy(payloads);
        !          1608: 
        !          1609:        return encrypted;
        !          1610: }
        !          1611: 
        !          1612: /**
        !          1613:  * Creates the IKE header for this message
        !          1614:  */
        !          1615: static ike_header_t *create_header(private_message_t *this)
        !          1616: {
        !          1617:        ike_header_t *ike_header;
        !          1618:        bool *reserved;
        !          1619:        int i;
        !          1620: 
        !          1621:        ike_header = ike_header_create_version(this->major_version,
        !          1622:                                                                                   this->minor_version);
        !          1623:        ike_header->set_exchange_type(ike_header, this->exchange_type);
        !          1624:        ike_header->set_message_id(ike_header, this->message_id);
        !          1625:        if (this->major_version == IKEV2_MAJOR_VERSION)
        !          1626:        {
        !          1627:                ike_header->set_response_flag(ike_header, !this->is_request);
        !          1628:                ike_header->set_version_flag(ike_header, this->version_flag);
        !          1629:                ike_header->set_initiator_flag(ike_header,
        !          1630:                                                this->ike_sa_id->is_initiator(this->ike_sa_id));
        !          1631:        }
        !          1632:        else
        !          1633:        {
        !          1634:                ike_header->set_encryption_flag(ike_header, this->is_encrypted);
        !          1635:        }
        !          1636:        ike_header->set_initiator_spi(ike_header,
        !          1637:                                                this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
        !          1638:        ike_header->set_responder_spi(ike_header,
        !          1639:                                                this->ike_sa_id->get_responder_spi(this->ike_sa_id));
        !          1640: 
        !          1641:        for (i = 0; i < countof(this->reserved); i++)
        !          1642:        {
        !          1643:                reserved = payload_get_field(&ike_header->payload_interface,
        !          1644:                                                                         RESERVED_BIT, i);
        !          1645:                if (reserved)
        !          1646:                {
        !          1647:                        *reserved = this->reserved[i];
        !          1648:                }
        !          1649:        }
        !          1650:        return ike_header;
        !          1651: }
        !          1652: 
        !          1653: /**
        !          1654:  * Generates the message, if needed, wraps the payloads in an encrypted payload.
        !          1655:  *
        !          1656:  * The generator and the possible encrypted payload are returned.  The latter
        !          1657:  * is not yet encrypted (but the transform is set).  It is also not added to
        !          1658:  * the payload list (so unless there are unencrypted payloads that list will
        !          1659:  * be empty afterwards).
        !          1660:  */
        !          1661: static status_t generate_message(private_message_t *this, keymat_t *keymat,
        !          1662:                                generator_t **out_generator, encrypted_payload_t **encrypted)
        !          1663: {
        !          1664:        keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
        !          1665:        generator_t *generator;
        !          1666:        payload_type_t next_type;
        !          1667:        enumerator_t *enumerator;
        !          1668:        aead_t *aead = NULL;
        !          1669:        chunk_t hash = chunk_empty;
        !          1670:        char str[BUF_LEN];
        !          1671:        ike_header_t *ike_header;
        !          1672:        payload_t *payload, *next;
        !          1673:        bool encrypting = FALSE;
        !          1674: 
        !          1675:        if (this->exchange_type == EXCHANGE_TYPE_UNDEFINED)
        !          1676:        {
        !          1677:                DBG1(DBG_ENC, "exchange type is not defined");
        !          1678:                return INVALID_STATE;
        !          1679:        }
        !          1680: 
        !          1681:        if (this->packet->get_source(this->packet) == NULL ||
        !          1682:                this->packet->get_destination(this->packet) == NULL)
        !          1683:        {
        !          1684:                DBG1(DBG_ENC, "source/destination not defined");
        !          1685:                return INVALID_STATE;
        !          1686:        }
        !          1687: 
        !          1688:        this->rule = get_message_rule(this);
        !          1689:        if (!this->rule)
        !          1690:        {
        !          1691:                DBG1(DBG_ENC, "no message rules specified for this message type");
        !          1692:                return NOT_SUPPORTED;
        !          1693:        }
        !          1694: 
        !          1695:        if (!this->sort_disabled)
        !          1696:        {
        !          1697:                order_payloads(this);
        !          1698:        }
        !          1699: 
        !          1700:        if (keymat && keymat->get_version(keymat) == IKEV1)
        !          1701:        {
        !          1702:                /* get a hash for this message, if any is required */
        !          1703:                if (keymat_v1->get_hash_phase2(keymat_v1, &this->public, &hash))
        !          1704:                {       /* insert a HASH payload as first payload */
        !          1705:                        hash_payload_t *hash_payload;
        !          1706: 
        !          1707:                        hash_payload = hash_payload_create(PLV1_HASH);
        !          1708:                        hash_payload->set_hash(hash_payload, hash);
        !          1709:                        this->payloads->insert_first(this->payloads, hash_payload);
        !          1710:                        if (this->exchange_type == INFORMATIONAL_V1)
        !          1711:                        {
        !          1712:                                this->is_encrypted = encrypting = TRUE;
        !          1713:                        }
        !          1714:                        chunk_free(&hash);
        !          1715:                }
        !          1716:        }
        !          1717: 
        !          1718:        if (this->major_version == IKEV2_MAJOR_VERSION)
        !          1719:        {
        !          1720:                encrypting = this->rule->encrypted;
        !          1721:        }
        !          1722:        else if (!encrypting)
        !          1723:        {
        !          1724:                /* If at least one payload requires encryption, encrypt the message.
        !          1725:                 * If no key material is available, the flag will be reset below. */
        !          1726:                enumerator = this->payloads->create_enumerator(this->payloads);
        !          1727:                while (enumerator->enumerate(enumerator, (void**)&payload))
        !          1728:                {
        !          1729:                        payload_rule_t *rule;
        !          1730: 
        !          1731:                        rule = get_payload_rule(this, payload->get_type(payload));
        !          1732:                        if (rule && rule->encrypted)
        !          1733:                        {
        !          1734:                                this->is_encrypted = encrypting = TRUE;
        !          1735:                                break;
        !          1736:                        }
        !          1737:                }
        !          1738:                enumerator->destroy(enumerator);
        !          1739:        }
        !          1740: 
        !          1741:        DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
        !          1742: 
        !          1743:        if (keymat)
        !          1744:        {
        !          1745:                aead = keymat->get_aead(keymat, FALSE);
        !          1746:        }
        !          1747:        if (encrypting)
        !          1748:        {
        !          1749:                if (aead)
        !          1750:                {
        !          1751:                        *encrypted = wrap_payloads(this);
        !          1752:                        (*encrypted)->set_transform(*encrypted, aead);
        !          1753:                }
        !          1754:                else if (this->exchange_type == INFORMATIONAL ||
        !          1755:                                 this->exchange_type == INFORMATIONAL_V1)
        !          1756:                {       /* allow sending unencrypted INFORMATIONALs */
        !          1757:                        encrypting = FALSE;
        !          1758:                }
        !          1759:                else
        !          1760:                {
        !          1761:                        DBG1(DBG_ENC, "unable to encrypt payloads without AEAD transform");
        !          1762:                        return FAILED;
        !          1763:                }
        !          1764:        }
        !          1765:        if (!encrypting)
        !          1766:        {
        !          1767:                DBG2(DBG_ENC, "not encrypting payloads");
        !          1768:                this->is_encrypted = FALSE;
        !          1769:        }
        !          1770: 
        !          1771:        /* generate all payloads with proper next type */
        !          1772:        *out_generator = generator = generator_create();
        !          1773:        ike_header = create_header(this);
        !          1774:        payload = (payload_t*)ike_header;
        !          1775:        enumerator = create_payload_enumerator(this);
        !          1776:        while (enumerator->enumerate(enumerator, &next))
        !          1777:        {
        !          1778:                payload->set_next_type(payload, next->get_type(next));
        !          1779:                generator->generate_payload(generator, payload);
        !          1780:                payload = next;
        !          1781:        }
        !          1782:        enumerator->destroy(enumerator);
        !          1783: 
        !          1784:        next_type = PL_NONE;
        !          1785:        if (this->is_encrypted)
        !          1786:        {       /* for encrypted IKEv1 messages */
        !          1787:                next_type = (*encrypted)->payload_interface.get_next_type(
        !          1788:                                                                                                                (payload_t*)*encrypted);
        !          1789:        }
        !          1790:        else if (*encrypted)
        !          1791:        {       /* use proper IKEv2 encrypted (fragment) payload type */
        !          1792:                next_type = (*encrypted)->payload_interface.get_type(
        !          1793:                                                                                                                (payload_t*)*encrypted);
        !          1794:        }
        !          1795:        payload->set_next_type(payload, next_type);
        !          1796:        generator->generate_payload(generator, payload);
        !          1797:        ike_header->destroy(ike_header);
        !          1798:        return SUCCESS;
        !          1799: }
        !          1800: 
        !          1801: /**
        !          1802:  * Encrypts and adds the encrypted payload (if any) to the payload list and
        !          1803:  * finalizes the message generation.  Destroys the given generator.
        !          1804:  */
        !          1805: static status_t finalize_message(private_message_t *this, keymat_t *keymat,
        !          1806:                                                generator_t *generator, encrypted_payload_t *encrypted)
        !          1807: {
        !          1808:        keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
        !          1809:        chunk_t chunk;
        !          1810:        uint32_t *lenpos;
        !          1811: 
        !          1812:        if (encrypted)
        !          1813:        {
        !          1814:                if (this->is_encrypted)
        !          1815:                {       /* for IKEv1 instead of associated data we provide the IV */
        !          1816:                        if (!keymat_v1->get_iv(keymat_v1, this->message_id, &chunk))
        !          1817:                        {
        !          1818:                                generator->destroy(generator);
        !          1819:                                encrypted->destroy(encrypted);
        !          1820:                                return FAILED;
        !          1821:                        }
        !          1822:                }
        !          1823:                else
        !          1824:                {       /* build associated data (without header of encrypted payload) */
        !          1825:                        chunk = generator->get_chunk(generator, &lenpos);
        !          1826:                        /* fill in length, including encrypted payload */
        !          1827:                        htoun32(lenpos, chunk.len + encrypted->get_length(encrypted));
        !          1828:                }
        !          1829:                this->payloads->insert_last(this->payloads, encrypted);
        !          1830:                if (encrypted->encrypt(encrypted, this->message_id, chunk) != SUCCESS)
        !          1831:                {
        !          1832:                        generator->destroy(generator);
        !          1833:                        return INVALID_STATE;
        !          1834:                }
        !          1835:                generator->generate_payload(generator, &encrypted->payload_interface);
        !          1836:        }
        !          1837:        chunk = generator->get_chunk(generator, &lenpos);
        !          1838:        htoun32(lenpos, chunk.len);
        !          1839:        this->packet->set_data(this->packet, chunk_clone(chunk));
        !          1840:        if (this->is_encrypted && this->exchange_type != INFORMATIONAL_V1)
        !          1841:        {
        !          1842:                /* update the IV for the next IKEv1 message */
        !          1843:                chunk_t last_block;
        !          1844:                aead_t *aead;
        !          1845:                size_t bs;
        !          1846: 
        !          1847:                aead = keymat->get_aead(keymat, FALSE);
        !          1848:                bs = aead->get_block_size(aead);
        !          1849:                last_block = chunk_create(chunk.ptr + chunk.len - bs, bs);
        !          1850:                if (!keymat_v1->update_iv(keymat_v1, this->message_id, last_block) ||
        !          1851:                        !keymat_v1->confirm_iv(keymat_v1, this->message_id))
        !          1852:                {
        !          1853:                        generator->destroy(generator);
        !          1854:                        return FAILED;
        !          1855:                }
        !          1856:        }
        !          1857:        generator->destroy(generator);
        !          1858:        return SUCCESS;
        !          1859: }
        !          1860: 
        !          1861: METHOD(message_t, generate, status_t,
        !          1862:        private_message_t *this, keymat_t *keymat, packet_t **packet)
        !          1863: {
        !          1864:        generator_t *generator = NULL;
        !          1865:        encrypted_payload_t *encrypted = NULL;
        !          1866:        status_t status;
        !          1867: 
        !          1868:        status = generate_message(this, keymat, &generator, &encrypted);
        !          1869:        if (status != SUCCESS)
        !          1870:        {
        !          1871:                DESTROY_IF(generator);
        !          1872:                return status;
        !          1873:        }
        !          1874:        status = finalize_message(this, keymat, generator, encrypted);
        !          1875:        if (status != SUCCESS)
        !          1876:        {
        !          1877:                return status;
        !          1878:        }
        !          1879:        if (packet)
        !          1880:        {
        !          1881:                *packet = this->packet->clone(this->packet);
        !          1882:        }
        !          1883:        return SUCCESS;
        !          1884: }
        !          1885: 
        !          1886: /**
        !          1887:  * Creates a (basic) clone of the given message
        !          1888:  */
        !          1889: static message_t *clone_message(private_message_t *this)
        !          1890: {
        !          1891:        message_t *message;
        !          1892:        host_t *src, *dst;
        !          1893: 
        !          1894:        src = this->packet->get_source(this->packet);
        !          1895:        dst = this->packet->get_destination(this->packet);
        !          1896: 
        !          1897:        message = message_create(this->major_version, this->minor_version);
        !          1898:        message->set_ike_sa_id(message, this->ike_sa_id);
        !          1899:        message->set_message_id(message, this->message_id);
        !          1900:        message->set_request(message, this->is_request);
        !          1901:        message->set_source(message, src->clone(src));
        !          1902:        message->set_destination(message, dst->clone(dst));
        !          1903:        message->set_exchange_type(message, this->exchange_type);
        !          1904:        memcpy(((private_message_t*)message)->reserved, this->reserved,
        !          1905:                   sizeof(this->reserved));
        !          1906:        return message;
        !          1907: }
        !          1908: 
        !          1909: /**
        !          1910:  * Create a single fragment with the given data
        !          1911:  */
        !          1912: static message_t *create_fragment(private_message_t *this, payload_type_t next,
        !          1913:                                                                  uint16_t num, uint16_t count, chunk_t data)
        !          1914: {
        !          1915:        enumerator_t *enumerator;
        !          1916:        payload_t *fragment, *payload;
        !          1917:        message_t *message;
        !          1918:        peer_cfg_t *peer_cfg;
        !          1919:        ike_sa_t *ike_sa;
        !          1920: 
        !          1921:        message = clone_message(this);
        !          1922:        if (this->major_version == IKEV1_MAJOR_VERSION)
        !          1923:        {
        !          1924:                /* other implementations seem to just use 0 as message ID, so here we go */
        !          1925:                message->set_message_id(message, 0);
        !          1926:                /* always use the initial message type for fragments, even for quick mode
        !          1927:                 * or transaction messages. */
        !          1928:                ike_sa = charon->bus->get_sa(charon->bus);
        !          1929:                if (ike_sa && (peer_cfg = ike_sa->get_peer_cfg(ike_sa)) &&
        !          1930:                        peer_cfg->use_aggressive(peer_cfg))
        !          1931:                {
        !          1932:                        message->set_exchange_type(message, AGGRESSIVE);
        !          1933:                }
        !          1934:                else
        !          1935:                {
        !          1936:                        message->set_exchange_type(message, ID_PROT);
        !          1937:                }
        !          1938:                fragment = (payload_t*)fragment_payload_create_from_data(
        !          1939:                                                                                                        num, num == count, data);
        !          1940:        }
        !          1941:        else
        !          1942:        {
        !          1943:                fragment = (payload_t*)encrypted_fragment_payload_create_from_data(
        !          1944:                                                                                                        num, count, data);
        !          1945:                if (num == 1)
        !          1946:                {
        !          1947:                        /* only in the first fragment is this set to the type of the first
        !          1948:                         * payload in the encrypted payload */
        !          1949:                        fragment->set_next_type(fragment, next);
        !          1950:                        /* move unencrypted payloads to the first fragment */
        !          1951:                        enumerator = this->payloads->create_enumerator(this->payloads);
        !          1952:                        while (enumerator->enumerate(enumerator, &payload))
        !          1953:                        {
        !          1954:                                if (payload->get_type(payload) != PLV2_ENCRYPTED)
        !          1955:                                {
        !          1956:                                        this->payloads->remove_at(this->payloads, enumerator);
        !          1957:                                        message->add_payload(message, payload);
        !          1958:                                }
        !          1959:                        }
        !          1960:                        enumerator->destroy(enumerator);
        !          1961:                }
        !          1962:        }
        !          1963:        message->add_payload(message, (payload_t*)fragment);
        !          1964:        return message;
        !          1965: }
        !          1966: 
        !          1967: /**
        !          1968:  * Destroy all fragments
        !          1969:  */
        !          1970: static void clear_fragments(private_message_t *this)
        !          1971: {
        !          1972:        array_destroy_offset(this->fragments, offsetof(packet_t, destroy));
        !          1973:        this->fragments = NULL;
        !          1974: }
        !          1975: 
        !          1976: /**
        !          1977:  * Reduce the fragment length but ensure it stays > 0
        !          1978:  */
        !          1979: #define REDUCE_FRAG_LEN(fl, amount) ({ \
        !          1980:        fl = max(1, (ssize_t)fl - (amount)); \
        !          1981: })
        !          1982: 
        !          1983: METHOD(message_t, fragment, status_t,
        !          1984:        private_message_t *this, keymat_t *keymat, size_t frag_len,
        !          1985:        enumerator_t **fragments)
        !          1986: {
        !          1987:        encrypted_payload_t *encrypted = NULL;
        !          1988:        generator_t *generator = NULL;
        !          1989:        message_t *fragment;
        !          1990:        packet_t *packet;
        !          1991:        payload_type_t next = PL_NONE;
        !          1992:        uint16_t num, count;
        !          1993:        host_t *src, *dst;
        !          1994:        chunk_t data;
        !          1995:        status_t status;
        !          1996:        uint32_t *lenpos;
        !          1997:        size_t len;
        !          1998: 
        !          1999:        src = this->packet->get_source(this->packet);
        !          2000:        dst = this->packet->get_destination(this->packet);
        !          2001:        if (!frag_len)
        !          2002:        {
        !          2003:                frag_len = (src->get_family(src) == AF_INET) ? 576 : 1280;
        !          2004:        }
        !          2005:        /* frag_len is the complete IP datagram length, account for overhead (we
        !          2006:         * assume no IP options/extension headers are used) */
        !          2007:        REDUCE_FRAG_LEN(frag_len, (src->get_family(src) == AF_INET) ? 20 : 40);
        !          2008:        /* 8 (UDP header) */
        !          2009:        REDUCE_FRAG_LEN(frag_len, 8);
        !          2010:        if (dst->get_port(dst) != IKEV2_UDP_PORT &&
        !          2011:                src->get_port(src) != IKEV2_UDP_PORT)
        !          2012:        {       /* reduce length due to non-ESP marker */
        !          2013:                REDUCE_FRAG_LEN(frag_len, 4);
        !          2014:        }
        !          2015: 
        !          2016:        if (is_encoded(this))
        !          2017:        {
        !          2018:                if (this->major_version == IKEV2_MAJOR_VERSION)
        !          2019:                {
        !          2020:                        encrypted = (encrypted_payload_t*)get_payload(this, PLV2_ENCRYPTED);
        !          2021:                }
        !          2022:                data = this->packet->get_data(this->packet);
        !          2023:                len = data.len;
        !          2024:        }
        !          2025:        else
        !          2026:        {
        !          2027:                status = generate_message(this, keymat, &generator, &encrypted);
        !          2028:                if (status != SUCCESS)
        !          2029:                {
        !          2030:                        DESTROY_IF(generator);
        !          2031:                        return status;
        !          2032:                }
        !          2033:                data = generator->get_chunk(generator, &lenpos);
        !          2034:                len = data.len + (encrypted ? encrypted->get_length(encrypted) : 0);
        !          2035:        }
        !          2036: 
        !          2037:        /* check if we actually need to fragment the message and if we have an
        !          2038:         * encrypted payload for IKEv2 */
        !          2039:        if (len <= frag_len ||
        !          2040:           (this->major_version == IKEV2_MAJOR_VERSION && !encrypted))
        !          2041:        {
        !          2042:                if (generator)
        !          2043:                {
        !          2044:                        status = finalize_message(this, keymat, generator, encrypted);
        !          2045:                        if (status != SUCCESS)
        !          2046:                        {
        !          2047:                                return status;
        !          2048:                        }
        !          2049:                }
        !          2050:                *fragments = enumerator_create_single(this->packet, NULL);
        !          2051:                return SUCCESS;
        !          2052:        }
        !          2053: 
        !          2054:        /* frag_len denoted the maximum IKE message size so far, later on it will
        !          2055:         * denote the maximum content size of a fragment payload, therefore,
        !          2056:         * account for IKE header */
        !          2057:        REDUCE_FRAG_LEN(frag_len, 28);
        !          2058: 
        !          2059:        if (this->major_version == IKEV1_MAJOR_VERSION)
        !          2060:        {
        !          2061:                if (generator)
        !          2062:                {
        !          2063:                        status = finalize_message(this, keymat, generator, encrypted);
        !          2064:                        if (status != SUCCESS)
        !          2065:                        {
        !          2066:                                return status;
        !          2067:                        }
        !          2068:                        data = this->packet->get_data(this->packet);
        !          2069:                        generator = NULL;
        !          2070:                }
        !          2071:                /* overhead for the fragmentation payload header */
        !          2072:                REDUCE_FRAG_LEN(frag_len, 8);
        !          2073:        }
        !          2074:        else
        !          2075:        {
        !          2076:                aead_t *aead;
        !          2077: 
        !          2078:                if (generator)
        !          2079:                {
        !          2080:                        generator->destroy(generator);
        !          2081:                        generator = generator_create();
        !          2082:                }
        !          2083:                else
        !          2084:                {       /* do not log again if it was generated previously */
        !          2085:                        generator = generator_create_no_dbg();
        !          2086:                }
        !          2087:                next = encrypted->payload_interface.get_next_type((payload_t*)encrypted);
        !          2088:                encrypted->generate_payloads(encrypted, generator);
        !          2089:                data = generator->get_chunk(generator, &lenpos);
        !          2090:                if (!is_encoded(this))
        !          2091:                {
        !          2092:                        encrypted->destroy(encrypted);
        !          2093:                }
        !          2094:                aead = keymat->get_aead(keymat, FALSE);
        !          2095:                /* overhead for the encrypted fragment payload */
        !          2096:                REDUCE_FRAG_LEN(frag_len, aead->get_iv_size(aead));
        !          2097:                REDUCE_FRAG_LEN(frag_len, aead->get_icv_size(aead));
        !          2098:                /* header */
        !          2099:                REDUCE_FRAG_LEN(frag_len, 8);
        !          2100:                /* padding and padding length */
        !          2101:                frag_len = round_down(frag_len, aead->get_block_size(aead));
        !          2102:                REDUCE_FRAG_LEN(frag_len, 1);
        !          2103:                /* TODO-FRAG: if there are unencrypted payloads, should we account for
        !          2104:                 * their length in the first fragment? we still would have to add
        !          2105:                 * an encrypted fragment payload (albeit empty), even so we couldn't
        !          2106:                 * prevent IP fragmentation in every case */
        !          2107:        }
        !          2108: 
        !          2109:        count = data.len / frag_len + (data.len % frag_len ? 1 : 0);
        !          2110:        this->fragments = array_create(0, count);
        !          2111:        DBG1(DBG_ENC, "splitting IKE message (%zu bytes) into %hu fragments", len,
        !          2112:                 count);
        !          2113:        for (num = 1; num <= count; num++)
        !          2114:        {
        !          2115:                len = min(data.len, frag_len);
        !          2116:                fragment = create_fragment(this, next, num, count,
        !          2117:                                                                   chunk_create(data.ptr, len));
        !          2118:                status = fragment->generate(fragment, keymat, &packet);
        !          2119:                fragment->destroy(fragment);
        !          2120:                if (status != SUCCESS)
        !          2121:                {
        !          2122:                        DBG1(DBG_ENC, "failed to generate IKE fragment");
        !          2123:                        clear_fragments(this);
        !          2124:                        DESTROY_IF(generator);
        !          2125:                        return FAILED;
        !          2126:                }
        !          2127:                array_insert(this->fragments, ARRAY_TAIL, packet);
        !          2128:                data = chunk_skip(data, len);
        !          2129:        }
        !          2130:        *fragments = array_create_enumerator(this->fragments);
        !          2131:        DESTROY_IF(generator);
        !          2132:        return SUCCESS;
        !          2133: }
        !          2134: 
        !          2135: METHOD(message_t, get_packet, packet_t*,
        !          2136:        private_message_t *this)
        !          2137: {
        !          2138:        return this->packet->clone(this->packet);
        !          2139: }
        !          2140: 
        !          2141: METHOD(message_t, get_packet_data, chunk_t,
        !          2142:        private_message_t *this)
        !          2143: {
        !          2144:        return this->packet->get_data(this->packet);
        !          2145: }
        !          2146: 
        !          2147: METHOD(message_t, get_fragments, enumerator_t*,
        !          2148:        private_message_t *this)
        !          2149: {
        !          2150:        return array_create_enumerator(this->fragments);
        !          2151: }
        !          2152: 
        !          2153: METHOD(message_t, parse_header, status_t,
        !          2154:        private_message_t *this)
        !          2155: {
        !          2156:        ike_header_t *ike_header;
        !          2157:        status_t status;
        !          2158:        bool *reserved;
        !          2159:        int i;
        !          2160: 
        !          2161:        DBG2(DBG_ENC, "parsing header of message");
        !          2162: 
        !          2163:        if (!this->parser)
        !          2164:        {       /* reassembled IKEv2 message, header is inherited from fragments */
        !          2165:                return SUCCESS;
        !          2166:        }
        !          2167:        this->parser->reset_context(this->parser);
        !          2168:        status = this->parser->parse_payload(this->parser, PL_HEADER,
        !          2169:                                                                                 (payload_t**)&ike_header);
        !          2170:        if (status != SUCCESS)
        !          2171:        {
        !          2172:                DBG1(DBG_ENC, "header could not be parsed");
        !          2173:                return status;
        !          2174: 
        !          2175:        }
        !          2176: 
        !          2177:        status = ike_header->payload_interface.verify(
        !          2178:                                                                                &ike_header->payload_interface);
        !          2179:        if (status != SUCCESS)
        !          2180:        {
        !          2181:                DBG1(DBG_ENC, "header verification failed");
        !          2182:                ike_header->destroy(ike_header);
        !          2183:                return status;
        !          2184:        }
        !          2185: 
        !          2186:        DESTROY_IF(this->ike_sa_id);
        !          2187:        this->ike_sa_id = ike_sa_id_create(
        !          2188:                                                                        ike_header->get_maj_version(ike_header),
        !          2189:                                                                        ike_header->get_initiator_spi(ike_header),
        !          2190:                                                                        ike_header->get_responder_spi(ike_header),
        !          2191:                                                                        ike_header->get_initiator_flag(ike_header));
        !          2192: 
        !          2193:        this->exchange_type = ike_header->get_exchange_type(ike_header);
        !          2194:        this->message_id = ike_header->get_message_id(ike_header);
        !          2195:        this->major_version = ike_header->get_maj_version(ike_header);
        !          2196:        this->minor_version = ike_header->get_min_version(ike_header);
        !          2197:        if (this->major_version == IKEV2_MAJOR_VERSION)
        !          2198:        {
        !          2199:                this->is_request = !ike_header->get_response_flag(ike_header);
        !          2200:        }
        !          2201:        else
        !          2202:        {
        !          2203:                this->is_encrypted = ike_header->get_encryption_flag(ike_header);
        !          2204:        }
        !          2205:        this->first_payload = ike_header->payload_interface.get_next_type(
        !          2206:                                                                                                &ike_header->payload_interface);
        !          2207:        if (this->first_payload == PLV1_FRAGMENT && this->is_encrypted)
        !          2208:        {       /* racoon sets the encrypted bit when sending a fragment, but these
        !          2209:                 * messages are really not encrypted */
        !          2210:                this->is_encrypted = FALSE;
        !          2211:        }
        !          2212: 
        !          2213:        for (i = 0; i < countof(this->reserved); i++)
        !          2214:        {
        !          2215:                reserved = payload_get_field(&ike_header->payload_interface,
        !          2216:                                                                         RESERVED_BIT, i);
        !          2217:                if (reserved)
        !          2218:                {
        !          2219:                        this->reserved[i] = *reserved;
        !          2220:                }
        !          2221:        }
        !          2222:        ike_header->destroy(ike_header);
        !          2223: 
        !          2224:        this->parser->set_major_version(this->parser, this->major_version);
        !          2225: 
        !          2226:        DBG2(DBG_ENC, "parsed a %N %s header", exchange_type_names,
        !          2227:                 this->exchange_type, this->major_version == IKEV1_MAJOR_VERSION ?
        !          2228:                 "message" : (this->is_request ? "request" : "response"));
        !          2229:        return SUCCESS;
        !          2230: }
        !          2231: 
        !          2232: /**
        !          2233:  * Check if a payload is for a mediation extension connectivity check
        !          2234:  */
        !          2235: static bool is_connectivity_check(private_message_t *this, payload_t *payload)
        !          2236: {
        !          2237: #ifdef ME
        !          2238:        if (this->exchange_type == INFORMATIONAL &&
        !          2239:                payload->get_type(payload) == PLV2_NOTIFY)
        !          2240:        {
        !          2241:                notify_payload_t *notify = (notify_payload_t*)payload;
        !          2242: 
        !          2243:                switch (notify->get_notify_type(notify))
        !          2244:                {
        !          2245:                        case ME_CONNECTID:
        !          2246:                        case ME_ENDPOINT:
        !          2247:                        case ME_CONNECTAUTH:
        !          2248:                                return TRUE;
        !          2249:                        default:
        !          2250:                                break;
        !          2251:                }
        !          2252:        }
        !          2253: #endif /* !ME */
        !          2254:        return FALSE;
        !          2255: }
        !          2256: 
        !          2257: /**
        !          2258:  * Parses and verifies the unencrypted payloads contained in the message
        !          2259:  */
        !          2260: static status_t parse_payloads(private_message_t *this)
        !          2261: {
        !          2262:        payload_type_t type = this->first_payload;
        !          2263:        payload_t *payload;
        !          2264:        status_t status;
        !          2265: 
        !          2266:        if (this->is_encrypted)
        !          2267:        {       /* wrap the whole encrypted IKEv1 message in a special encrypted
        !          2268:                 * payload which is then handled just like a regular payload */
        !          2269:                encrypted_payload_t *encryption;
        !          2270: 
        !          2271:                status = this->parser->parse_payload(this->parser, PLV1_ENCRYPTED,
        !          2272:                                                                                         (payload_t**)&encryption);
        !          2273:                if (status != SUCCESS)
        !          2274:                {
        !          2275:                        DBG1(DBG_ENC, "failed to wrap encrypted IKEv1 message");
        !          2276:                        return PARSE_ERROR;
        !          2277:                }
        !          2278:                encryption->payload_interface.set_next_type((payload_t*)encryption,
        !          2279:                                                                                                        this->first_payload);
        !          2280:                this->payloads->insert_last(this->payloads, encryption);
        !          2281:                return SUCCESS;
        !          2282:        }
        !          2283: 
        !          2284:        while (type != PL_NONE)
        !          2285:        {
        !          2286:                DBG2(DBG_ENC, "starting parsing a %N payload",
        !          2287:                         payload_type_names, type);
        !          2288: 
        !          2289:                status = this->parser->parse_payload(this->parser, type, &payload);
        !          2290:                if (status != SUCCESS)
        !          2291:                {
        !          2292:                        DBG1(DBG_ENC, "payload type %N could not be parsed",
        !          2293:                                 payload_type_names, type);
        !          2294:                        return PARSE_ERROR;
        !          2295:                }
        !          2296: 
        !          2297:                DBG2(DBG_ENC, "verifying payload of type %N", payload_type_names, type);
        !          2298:                status = payload->verify(payload);
        !          2299:                if (status != SUCCESS)
        !          2300:                {
        !          2301:                        DBG1(DBG_ENC, "%N payload verification failed",
        !          2302:                                 payload_type_names, type);
        !          2303:                        payload->destroy(payload);
        !          2304:                        return VERIFY_ERROR;
        !          2305:                }
        !          2306:                if (payload->get_type(payload) == PL_UNKNOWN)
        !          2307:                {
        !          2308:                        DBG2(DBG_ENC, "%N payload unknown or not allowed",
        !          2309:                                 payload_type_names, type);
        !          2310:                }
        !          2311:                else
        !          2312:                {
        !          2313:                        DBG2(DBG_ENC, "%N payload verified, adding to payload list",
        !          2314:                                 payload_type_names, type);
        !          2315:                }
        !          2316:                this->payloads->insert_last(this->payloads, payload);
        !          2317: 
        !          2318:                /* an encrypted (fragment) payload MUST be the last one, so STOP here.
        !          2319:                 * decryption is done later */
        !          2320:                if (type == PLV2_ENCRYPTED || type == PLV2_FRAGMENT)
        !          2321:                {
        !          2322:                        DBG2(DBG_ENC, "%N payload found, stop parsing",
        !          2323:                                 payload_type_names, type);
        !          2324:                        break;
        !          2325:                }
        !          2326:                type = payload->get_next_type(payload);
        !          2327:        }
        !          2328:        return SUCCESS;
        !          2329: }
        !          2330: 
        !          2331: /**
        !          2332:  * Decrypt an encrypted payload and extract all contained payloads.
        !          2333:  */
        !          2334: static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat,
        !          2335:                                                payload_t *previous, encrypted_payload_t *encryption)
        !          2336: {
        !          2337:        payload_t *encrypted;
        !          2338:        payload_type_t type;
        !          2339:        chunk_t chunk;
        !          2340:        aead_t *aead;
        !          2341:        size_t bs;
        !          2342:        status_t status = SUCCESS;
        !          2343: 
        !          2344:        if (!keymat)
        !          2345:        {
        !          2346:                DBG1(DBG_ENC, "found encrypted payload, but no keymat");
        !          2347:                return INVALID_ARG;
        !          2348:        }
        !          2349:        aead = keymat->get_aead(keymat, TRUE);
        !          2350:        if (!aead)
        !          2351:        {
        !          2352:                DBG1(DBG_ENC, "found encrypted payload, but no transform set");
        !          2353:                return INVALID_ARG;
        !          2354:        }
        !          2355:        if (!this->parser)
        !          2356:        {
        !          2357:                /* reassembled IKEv2 messages are already decrypted, we still call
        !          2358:                 * decrypt() to parse the contained payloads */
        !          2359:                status = encryption->decrypt(encryption, chunk_empty);
        !          2360:        }
        !          2361:        else
        !          2362:        {
        !          2363:                bs = aead->get_block_size(aead);
        !          2364:                encryption->set_transform(encryption, aead);
        !          2365:                chunk = this->packet->get_data(this->packet);
        !          2366:                if (chunk.len < encryption->get_length(encryption) ||
        !          2367:                        chunk.len < bs)
        !          2368:                {
        !          2369:                        DBG1(DBG_ENC, "invalid payload length");
        !          2370:                        return VERIFY_ERROR;
        !          2371:                }
        !          2372:                if (keymat->get_version(keymat) == IKEV1)
        !          2373:                {       /* instead of associated data we provide the IV, we also update
        !          2374:                         * the IV with the last encrypted block */
        !          2375:                        keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
        !          2376:                        chunk_t iv;
        !          2377: 
        !          2378:                        if (keymat_v1->get_iv(keymat_v1, this->message_id, &iv))
        !          2379:                        {
        !          2380:                                status = encryption->decrypt(encryption, iv);
        !          2381:                                if (status == SUCCESS)
        !          2382:                                {
        !          2383:                                        if (!keymat_v1->update_iv(keymat_v1, this->message_id,
        !          2384:                                                        chunk_create(chunk.ptr + chunk.len - bs, bs)))
        !          2385:                                        {
        !          2386:                                                status = FAILED;
        !          2387:                                        }
        !          2388:                                }
        !          2389:                        }
        !          2390:                        else
        !          2391:                        {
        !          2392:                                status = FAILED;
        !          2393:                        }
        !          2394:                }
        !          2395:                else
        !          2396:                {
        !          2397:                        chunk.len -= encryption->get_length(encryption);
        !          2398:                        status = encryption->decrypt(encryption, chunk);
        !          2399:                }
        !          2400:        }
        !          2401:        if (status != SUCCESS)
        !          2402:        {
        !          2403:                return status;
        !          2404:        }
        !          2405: 
        !          2406:        while ((encrypted = encryption->remove_payload(encryption)))
        !          2407:        {
        !          2408:                type = encrypted->get_type(encrypted);
        !          2409:                if (previous)
        !          2410:                {
        !          2411:                        previous->set_next_type(previous, type);
        !          2412:                }
        !          2413:                else
        !          2414:                {
        !          2415:                        this->first_payload = type;
        !          2416:                }
        !          2417:                DBG2(DBG_ENC, "insert decrypted payload of type %N at end of list",
        !          2418:                         payload_type_names, type);
        !          2419:                this->payloads->insert_last(this->payloads, encrypted);
        !          2420:                previous = encrypted;
        !          2421:        }
        !          2422:        return SUCCESS;
        !          2423: }
        !          2424: 
        !          2425: /**
        !          2426:  * Decrypt an encrypted fragment payload.
        !          2427:  */
        !          2428: static status_t decrypt_fragment(private_message_t *this, keymat_t *keymat,
        !          2429:                                                                 encrypted_fragment_payload_t *fragment)
        !          2430: {
        !          2431:        encrypted_payload_t *encrypted = (encrypted_payload_t*)fragment;
        !          2432:        chunk_t chunk;
        !          2433:        aead_t *aead;
        !          2434:        size_t bs;
        !          2435: 
        !          2436:        if (!keymat)
        !          2437:        {
        !          2438:                DBG1(DBG_ENC, "found encrypted fragment payload, but no keymat");
        !          2439:                return INVALID_ARG;
        !          2440:        }
        !          2441:        aead = keymat->get_aead(keymat, TRUE);
        !          2442:        if (!aead)
        !          2443:        {
        !          2444:                DBG1(DBG_ENC, "found encrypted fragment payload, but no transform set");
        !          2445:                return INVALID_ARG;
        !          2446:        }
        !          2447:        bs = aead->get_block_size(aead);
        !          2448:        encrypted->set_transform(encrypted, aead);
        !          2449:        chunk = this->packet->get_data(this->packet);
        !          2450:        if (chunk.len < encrypted->get_length(encrypted) ||
        !          2451:                chunk.len < bs)
        !          2452:        {
        !          2453:                DBG1(DBG_ENC, "invalid payload length");
        !          2454:                return VERIFY_ERROR;
        !          2455:        }
        !          2456:        chunk.len -= encrypted->get_length(encrypted);
        !          2457:        return encrypted->decrypt(encrypted, chunk);
        !          2458: }
        !          2459: 
        !          2460: /**
        !          2461:  * Do we accept unencrypted ID/HASH payloads in Main Mode, as seen from
        !          2462:  * some SonicWall boxes?
        !          2463:  */
        !          2464: static bool accept_unencrypted_mm(private_message_t *this, payload_type_t type)
        !          2465: {
        !          2466:        if (this->exchange_type == ID_PROT)
        !          2467:        {
        !          2468:                if (type == PLV1_ID || type == PLV1_HASH)
        !          2469:                {
        !          2470:                        return lib->settings->get_bool(lib->settings,
        !          2471:                                                                        "%s.accept_unencrypted_mainmode_messages",
        !          2472:                                                                        FALSE, lib->ns);
        !          2473:                }
        !          2474:        }
        !          2475:        return FALSE;
        !          2476: }
        !          2477: 
        !          2478: /**
        !          2479:  * Decrypt payload from the encrypted payload
        !          2480:  */
        !          2481: static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat)
        !          2482: {
        !          2483:        payload_t *payload, *previous = NULL;
        !          2484:        enumerator_t *enumerator;
        !          2485:        payload_rule_t *rule;
        !          2486:        payload_type_t type;
        !          2487:        status_t status = SUCCESS;
        !          2488:        char *was_encrypted = NULL;
        !          2489: 
        !          2490:        enumerator = this->payloads->create_enumerator(this->payloads);
        !          2491:        while (enumerator->enumerate(enumerator, &payload))
        !          2492:        {
        !          2493:                type = payload->get_type(payload);
        !          2494: 
        !          2495:                DBG2(DBG_ENC, "process payload of type %N", payload_type_names, type);
        !          2496: 
        !          2497:                if (type == PLV2_ENCRYPTED || type == PLV1_ENCRYPTED ||
        !          2498:                        type == PLV2_FRAGMENT)
        !          2499:                {
        !          2500:                        if (was_encrypted)
        !          2501:                        {
        !          2502:                                DBG1(DBG_ENC, "%s can't contain other payloads of type %N",
        !          2503:                                         was_encrypted, payload_type_names, type);
        !          2504:                                status = VERIFY_ERROR;
        !          2505:                                break;
        !          2506:                        }
        !          2507:                }
        !          2508: 
        !          2509:                if (type == PLV2_ENCRYPTED || type == PLV1_ENCRYPTED)
        !          2510:                {
        !          2511:                        encrypted_payload_t *encryption;
        !          2512: 
        !          2513:                        DBG2(DBG_ENC, "found an encrypted payload");
        !          2514:                        encryption = (encrypted_payload_t*)payload;
        !          2515:                        this->payloads->remove_at(this->payloads, enumerator);
        !          2516: 
        !          2517:                        if (enumerator->enumerate(enumerator, NULL))
        !          2518:                        {
        !          2519:                                DBG1(DBG_ENC, "encrypted payload is not last payload");
        !          2520:                                encryption->destroy(encryption);
        !          2521:                                status = VERIFY_ERROR;
        !          2522:                                break;
        !          2523:                        }
        !          2524:                        status = decrypt_and_extract(this, keymat, previous, encryption);
        !          2525:                        encryption->destroy(encryption);
        !          2526:                        if (status != SUCCESS)
        !          2527:                        {
        !          2528:                                break;
        !          2529:                        }
        !          2530:                        was_encrypted = "encrypted payload";
        !          2531:                }
        !          2532:                else if (type == PLV2_FRAGMENT)
        !          2533:                {
        !          2534:                        encrypted_fragment_payload_t *fragment;
        !          2535: 
        !          2536:                        DBG2(DBG_ENC, "found an encrypted fragment payload");
        !          2537:                        fragment = (encrypted_fragment_payload_t*)payload;
        !          2538: 
        !          2539:                        if (enumerator->enumerate(enumerator, NULL))
        !          2540:                        {
        !          2541:                                DBG1(DBG_ENC, "encrypted fragment payload is not last payload");
        !          2542:                                status = VERIFY_ERROR;
        !          2543:                                break;
        !          2544:                        }
        !          2545:                        status = decrypt_fragment(this, keymat, fragment);
        !          2546:                        if (status != SUCCESS)
        !          2547:                        {
        !          2548:                                break;
        !          2549:                        }
        !          2550:                        was_encrypted = "encrypted fragment payload";
        !          2551:                }
        !          2552: 
        !          2553:                if (type != PL_UNKNOWN && !was_encrypted &&
        !          2554:                        !is_connectivity_check(this, payload) &&
        !          2555:                        this->exchange_type != AGGRESSIVE)
        !          2556:                {
        !          2557:                        rule = get_payload_rule(this, type);
        !          2558:                        if ((!rule || rule->encrypted) &&
        !          2559:                                !accept_unencrypted_mm(this, type))
        !          2560:                        {
        !          2561:                                DBG1(DBG_ENC, "payload type %N was not encrypted",
        !          2562:                                         payload_type_names, type);
        !          2563:                                status = FAILED;
        !          2564:                                break;
        !          2565:                        }
        !          2566:                }
        !          2567:                previous = payload;
        !          2568:        }
        !          2569:        enumerator->destroy(enumerator);
        !          2570:        return status;
        !          2571: }
        !          2572: 
        !          2573: /**
        !          2574:  * Verify a message and all payload according to message/payload rules
        !          2575:  */
        !          2576: static status_t verify(private_message_t *this)
        !          2577: {
        !          2578:        bool complete = FALSE;
        !          2579:        int i;
        !          2580: 
        !          2581:        DBG2(DBG_ENC, "verifying message structure");
        !          2582: 
        !          2583:        /* check for payloads with wrong count */
        !          2584:        for (i = 0; i < this->rule->rule_count; i++)
        !          2585:        {
        !          2586:                enumerator_t *enumerator;
        !          2587:                payload_t *payload;
        !          2588:                payload_rule_t *rule;
        !          2589:                int found = 0;
        !          2590: 
        !          2591:                rule = &this->rule->rules[i];
        !          2592:                enumerator = create_payload_enumerator(this);
        !          2593:                while (enumerator->enumerate(enumerator, &payload))
        !          2594:                {
        !          2595:                        payload_type_t type;
        !          2596: 
        !          2597:                        type = payload->get_type(payload);
        !          2598:                        if (type == rule->type)
        !          2599:                        {
        !          2600:                                found++;
        !          2601:                                DBG2(DBG_ENC, "found payload of type %N",
        !          2602:                                         payload_type_names, type);
        !          2603:                                if (found > rule->max_occurrence)
        !          2604:                                {
        !          2605:                                        DBG1(DBG_ENC, "payload of type %N more than %d times (%d) "
        !          2606:                                                 "occurred in current message", payload_type_names,
        !          2607:                                                 type, rule->max_occurrence, found);
        !          2608:                                        enumerator->destroy(enumerator);
        !          2609:                                        return VERIFY_ERROR;
        !          2610:                                }
        !          2611:                        }
        !          2612:                }
        !          2613:                enumerator->destroy(enumerator);
        !          2614: 
        !          2615:                if (!complete && found < rule->min_occurrence)
        !          2616:                {
        !          2617:                        DBG1(DBG_ENC, "payload of type %N not occurred %d times (%d)",
        !          2618:                                 payload_type_names, rule->type, rule->min_occurrence, found);
        !          2619:                        return VERIFY_ERROR;
        !          2620:                }
        !          2621:                if (found && rule->sufficient)
        !          2622:                {
        !          2623:                        complete = TRUE;
        !          2624:                }
        !          2625:        }
        !          2626:        return SUCCESS;
        !          2627: }
        !          2628: 
        !          2629: METHOD(message_t, parse_body, status_t,
        !          2630:        private_message_t *this, keymat_t *keymat)
        !          2631: {
        !          2632:        status_t status = SUCCESS;
        !          2633:        char str[BUF_LEN];
        !          2634: 
        !          2635:        DBG2(DBG_ENC, "parsing body of message, first payload is %N",
        !          2636:                 payload_type_names, this->first_payload);
        !          2637: 
        !          2638:        this->rule = get_message_rule(this);
        !          2639:        if (!this->rule)
        !          2640:        {
        !          2641:                DBG1(DBG_ENC, "no message rules specified for a %N %s",
        !          2642:                         exchange_type_names, this->exchange_type,
        !          2643:                         this->is_request ? "request" : "response");
        !          2644:                return NOT_SUPPORTED;
        !          2645:        }
        !          2646: 
        !          2647:        /* reassembled IKEv2 messages are already parsed (except for the payloads
        !          2648:         * contained in the encrypted payload, which are handled below) */
        !          2649:        if (this->parser)
        !          2650:        {
        !          2651:                status = parse_payloads(this);
        !          2652:                if (status != SUCCESS)
        !          2653:                {       /* error is already logged */
        !          2654:                        return status;
        !          2655:                }
        !          2656:        }
        !          2657: 
        !          2658:        status = decrypt_payloads(this, keymat);
        !          2659:        if (status != SUCCESS)
        !          2660:        {
        !          2661:                DBG1(DBG_ENC, "could not decrypt payloads");
        !          2662:                return status;
        !          2663:        }
        !          2664: 
        !          2665:        status = verify(this);
        !          2666:        if (status != SUCCESS)
        !          2667:        {
        !          2668:                return status;
        !          2669:        }
        !          2670: 
        !          2671:        DBG1(DBG_ENC, "parsed %s", get_string(this, str, sizeof(str)));
        !          2672: 
        !          2673:        if (keymat && keymat->get_version(keymat) == IKEV1)
        !          2674:        {
        !          2675:                keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
        !          2676:                chunk_t hash;
        !          2677: 
        !          2678:                if (keymat_v1->get_hash_phase2(keymat_v1, &this->public, &hash))
        !          2679:                {
        !          2680:                        hash_payload_t *hash_payload;
        !          2681:                        chunk_t other_hash;
        !          2682: 
        !          2683:                        if (this->first_payload != PLV1_HASH)
        !          2684:                        {
        !          2685:                                if (this->exchange_type == INFORMATIONAL_V1)
        !          2686:                                {
        !          2687:                                        DBG1(DBG_ENC, "ignoring unprotected INFORMATIONAL from %H",
        !          2688:                                                 this->packet->get_source(this->packet));
        !          2689:                                }
        !          2690:                                else
        !          2691:                                {
        !          2692:                                        DBG1(DBG_ENC, "expected HASH payload as first payload");
        !          2693:                                }
        !          2694:                                chunk_free(&hash);
        !          2695:                                return VERIFY_ERROR;
        !          2696:                        }
        !          2697:                        hash_payload = (hash_payload_t*)get_payload(this, PLV1_HASH);
        !          2698:                        other_hash = hash_payload->get_hash(hash_payload);
        !          2699:                        DBG3(DBG_ENC, "HASH received %B\nHASH expected %B",
        !          2700:                                 &other_hash, &hash);
        !          2701:                        if (!chunk_equals_const(hash, other_hash))
        !          2702:                        {
        !          2703:                                DBG1(DBG_ENC, "received HASH payload does not match");
        !          2704:                                chunk_free(&hash);
        !          2705:                                return FAILED;
        !          2706:                        }
        !          2707:                        chunk_free(&hash);
        !          2708:                }
        !          2709:                if (this->is_encrypted && this->exchange_type != INFORMATIONAL_V1)
        !          2710:                {       /* message verified, confirm IV */
        !          2711:                        if (!keymat_v1->confirm_iv(keymat_v1, this->message_id))
        !          2712:                        {
        !          2713:                                return FAILED;
        !          2714:                        }
        !          2715:                }
        !          2716:        }
        !          2717:        return SUCCESS;
        !          2718: }
        !          2719: 
        !          2720: /**
        !          2721:  * Store the fragment data for the fragment with the given fragment number.
        !          2722:  */
        !          2723: static status_t add_fragment(private_message_t *this, uint16_t num,
        !          2724:                                                         chunk_t data)
        !          2725: {
        !          2726:        fragment_t *fragment;
        !          2727:        int i, insert_at = -1;
        !          2728: 
        !          2729:        for (i = 0; i < array_count(this->fragments); i++)
        !          2730:        {
        !          2731:                array_get(this->fragments, i, &fragment);
        !          2732:                if (fragment->num == num)
        !          2733:                {
        !          2734:                        /* ignore a duplicate fragment */
        !          2735:                        DBG1(DBG_ENC, "received duplicate fragment #%hu", num);
        !          2736:                        return NEED_MORE;
        !          2737:                }
        !          2738:                if (fragment->num > num)
        !          2739:                {
        !          2740:                        insert_at = i;
        !          2741:                        break;
        !          2742:                }
        !          2743:        }
        !          2744:        this->frag->len += data.len;
        !          2745:        if (this->frag->len > this->frag->max_packet)
        !          2746:        {
        !          2747:                DBG1(DBG_ENC, "fragmented IKE message is too large");
        !          2748:                reset_defrag(this);
        !          2749:                return FAILED;
        !          2750:        }
        !          2751:        INIT(fragment,
        !          2752:                .num = num,
        !          2753:                .data = chunk_clone(data),
        !          2754:        );
        !          2755:        array_insert(this->fragments, insert_at, fragment);
        !          2756:        return SUCCESS;
        !          2757: }
        !          2758: 
        !          2759: /**
        !          2760:  * Merge the cached fragment data and resets the defragmentation state.
        !          2761:  * Also updates the IP addresses to those of the last received fragment.
        !          2762:  */
        !          2763: static chunk_t merge_fragments(private_message_t *this, message_t *last)
        !          2764: {
        !          2765:        fragment_t *fragment;
        !          2766:        bio_writer_t *writer;
        !          2767:        host_t *src, *dst;
        !          2768:        chunk_t data;
        !          2769:        int i;
        !          2770: 
        !          2771:        writer = bio_writer_create(this->frag->len);
        !          2772:        for (i = 0; i < array_count(this->fragments); i++)
        !          2773:        {
        !          2774:                array_get(this->fragments, i, &fragment);
        !          2775:                writer->write_data(writer, fragment->data);
        !          2776:        }
        !          2777:        data = writer->extract_buf(writer);
        !          2778:        writer->destroy(writer);
        !          2779: 
        !          2780:        /* set addresses to those of the last fragment we received */
        !          2781:        src = last->get_source(last);
        !          2782:        dst = last->get_destination(last);
        !          2783:        this->packet->set_source(this->packet, src->clone(src));
        !          2784:        this->packet->set_destination(this->packet, dst->clone(dst));
        !          2785: 
        !          2786:        reset_defrag(this);
        !          2787:        free(this->frag);
        !          2788:        this->frag = NULL;
        !          2789:        return data;
        !          2790: }
        !          2791: 
        !          2792: METHOD(message_t, add_fragment_v1, status_t,
        !          2793:        private_message_t *this, message_t *message)
        !          2794: {
        !          2795:        fragment_payload_t *payload;
        !          2796:        chunk_t data;
        !          2797:        uint8_t num;
        !          2798:        status_t status;
        !          2799: 
        !          2800:        if (!this->frag)
        !          2801:        {
        !          2802:                return INVALID_STATE;
        !          2803:        }
        !          2804:        payload = (fragment_payload_t*)message->get_payload(message, PLV1_FRAGMENT);
        !          2805:        if (!payload)
        !          2806:        {
        !          2807:                return INVALID_ARG;
        !          2808:        }
        !          2809:        if (!this->fragments || this->message_id != payload->get_id(payload))
        !          2810:        {
        !          2811:                reset_defrag(this);
        !          2812:                this->message_id = payload->get_id(payload);
        !          2813:                /* we don't know the total number of fragments, assume something */
        !          2814:                this->fragments = array_create(0, 4);
        !          2815:        }
        !          2816: 
        !          2817:        num = payload->get_number(payload);
        !          2818:        data = payload->get_data(payload);
        !          2819:        if (!this->frag->last && payload->is_last(payload))
        !          2820:        {
        !          2821:                this->frag->last = num;
        !          2822:        }
        !          2823:        status = add_fragment(this, num, data);
        !          2824:        if (status != SUCCESS)
        !          2825:        {
        !          2826:                return status;
        !          2827:        }
        !          2828: 
        !          2829:        if (array_count(this->fragments) != this->frag->last)
        !          2830:        {
        !          2831:                /* there are some fragments missing */
        !          2832:                DBG1(DBG_ENC, "received fragment #%hhu, waiting for complete IKE "
        !          2833:                         "message", num);
        !          2834:                return NEED_MORE;
        !          2835:        }
        !          2836: 
        !          2837:        data = merge_fragments(this, message);
        !          2838:        this->packet->set_data(this->packet, data);
        !          2839:        DBG1(DBG_ENC, "received fragment #%hhu, reassembled fragmented IKE "
        !          2840:                 "message (%zu bytes)", num, data.len);
        !          2841: 
        !          2842:        this->parser = parser_create(data);
        !          2843: 
        !          2844:        if (parse_header(this) != SUCCESS)
        !          2845:        {
        !          2846:                DBG1(DBG_IKE, "failed to parse header of reassembled IKE message");
        !          2847:                return FAILED;
        !          2848:        }
        !          2849:        return SUCCESS;
        !          2850: }
        !          2851: 
        !          2852: METHOD(message_t, add_fragment_v2, status_t,
        !          2853:        private_message_t *this, message_t *message)
        !          2854: {
        !          2855:        encrypted_fragment_payload_t *encrypted_fragment;
        !          2856:        encrypted_payload_t *encrypted;
        !          2857:        payload_t *payload;
        !          2858:        aead_t *aead;
        !          2859:        enumerator_t *enumerator;
        !          2860:        chunk_t data;
        !          2861:        uint16_t total, num;
        !          2862:        size_t len;
        !          2863:        status_t status;
        !          2864: 
        !          2865:        if (!this->frag)
        !          2866:        {
        !          2867:                return INVALID_STATE;
        !          2868:        }
        !          2869:        payload = message->get_payload(message, PLV2_FRAGMENT);
        !          2870:        if (!payload || this->message_id != message->get_message_id(message))
        !          2871:        {
        !          2872:                return INVALID_ARG;
        !          2873:        }
        !          2874:        encrypted_fragment = (encrypted_fragment_payload_t*)payload;
        !          2875:        total = encrypted_fragment->get_total_fragments(encrypted_fragment);
        !          2876:        if (total > MAX_FRAGMENTS)
        !          2877:        {
        !          2878:                DBG1(DBG_IKE, "maximum fragment count exceeded");
        !          2879:                reset_defrag(this);
        !          2880:                return FAILED;
        !          2881:        }
        !          2882:        if (!this->fragments || total > this->frag->last)
        !          2883:        {
        !          2884:                reset_defrag(this);
        !          2885:                this->frag->last = total;
        !          2886:                this->fragments = array_create(0, total);
        !          2887:        }
        !          2888:        num = encrypted_fragment->get_fragment_number(encrypted_fragment);
        !          2889:        data = encrypted_fragment->get_content(encrypted_fragment);
        !          2890:        status = add_fragment(this, num, data);
        !          2891:        if (status != SUCCESS)
        !          2892:        {
        !          2893:                return status;
        !          2894:        }
        !          2895: 
        !          2896:        if (num == 1)
        !          2897:        {
        !          2898:                /* the first fragment denotes the payload type of the first payload in
        !          2899:                 * the original encrypted payload, cache that */
        !          2900:                this->first_payload = payload->get_next_type(payload);
        !          2901:                /* move all unencrypted payloads contained in the first fragment */
        !          2902:                enumerator = message->create_payload_enumerator(message);
        !          2903:                while (enumerator->enumerate(enumerator, &payload))
        !          2904:                {
        !          2905:                        if (payload->get_type(payload) != PLV2_FRAGMENT)
        !          2906:                        {
        !          2907:                                message->remove_payload_at(message, enumerator);
        !          2908:                                this->payloads->insert_last(this->payloads, payload);
        !          2909:                        }
        !          2910:                }
        !          2911:                enumerator->destroy(enumerator);
        !          2912:        }
        !          2913: 
        !          2914:        if (array_count(this->fragments) != total)
        !          2915:        {
        !          2916:                /* there are some fragments missing */
        !          2917:                DBG1(DBG_ENC, "received fragment #%hu of %hu, waiting for complete IKE "
        !          2918:                         "message", num, total);
        !          2919:                return NEED_MORE;
        !          2920:        }
        !          2921: 
        !          2922:        encrypted = (encrypted_payload_t*)encrypted_fragment;
        !          2923:        aead = encrypted->get_transform(encrypted);
        !          2924: 
        !          2925:        data = merge_fragments(this, message);
        !          2926: 
        !          2927:        encrypted = encrypted_payload_create_from_plain(this->first_payload, data);
        !          2928:        encrypted->set_transform(encrypted, aead);
        !          2929:        this->payloads->insert_last(this->payloads, encrypted);
        !          2930:        /* update next payload type (could be an unencrypted payload) */
        !          2931:        this->payloads->get_first(this->payloads, (void**)&payload);
        !          2932:        this->first_payload = payload->get_type(payload);
        !          2933: 
        !          2934:        /* we report the length of the complete IKE message when splitting, do the
        !          2935:         * same here, so add the IKEv2 header len to the reassembled payload data */
        !          2936:        len = 28;
        !          2937:        enumerator = create_payload_enumerator(this);
        !          2938:        while (enumerator->enumerate(enumerator, &payload))
        !          2939:        {
        !          2940:                len += payload->get_length(payload);
        !          2941:        }
        !          2942:        enumerator->destroy(enumerator);
        !          2943: 
        !          2944:        DBG1(DBG_ENC, "received fragment #%hu of %hu, reassembled fragmented IKE "
        !          2945:                 "message (%zu bytes)", num, total, len);
        !          2946:        return SUCCESS;
        !          2947: }
        !          2948: 
        !          2949: METHOD(message_t, destroy, void,
        !          2950:        private_message_t *this)
        !          2951: {
        !          2952:        DESTROY_IF(this->ike_sa_id);
        !          2953:        DESTROY_IF(this->parser);
        !          2954:        this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
        !          2955:        this->packet->destroy(this->packet);
        !          2956:        if (this->frag)
        !          2957:        {
        !          2958:                reset_defrag(this);
        !          2959:                free(this->frag);
        !          2960:        }
        !          2961:        else
        !          2962:        {
        !          2963:                array_destroy_offset(this->fragments, offsetof(packet_t, destroy));
        !          2964:        }
        !          2965:        free(this);
        !          2966: }
        !          2967: 
        !          2968: /*
        !          2969:  * Described in header.
        !          2970:  */
        !          2971: message_t *message_create_from_packet(packet_t *packet)
        !          2972: {
        !          2973:        private_message_t *this;
        !          2974: 
        !          2975:        INIT(this,
        !          2976:                .public = {
        !          2977:                        .set_major_version = _set_major_version,
        !          2978:                        .get_major_version = _get_major_version,
        !          2979:                        .set_minor_version = _set_minor_version,
        !          2980:                        .get_minor_version = _get_minor_version,
        !          2981:                        .set_message_id = _set_message_id,
        !          2982:                        .get_message_id = _get_message_id,
        !          2983:                        .get_initiator_spi = _get_initiator_spi,
        !          2984:                        .get_responder_spi = _get_responder_spi,
        !          2985:                        .set_ike_sa_id = _set_ike_sa_id,
        !          2986:                        .get_ike_sa_id = _get_ike_sa_id,
        !          2987:                        .set_exchange_type = _set_exchange_type,
        !          2988:                        .get_exchange_type = _get_exchange_type,
        !          2989:                        .get_first_payload_type = _get_first_payload_type,
        !          2990:                        .set_request = _set_request,
        !          2991:                        .get_request = _get_request,
        !          2992:                        .set_version_flag = _set_version_flag,
        !          2993:                        .get_reserved_header_bit = _get_reserved_header_bit,
        !          2994:                        .set_reserved_header_bit = _set_reserved_header_bit,
        !          2995:                        .add_payload = _add_payload,
        !          2996:                        .add_notify = _add_notify,
        !          2997:                        .disable_sort = _disable_sort,
        !          2998:                        .generate = _generate,
        !          2999:                        .is_encoded = _is_encoded,
        !          3000:                        .is_fragmented = _is_fragmented,
        !          3001:                        .fragment = _fragment,
        !          3002:                        .add_fragment = _add_fragment_v2,
        !          3003:                        .set_source = _set_source,
        !          3004:                        .get_source = _get_source,
        !          3005:                        .set_destination = _set_destination,
        !          3006:                        .get_destination = _get_destination,
        !          3007:                        .create_payload_enumerator = _create_payload_enumerator,
        !          3008:                        .remove_payload_at = _remove_payload_at,
        !          3009:                        .get_payload = _get_payload,
        !          3010:                        .get_notify = _get_notify,
        !          3011:                        .parse_header = _parse_header,
        !          3012:                        .parse_body = _parse_body,
        !          3013:                        .get_packet = _get_packet,
        !          3014:                        .get_packet_data = _get_packet_data,
        !          3015:                        .get_fragments = _get_fragments,
        !          3016:                        .destroy = _destroy,
        !          3017:                },
        !          3018:                .exchange_type = EXCHANGE_TYPE_UNDEFINED,
        !          3019:                .is_request = TRUE,
        !          3020:                .first_payload = PL_NONE,
        !          3021:                .packet = packet,
        !          3022:                .payloads = linked_list_create(),
        !          3023:                .parser = parser_create(packet->get_data(packet)),
        !          3024:        );
        !          3025: 
        !          3026:        return &this->public;
        !          3027: }
        !          3028: 
        !          3029: /*
        !          3030:  * Described in header.
        !          3031:  */
        !          3032: message_t *message_create(int major, int minor)
        !          3033: {
        !          3034:        message_t *this = message_create_from_packet(packet_create());
        !          3035: 
        !          3036:        this->set_major_version(this, major);
        !          3037:        this->set_minor_version(this, minor);
        !          3038: 
        !          3039:        return this;
        !          3040: }
        !          3041: 
        !          3042: /*
        !          3043:  * Described in header.
        !          3044:  */
        !          3045: message_t *message_create_defrag(message_t *fragment)
        !          3046: {
        !          3047:        private_message_t *this;
        !          3048: 
        !          3049:        if (!fragment->get_payload(fragment, PLV1_FRAGMENT) &&
        !          3050:                !fragment->get_payload(fragment, PLV2_FRAGMENT))
        !          3051:        {
        !          3052:                return NULL;
        !          3053:        }
        !          3054:        this = (private_message_t*)clone_message((private_message_t*)fragment);
        !          3055:        /* we don't need a parser for IKEv2, the one for IKEv1 is created after
        !          3056:         * reassembling the original message */
        !          3057:        this->parser->destroy(this->parser);
        !          3058:        this->parser = NULL;
        !          3059:        if (fragment->get_major_version(fragment) == IKEV1_MAJOR_VERSION)
        !          3060:        {
        !          3061:                /* we store the fragment ID in the message ID field, which should be
        !          3062:                 * zero for fragments, but make sure */
        !          3063:                this->message_id = 0;
        !          3064:                this->public.add_fragment = _add_fragment_v1;
        !          3065:        }
        !          3066:        INIT(this->frag,
        !          3067:                .max_packet = lib->settings->get_int(lib->settings,
        !          3068:                                                                "%s.max_packet", PACKET_MAX_DEFAULT, lib->ns),
        !          3069:        );
        !          3070:        return &this->public;
        !          3071: }

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