Annotation of embedaddon/strongswan/src/libtls/tls.c, revision 1.1.1.2

1.1       misho       1: /*
1.1.1.2 ! misho       2:  * Copyright (C) 2021 Tobias Brunner
        !             3:  * Copyright (C) 2020-2021 Pascal Knecht
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
1.1       misho       6:  * Copyright (C) 2010 Martin Willi
                      7:  * Copyright (C) 2010 revosec AG
                      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 "tls.h"
                     21: 
                     22: #include <utils/debug.h>
                     23: 
                     24: #include "tls_protection.h"
                     25: #include "tls_compression.h"
                     26: #include "tls_fragmentation.h"
                     27: #include "tls_crypto.h"
                     28: #include "tls_server.h"
                     29: #include "tls_peer.h"
                     30: 
1.1.1.2 ! misho      31: ENUM_BEGIN(tls_version_names, TLS_UNSPEC, TLS_UNSPEC,
        !            32:        "TLS UNSPEC");
        !            33: ENUM_NEXT(tls_version_names, SSL_2_0, SSL_2_0, TLS_UNSPEC,
1.1       misho      34:        "SSLv2");
1.1.1.2 ! misho      35: ENUM_NEXT(tls_version_names, SSL_3_0, TLS_1_3, SSL_2_0,
1.1       misho      36:        "SSLv3",
                     37:        "TLS 1.0",
                     38:        "TLS 1.1",
1.1.1.2 ! misho      39:        "TLS 1.2",
        !            40:        "TLS 1.3");
        !            41: ENUM_END(tls_version_names, TLS_1_3);
        !            42: 
        !            43: /**
        !            44:  * Only supported versions are mapped
        !            45:  */
        !            46: ENUM(tls_numeric_version_names, TLS_SUPPORTED_MIN, TLS_SUPPORTED_MAX,
        !            47:        "1.0",
        !            48:        "1.1",
        !            49:        "1.2",
        !            50:        "1.3");
1.1       misho      51: 
                     52: ENUM(tls_content_type_names, TLS_CHANGE_CIPHER_SPEC, TLS_APPLICATION_DATA,
                     53:        "ChangeCipherSpec",
                     54:        "Alert",
                     55:        "Handshake",
                     56:        "ApplicationData",
                     57: );
                     58: 
1.1.1.2 ! misho      59: ENUM_BEGIN(tls_handshake_type_names, TLS_HELLO_REQUEST, TLS_HELLO_REQUEST,
        !            60:        "HelloRequest");
        !            61: ENUM_NEXT(tls_handshake_type_names,
        !            62:                TLS_CLIENT_HELLO, TLS_HELLO_RETRY_REQUEST, TLS_HELLO_REQUEST,
1.1       misho      63:        "ClientHello",
1.1.1.2 ! misho      64:        "ServerHello",
        !            65:        "HelloVerifyRequest",
        !            66:        "NewSessionTicket",
        !            67:        "EndOfEarlyData",
        !            68:        "HelloRetryRequest");
        !            69: ENUM_NEXT(tls_handshake_type_names,
        !            70:                TLS_ENCRYPTED_EXTENSIONS, TLS_ENCRYPTED_EXTENSIONS,
        !            71:                TLS_HELLO_RETRY_REQUEST,
        !            72:        "EncryptedExtensions");
1.1       misho      73: ENUM_NEXT(tls_handshake_type_names,
1.1.1.2 ! misho      74:                TLS_CERTIFICATE, TLS_CLIENT_KEY_EXCHANGE, TLS_ENCRYPTED_EXTENSIONS,
1.1       misho      75:        "Certificate",
                     76:        "ServerKeyExchange",
                     77:        "CertificateRequest",
                     78:        "ServerHelloDone",
                     79:        "CertificateVerify",
                     80:        "ClientKeyExchange");
                     81: ENUM_NEXT(tls_handshake_type_names,
1.1.1.2 ! misho      82:                  TLS_FINISHED, TLS_KEY_UPDATE, TLS_CLIENT_KEY_EXCHANGE,
        !            83:        "Finished",
        !            84:        "CertificateUrl",
        !            85:        "CertificateStatus",
        !            86:        "SupplementalData",
        !            87:        "KeyUpdate");
        !            88: ENUM_NEXT(tls_handshake_type_names,
        !            89:                TLS_MESSAGE_HASH, TLS_MESSAGE_HASH, TLS_KEY_UPDATE,
        !            90:        "MessageHash");
        !            91: ENUM_END(tls_handshake_type_names, TLS_MESSAGE_HASH);
1.1       misho      92: 
                     93: ENUM_BEGIN(tls_extension_names, TLS_EXT_SERVER_NAME, TLS_EXT_STATUS_REQUEST,
                     94:        "server name",
                     95:        "max fragment length",
                     96:        "client certificate url",
                     97:        "trusted ca keys",
                     98:        "truncated hmac",
                     99:        "status request");
                    100: ENUM_NEXT(tls_extension_names,
1.1.1.2 ! misho     101:                TLS_EXT_SUPPORTED_GROUPS, TLS_EXT_EC_POINT_FORMATS,
1.1       misho     102:                TLS_EXT_STATUS_REQUEST,
1.1.1.2 ! misho     103:        "supported groups",
1.1       misho     104:        "ec point formats");
                    105: ENUM_NEXT(tls_extension_names,
1.1.1.2 ! misho     106:                TLS_EXT_SIGNATURE_ALGORITHMS,
        !           107:                TLS_EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
1.1       misho     108:                TLS_EXT_EC_POINT_FORMATS,
1.1.1.2 ! misho     109:        "signature algorithms",
        !           110:        "use rtp",
        !           111:        "heartbeat",
        !           112:        "application layer protocol negotiation");
        !           113: ENUM_NEXT(tls_extension_names,
        !           114:                TLS_CLIENT_CERTIFICATE_TYPE, TLS_SERVER_CERTIFICATE_TYPE,
        !           115:                TLS_EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
        !           116:        "client certificate type",
        !           117:        "server certificate type");
        !           118: ENUM_NEXT(tls_extension_names,
        !           119:                TLS_EXT_ENCRYPT_THEN_MAC, TLS_EXT_EXTENDED_MASTER_SECRET,
        !           120:                TLS_SERVER_CERTIFICATE_TYPE,
        !           121:        "encrypt-then-mac",
        !           122:        "extended master secret");
        !           123: ENUM_NEXT(tls_extension_names,
        !           124:                TLS_EXT_SESSION_TICKET, TLS_EXT_SESSION_TICKET,
        !           125:                TLS_EXT_EXTENDED_MASTER_SECRET,
        !           126:        "session ticket");
        !           127: ENUM_NEXT(tls_extension_names,
        !           128:                TLS_EXT_PRE_SHARED_KEY, TLS_EXT_PSK_KEY_EXCHANGE_MODES,
        !           129:                TLS_EXT_SESSION_TICKET,
        !           130:        "pre-shared key",
        !           131:        "early data",
        !           132:        "supported versions",
        !           133:        "cookie",
        !           134:        "psk key exchange modes");
        !           135: ENUM_NEXT(tls_extension_names,
        !           136:                TLS_EXT_CERTIFICATE_AUTHORITIES, TLS_EXT_KEY_SHARE,
        !           137:                TLS_EXT_PSK_KEY_EXCHANGE_MODES,
        !           138:        "certificate authorities",
        !           139:        "oid filters",
        !           140:        "post-handshake auth",
        !           141:        "signature algorithms cert",
        !           142:        "key-share");
1.1       misho     143: ENUM_NEXT(tls_extension_names,
                    144:                TLS_EXT_RENEGOTIATION_INFO, TLS_EXT_RENEGOTIATION_INFO,
1.1.1.2 ! misho     145:                TLS_EXT_KEY_SHARE,
1.1       misho     146:        "renegotiation info");
                    147: ENUM_END(tls_extension_names, TLS_EXT_RENEGOTIATION_INFO);
                    148: 
1.1.1.2 ! misho     149: chunk_t tls_hello_retry_request_magic = chunk_from_chars(
        !           150:        0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
        !           151:        0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
        !           152:        0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
        !           153:        0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
        !           154: );
        !           155: 
        !           156: chunk_t tls_downgrade_protection_tls11 = chunk_from_chars(
        !           157:        0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x00,
        !           158: );
        !           159: chunk_t tls_downgrade_protection_tls12 = chunk_from_chars(
        !           160:        0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01,
        !           161: );
        !           162: 
1.1       misho     163: /**
                    164:  * TLS record
                    165:  */
                    166: typedef struct __attribute__((packed)) {
                    167:        uint8_t type;
                    168:        uint16_t version;
                    169:        uint16_t length;
                    170:        char data[];
                    171: } tls_record_t;
                    172: 
                    173: typedef struct private_tls_t private_tls_t;
                    174: 
                    175: /**
                    176:  * Private data of an tls_protection_t object.
                    177:  */
                    178: struct private_tls_t {
                    179: 
                    180:        /**
                    181:         * Public tls_t interface.
                    182:         */
                    183:        tls_t public;
                    184: 
                    185:        /**
                    186:         * Role this TLS stack acts as.
                    187:         */
                    188:        bool is_server;
                    189: 
                    190:        /**
1.1.1.2 ! misho     191:         * Negotiated TLS version and maximum supported TLS version
1.1       misho     192:         */
1.1.1.2 ! misho     193:        tls_version_t version_max;
        !           194: 
        !           195:        /**
        !           196:         * Minimal supported TLS version
        !           197:         */
        !           198:        tls_version_t version_min;
1.1       misho     199: 
                    200:        /**
                    201:         * TLS stack purpose, as given to constructor
                    202:         */
                    203:        tls_purpose_t purpose;
                    204: 
                    205:        /**
1.1.1.2 ! misho     206:         * Flags for this TLS stack
        !           207:         */
        !           208:        tls_flag_t flags;
        !           209: 
        !           210:        /**
1.1       misho     211:         * TLS record protection layer
                    212:         */
                    213:        tls_protection_t *protection;
                    214: 
                    215:        /**
                    216:         * TLS record compression layer
                    217:         */
                    218:        tls_compression_t *compression;
                    219: 
                    220:        /**
                    221:         * TLS record fragmentation layer
                    222:         */
                    223:        tls_fragmentation_t *fragmentation;
                    224: 
                    225:        /**
                    226:         * TLS alert handler
                    227:         */
                    228:        tls_alert_t *alert;
                    229: 
                    230:        /**
                    231:         * TLS crypto helper context
                    232:         */
                    233:        tls_crypto_t *crypto;
                    234: 
                    235:        /**
                    236:         * TLS handshake protocol handler
                    237:         */
                    238:        tls_handshake_t *handshake;
                    239: 
                    240:        /**
                    241:         * TLS application data handler
                    242:         */
                    243:        tls_application_t *application;
                    244: 
                    245:        /**
                    246:         * Allocated input buffer
                    247:         */
                    248:        chunk_t input;
                    249: 
                    250:        /**
                    251:         * Number of bytes read in input buffer
                    252:         */
                    253:        size_t inpos;
                    254: 
                    255:        /**
                    256:         * Allocated output buffer
                    257:         */
                    258:        chunk_t output;
                    259: 
                    260:        /**
                    261:         * Number of bytes processed from output buffer
                    262:         */
                    263:        size_t outpos;
                    264: 
                    265:        /**
                    266:         * Position in partially received record header
                    267:         */
                    268:        size_t headpos;
                    269: 
                    270:        /**
                    271:         * Partial TLS record header received
                    272:         */
                    273:        tls_record_t head;
                    274: };
                    275: 
                    276: /**
                    277:  * Described in header.
                    278:  */
                    279: void libtls_init(void)
                    280: {
                    281:        /* empty */
                    282: }
                    283: 
                    284: METHOD(tls_t, process, status_t,
                    285:        private_tls_t *this, void *buf, size_t buflen)
                    286: {
                    287:        tls_record_t *record;
                    288:        status_t status;
                    289:        u_int len;
                    290: 
                    291:        if (this->headpos)
                    292:        {       /* have a partial TLS record header, try to complete it */
                    293:                len = min(buflen, sizeof(this->head) - this->headpos);
                    294:                memcpy(((char*)&this->head) + this->headpos, buf, len);
                    295:                this->headpos += len;
                    296:                buflen -= len;
                    297:                buf += len;
                    298:                if (this->headpos == sizeof(this->head))
                    299:                {       /* header complete, allocate space with new header */
                    300:                        len = untoh16(&this->head.length);
                    301:                        this->input = chunk_alloc(len + sizeof(tls_record_t));
                    302:                        memcpy(this->input.ptr, &this->head, sizeof(this->head));
                    303:                        this->inpos = sizeof(this->head);
                    304:                        this->headpos = 0;
                    305:                }
                    306:        }
                    307: 
                    308:        while (buflen)
                    309:        {
                    310:                if (this->input.len == 0)
                    311:                {
                    312:                        while (buflen >= sizeof(tls_record_t))
                    313:                        {
                    314:                                /* try to process records inline */
                    315:                                record = buf;
                    316:                                len = untoh16(&record->length);
                    317: 
                    318:                                if (len + sizeof(tls_record_t) > buflen)
                    319:                                {       /* not a full record, read to buffer */
                    320:                                        this->input = chunk_alloc(len + sizeof(tls_record_t));
                    321:                                        this->inpos = 0;
                    322:                                        break;
                    323:                                }
                    324:                                DBG2(DBG_TLS, "processing TLS %N record (%d bytes)",
                    325:                                         tls_content_type_names, record->type, len);
                    326:                                status = this->protection->process(this->protection,
                    327:                                                                record->type, chunk_create(record->data, len));
                    328:                                if (status != NEED_MORE)
                    329:                                {
                    330:                                        return status;
                    331:                                }
                    332:                                buf += len + sizeof(tls_record_t);
                    333:                                buflen -= len + sizeof(tls_record_t);
                    334:                                if (buflen == 0)
                    335:                                {
                    336:                                        return NEED_MORE;
                    337:                                }
                    338:                        }
                    339:                        if (buflen < sizeof(tls_record_t))
                    340:                        {
                    341:                                DBG2(DBG_TLS, "received incomplete TLS record header");
                    342:                                memcpy(&this->head, buf, buflen);
                    343:                                this->headpos = buflen;
                    344:                                break;
                    345:                        }
                    346:                }
                    347:                len = min(buflen, this->input.len - this->inpos);
                    348:                memcpy(this->input.ptr + this->inpos, buf, len);
                    349:                buf += len;
                    350:                buflen -= len;
                    351:                this->inpos += len;
                    352:                DBG2(DBG_TLS, "buffering %d bytes, %d bytes of %d byte TLS record received",
                    353:                         len, this->inpos, this->input.len);
                    354:                if (this->input.len == this->inpos)
                    355:                {
                    356:                        record = (tls_record_t*)this->input.ptr;
                    357:                        len = untoh16(&record->length);
                    358: 
                    359:                        DBG2(DBG_TLS, "processing buffered TLS %N record (%d bytes)",
                    360:                                 tls_content_type_names, record->type, len);
                    361:                        status = this->protection->process(this->protection,
                    362:                                                                record->type, chunk_create(record->data, len));
                    363:                        chunk_free(&this->input);
                    364:                        this->inpos = 0;
                    365:                        if (status != NEED_MORE)
                    366:                        {
                    367:                                return status;
                    368:                        }
                    369:                }
                    370:        }
                    371:        return NEED_MORE;
                    372: }
                    373: 
                    374: METHOD(tls_t, build, status_t,
                    375:        private_tls_t *this, void *buf, size_t *buflen, size_t *msglen)
                    376: {
                    377:        tls_content_type_t type;
                    378:        tls_record_t record;
                    379:        status_t status;
                    380:        chunk_t data;
                    381:        size_t len;
                    382: 
                    383:        len = *buflen;
                    384:        if (this->output.len == 0)
                    385:        {
                    386:                /* query upper layers for new records, as many as we can get */
                    387:                while (TRUE)
                    388:                {
                    389:                        status = this->protection->build(this->protection, &type, &data);
                    390:                        switch (status)
                    391:                        {
                    392:                                case NEED_MORE:
                    393:                                        record.type = type;
1.1.1.2 ! misho     394:                                        if (this->version_max < TLS_1_3)
        !           395:                                        {
        !           396:                                                htoun16(&record.version, this->version_max);
        !           397:                                        }
        !           398:                                        else
        !           399:                                        {
        !           400:                                                htoun16(&record.version, TLS_1_2);
        !           401:                                        }
1.1       misho     402:                                        htoun16(&record.length, data.len);
                    403:                                        this->output = chunk_cat("mcm", this->output,
                    404:                                                                                         chunk_from_thing(record), data);
                    405:                                        DBG2(DBG_TLS, "sending TLS %N record (%d bytes)",
                    406:                                                 tls_content_type_names, type, data.len);
                    407:                                        continue;
                    408:                                case INVALID_STATE:
                    409:                                        if (this->output.len == 0)
                    410:                                        {
                    411:                                                return INVALID_STATE;
                    412:                                        }
                    413:                                        break;
                    414:                                default:
                    415:                                        return status;
                    416:                        }
                    417:                        break;
                    418:                }
                    419:                if (msglen)
                    420:                {
                    421:                        *msglen = this->output.len;
                    422:                }
                    423:        }
                    424:        else
                    425:        {
                    426:                if (msglen)
                    427:                {
                    428:                        *msglen = 0;
                    429:                }
                    430:        }
                    431:        len = min(len, this->output.len - this->outpos);
                    432:        memcpy(buf, this->output.ptr + this->outpos, len);
                    433:        this->outpos += len;
                    434:        *buflen = len;
                    435:        if (this->outpos == this->output.len)
                    436:        {
                    437:                chunk_free(&this->output);
                    438:                this->outpos = 0;
                    439:                return ALREADY_DONE;
                    440:        }
                    441:        return NEED_MORE;
                    442: }
                    443: 
                    444: METHOD(tls_t, is_server, bool,
                    445:        private_tls_t *this)
                    446: {
                    447:        return this->is_server;
                    448: }
                    449: 
                    450: METHOD(tls_t, get_server_id, identification_t*,
                    451:        private_tls_t *this)
                    452: {
                    453:        return this->handshake->get_server_id(this->handshake);
                    454: }
                    455: 
                    456: METHOD(tls_t, get_peer_id, identification_t*,
                    457:        private_tls_t *this)
                    458: {
                    459:        return this->handshake->get_peer_id(this->handshake);
                    460: }
                    461: 
1.1.1.2 ! misho     462: /**
        !           463:  * Determine the min/max versions
        !           464:  */
        !           465: static void determine_versions(private_tls_t *this)
        !           466: {
        !           467:        tls_version_t version;
        !           468:        char *version_str;
        !           469: 
        !           470:        if (this->version_min == TLS_UNSPEC)
        !           471:        {       /* default to TLS 1.2 as older versions are considered deprecated */
        !           472:                this->version_min = TLS_1_2;
        !           473: 
        !           474:                version_str = lib->settings->get_str(lib->settings, "%s.tls.version_min",
        !           475:                                                                                         NULL, lib->ns);
        !           476:                if (version_str &&
        !           477:                        enum_from_name(tls_numeric_version_names, version_str, &version))
        !           478:                {
        !           479:                        this->version_min = version;
        !           480:                }
        !           481:        }
        !           482:        if (this->version_max == TLS_UNSPEC)
        !           483:        {       /* default to TLS 1.2 until 1.3 is stable for use in EAP */
        !           484:                this->version_max = TLS_1_2;
        !           485: 
        !           486:                version_str = lib->settings->get_str(lib->settings, "%s.tls.version_max",
        !           487:                                                                                         NULL, lib->ns);
        !           488:                if (version_str &&
        !           489:                        enum_from_name(tls_numeric_version_names, version_str, &version))
        !           490:                {
        !           491:                        this->version_max = version;
        !           492:                }
        !           493:        }
        !           494:        if (this->version_max < this->version_min)
        !           495:        {
        !           496:                this->version_min = this->version_max;
        !           497:        }
        !           498: }
        !           499: 
        !           500: METHOD(tls_t, get_version_max, tls_version_t,
        !           501:        private_tls_t *this)
        !           502: {
        !           503:        determine_versions(this);
        !           504:        return this->version_max;
        !           505: }
        !           506: 
        !           507: METHOD(tls_t, get_version_min, tls_version_t,
1.1       misho     508:        private_tls_t *this)
                    509: {
1.1.1.2 ! misho     510:        determine_versions(this);
        !           511:        return this->version_min;
1.1       misho     512: }
                    513: 
                    514: METHOD(tls_t, set_version, bool,
1.1.1.2 ! misho     515:        private_tls_t *this, tls_version_t min_version, tls_version_t max_version)
1.1       misho     516: {
1.1.1.2 ! misho     517:        if (min_version == TLS_UNSPEC)
        !           518:        {
        !           519:                min_version = this->version_min;
        !           520:        }
        !           521:        if (max_version == TLS_UNSPEC)
        !           522:        {
        !           523:                max_version = this->version_max;
        !           524:        }
        !           525:        if ((this->version_min != TLS_UNSPEC && min_version < this->version_min) ||
        !           526:                (this->version_max != TLS_UNSPEC && max_version > this->version_max) ||
        !           527:                (min_version != TLS_UNSPEC && min_version < TLS_SUPPORTED_MIN) ||
        !           528:                (max_version != TLS_UNSPEC && max_version > TLS_SUPPORTED_MAX) ||
        !           529:                min_version > max_version)
1.1       misho     530:        {
                    531:                return FALSE;
                    532:        }
1.1.1.2 ! misho     533: 
        !           534:        this->version_min = min_version;
        !           535:        this->version_max = max_version;
        !           536: 
        !           537:        if (min_version != TLS_UNSPEC && min_version == max_version)
1.1       misho     538:        {
1.1.1.2 ! misho     539:                this->protection->set_version(this->protection, max_version);
1.1       misho     540:        }
1.1.1.2 ! misho     541:        return TRUE;
1.1       misho     542: }
                    543: 
                    544: METHOD(tls_t, get_purpose, tls_purpose_t,
                    545:        private_tls_t *this)
                    546: {
                    547:        return this->purpose;
                    548: }
                    549: 
1.1.1.2 ! misho     550: METHOD(tls_t, get_flags, tls_flag_t,
        !           551:        private_tls_t *this)
        !           552: {
        !           553:        return this->flags;
        !           554: }
        !           555: 
1.1       misho     556: METHOD(tls_t, is_complete, bool,
                    557:        private_tls_t *this)
                    558: {
                    559:        if (this->handshake->finished(this->handshake))
                    560:        {
                    561:                if (!this->application)
                    562:                {
                    563:                        return TRUE;
                    564:                }
                    565:                return this->fragmentation->application_finished(this->fragmentation);
                    566:        }
                    567:        return FALSE;
                    568: }
                    569: 
                    570: METHOD(tls_t, get_eap_msk, chunk_t,
                    571:        private_tls_t *this)
                    572: {
                    573:        return this->crypto->get_eap_msk(this->crypto);
                    574: }
                    575: 
                    576: METHOD(tls_t, get_auth, auth_cfg_t*,
                    577:        private_tls_t *this)
                    578: {
                    579:        return this->handshake->get_auth(this->handshake);
                    580: }
                    581: 
                    582: METHOD(tls_t, destroy, void,
                    583:        private_tls_t *this)
                    584: {
                    585:        this->protection->destroy(this->protection);
                    586:        this->compression->destroy(this->compression);
                    587:        this->fragmentation->destroy(this->fragmentation);
                    588:        this->crypto->destroy(this->crypto);
                    589:        this->handshake->destroy(this->handshake);
                    590:        DESTROY_IF(this->application);
                    591:        this->alert->destroy(this->alert);
                    592: 
                    593:        free(this->input.ptr);
                    594:        free(this->output.ptr);
                    595: 
                    596:        free(this);
                    597: }
                    598: 
                    599: /**
                    600:  * See header
                    601:  */
                    602: tls_t *tls_create(bool is_server, identification_t *server,
                    603:                                  identification_t *peer, tls_purpose_t purpose,
1.1.1.2 ! misho     604:                                  tls_application_t *application, tls_cache_t *cache,
        !           605:                                  tls_flag_t flags)
1.1       misho     606: {
                    607:        private_tls_t *this;
                    608: 
                    609:        switch (purpose)
                    610:        {
                    611:                case TLS_PURPOSE_EAP_TLS:
                    612:                case TLS_PURPOSE_EAP_TTLS:
                    613:                case TLS_PURPOSE_EAP_PEAP:
                    614:                case TLS_PURPOSE_GENERIC:
                    615:                        break;
                    616:                default:
                    617:                        return NULL;
                    618:        }
                    619: 
                    620:        INIT(this,
                    621:                .public = {
                    622:                        .process = _process,
                    623:                        .build = _build,
                    624:                        .is_server = _is_server,
                    625:                        .get_server_id = _get_server_id,
                    626:                        .get_peer_id = _get_peer_id,
1.1.1.2 ! misho     627:                        .get_version_max = _get_version_max,
        !           628:                        .get_version_min = _get_version_min,
1.1       misho     629:                        .set_version = _set_version,
                    630:                        .get_purpose = _get_purpose,
1.1.1.2 ! misho     631:                        .get_flags = _get_flags,
1.1       misho     632:                        .is_complete = _is_complete,
                    633:                        .get_eap_msk = _get_eap_msk,
                    634:                        .get_auth = _get_auth,
                    635:                        .destroy = _destroy,
                    636:                },
                    637:                .is_server = is_server,
                    638:                .application = application,
                    639:                .purpose = purpose,
1.1.1.2 ! misho     640:                .flags = flags,
1.1       misho     641:        );
                    642:        lib->settings->add_fallback(lib->settings, "%s.tls", "libtls", lib->ns);
                    643: 
                    644:        this->crypto = tls_crypto_create(&this->public, cache);
                    645:        this->alert = tls_alert_create();
                    646:        if (is_server)
                    647:        {
                    648:                this->handshake = &tls_server_create(&this->public, this->crypto,
                    649:                                                                                this->alert, server, peer)->handshake;
                    650:        }
                    651:        else
                    652:        {
                    653:                this->handshake = &tls_peer_create(&this->public, this->crypto,
                    654:                                                                                this->alert, peer, server)->handshake;
                    655:        }
                    656:        this->fragmentation = tls_fragmentation_create(this->handshake, this->alert,
                    657:                                                                                                   this->application, purpose);
                    658:        this->compression = tls_compression_create(this->fragmentation, this->alert);
                    659:        this->protection = tls_protection_create(this->compression, this->alert);
                    660:        this->crypto->set_protection(this->crypto, this->protection);
                    661: 
                    662:        return &this->public;
                    663: }

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