Annotation of embedaddon/strongswan/src/libtls/tls_peer.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2010 Martin Willi
                      3:  * Copyright (C) 2010 revosec AG
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "tls_peer.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: #include <credentials/certificates/x509.h>
                     20: 
                     21: #include <time.h>
                     22: 
                     23: typedef struct private_tls_peer_t private_tls_peer_t;
                     24: 
                     25: typedef enum {
                     26:        STATE_INIT,
                     27:        STATE_HELLO_SENT,
                     28:        STATE_HELLO_RECEIVED,
                     29:        STATE_HELLO_DONE,
                     30:        STATE_CERT_SENT,
                     31:        STATE_CERT_RECEIVED,
                     32:        STATE_KEY_EXCHANGE_RECEIVED,
                     33:        STATE_CERTREQ_RECEIVED,
                     34:        STATE_KEY_EXCHANGE_SENT,
                     35:        STATE_VERIFY_SENT,
                     36:        STATE_CIPHERSPEC_CHANGED_OUT,
                     37:        STATE_FINISHED_SENT,
                     38:        STATE_CIPHERSPEC_CHANGED_IN,
                     39:        STATE_FINISHED_RECEIVED,
                     40: } peer_state_t;
                     41: 
                     42: /**
                     43:  * Private data of an tls_peer_t object.
                     44:  */
                     45: struct private_tls_peer_t {
                     46: 
                     47:        /**
                     48:         * Public tls_peer_t interface.
                     49:         */
                     50:        tls_peer_t public;
                     51: 
                     52:        /**
                     53:         * TLS stack
                     54:         */
                     55:        tls_t *tls;
                     56: 
                     57:        /**
                     58:         * TLS crypto context
                     59:         */
                     60:        tls_crypto_t *crypto;
                     61: 
                     62:        /**
                     63:         * TLS alert handler
                     64:         */
                     65:        tls_alert_t *alert;
                     66: 
                     67:        /**
                     68:         * Peer identity, NULL for no client authentication
                     69:         */
                     70:        identification_t *peer;
                     71: 
                     72:        /**
                     73:         * Server identity
                     74:         */
                     75:        identification_t *server;
                     76: 
                     77:        /**
                     78:         * State we are in
                     79:         */
                     80:        peer_state_t state;
                     81: 
                     82:        /**
                     83:         * TLS version we offered in hello
                     84:         */
                     85:        tls_version_t hello_version;
                     86: 
                     87:        /**
                     88:         * Hello random data selected by client
                     89:         */
                     90:        char client_random[32];
                     91: 
                     92:        /**
                     93:         * Hello random data selected by server
                     94:         */
                     95:        char server_random[32];
                     96: 
                     97:        /**
                     98:         * Auth helper for peer authentication
                     99:         */
                    100:        auth_cfg_t *peer_auth;
                    101: 
                    102:        /**
                    103:         * Auth helper for server authentication
                    104:         */
                    105:        auth_cfg_t *server_auth;
                    106: 
                    107:        /**
                    108:         * Peer private key
                    109:         */
                    110:        private_key_t *private;
                    111: 
                    112:        /**
                    113:         * DHE exchange
                    114:         */
                    115:        diffie_hellman_t *dh;
                    116: 
                    117:        /**
                    118:         * Resuming a session?
                    119:         */
                    120:        bool resume;
                    121: 
                    122:        /**
                    123:         * TLS session identifier
                    124:         */
                    125:        chunk_t session;
                    126: 
                    127:        /**
                    128:         * List of server-supported hashsig algorithms
                    129:         */
                    130:        chunk_t hashsig;
                    131: 
                    132:        /**
                    133:         * List of server-supported client certificate types
                    134:         */
                    135:        chunk_t cert_types;
                    136: };
                    137: 
                    138: /**
                    139:  * Process a server hello message
                    140:  */
                    141: static status_t process_server_hello(private_tls_peer_t *this,
                    142:                                                                         bio_reader_t *reader)
                    143: {
                    144:        uint8_t compression;
                    145:        uint16_t version, cipher;
                    146:        chunk_t random, session, ext = chunk_empty;
                    147:        tls_cipher_suite_t suite = 0;
                    148: 
                    149:        this->crypto->append_handshake(this->crypto,
                    150:                                                                   TLS_SERVER_HELLO, reader->peek(reader));
                    151: 
                    152:        if (!reader->read_uint16(reader, &version) ||
                    153:                !reader->read_data(reader, sizeof(this->server_random), &random) ||
                    154:                !reader->read_data8(reader, &session) ||
                    155:                !reader->read_uint16(reader, &cipher) ||
                    156:                !reader->read_uint8(reader, &compression) ||
                    157:                (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
                    158:        {
                    159:                DBG1(DBG_TLS, "received invalid ServerHello");
                    160:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    161:                return NEED_MORE;
                    162:        }
                    163: 
                    164:        memcpy(this->server_random, random.ptr, sizeof(this->server_random));
                    165: 
                    166:        if (!this->tls->set_version(this->tls, version))
                    167:        {
                    168:                DBG1(DBG_TLS, "negotiated version %N not supported",
                    169:                         tls_version_names, version);
                    170:                this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
                    171:                return NEED_MORE;
                    172:        }
                    173: 
                    174:        if (chunk_equals(this->session, session))
                    175:        {
                    176:                suite = this->crypto->resume_session(this->crypto, session, this->server,
                    177:                                                                                chunk_from_thing(this->client_random),
                    178:                                                                                chunk_from_thing(this->server_random));
                    179:                if (suite)
                    180:                {
                    181:                        DBG1(DBG_TLS, "resumed %N using suite %N",
                    182:                                 tls_version_names, version, tls_cipher_suite_names, suite);
                    183:                        this->resume = TRUE;
                    184:                }
                    185:        }
                    186:        if (!suite)
                    187:        {
                    188:                suite = cipher;
                    189:                if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1, KEY_ANY))
                    190:                {
                    191:                        DBG1(DBG_TLS, "received TLS cipher suite %N unacceptable",
                    192:                                 tls_cipher_suite_names, suite);
                    193:                        this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
                    194:                        return NEED_MORE;
                    195:                }
                    196:                DBG1(DBG_TLS, "negotiated %N using suite %N",
                    197:                         tls_version_names, version, tls_cipher_suite_names, suite);
                    198:                free(this->session.ptr);
                    199:                this->session = chunk_clone(session);
                    200:        }
                    201:        this->state = STATE_HELLO_RECEIVED;
                    202:        return NEED_MORE;
                    203: }
                    204: 
                    205: /**
                    206:  * Check if a server certificate is acceptable for the given server identity
                    207:  */
                    208: static bool check_certificate(private_tls_peer_t *this, certificate_t *cert)
                    209: {
                    210:        identification_t *id;
                    211: 
                    212:        if (cert->has_subject(cert, this->server))
                    213:        {
                    214:                return TRUE;
                    215:        }
                    216:        id = cert->get_subject(cert);
                    217:        if (id->matches(id, this->server))
                    218:        {
                    219:                return TRUE;
                    220:        }
                    221:        if (cert->get_type(cert) == CERT_X509)
                    222:        {
                    223:                x509_t *x509 = (x509_t*)cert;
                    224:                enumerator_t *enumerator;
                    225: 
                    226:                enumerator = x509->create_subjectAltName_enumerator(x509);
                    227:                while (enumerator->enumerate(enumerator, &id))
                    228:                {
                    229:                        if (id->matches(id, this->server))
                    230:                        {
                    231:                                enumerator->destroy(enumerator);
                    232:                                return TRUE;
                    233:                        }
                    234:                }
                    235:                enumerator->destroy(enumerator);
                    236:        }
                    237:        DBG1(DBG_TLS, "server certificate does not match to '%Y'", this->server);
                    238:        return FALSE;
                    239: }
                    240: 
                    241: /**
                    242:  * Process a Certificate message
                    243:  */
                    244: static status_t process_certificate(private_tls_peer_t *this,
                    245:                                                                        bio_reader_t *reader)
                    246: {
                    247:        certificate_t *cert;
                    248:        bio_reader_t *certs;
                    249:        chunk_t data;
                    250:        bool first = TRUE;
                    251: 
                    252:        this->crypto->append_handshake(this->crypto,
                    253:                                                                   TLS_CERTIFICATE, reader->peek(reader));
                    254: 
                    255:        if (!reader->read_data24(reader, &data))
                    256:        {
                    257:                DBG1(DBG_TLS, "certificate message header invalid");
                    258:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    259:                return NEED_MORE;
                    260:        }
                    261:        certs = bio_reader_create(data);
                    262:        while (certs->remaining(certs))
                    263:        {
                    264:                if (!certs->read_data24(certs, &data))
                    265:                {
                    266:                        DBG1(DBG_TLS, "certificate message invalid");
                    267:                        this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    268:                        certs->destroy(certs);
                    269:                        return NEED_MORE;
                    270:                }
                    271:                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    272:                                                                  BUILD_BLOB_ASN1_DER, data, BUILD_END);
                    273:                if (cert)
                    274:                {
                    275:                        if (first)
                    276:                        {
                    277:                                if (!check_certificate(this, cert))
                    278:                                {
                    279:                                        cert->destroy(cert);
                    280:                                        certs->destroy(certs);
                    281:                                        this->alert->add(this->alert, TLS_FATAL, TLS_ACCESS_DENIED);
                    282:                                        return NEED_MORE;
                    283:                                }
                    284:                                this->server_auth->add(this->server_auth,
                    285:                                                                           AUTH_HELPER_SUBJECT_CERT, cert);
                    286:                                DBG1(DBG_TLS, "received TLS server certificate '%Y'",
                    287:                                         cert->get_subject(cert));
                    288:                                first = FALSE;
                    289:                        }
                    290:                        else
                    291:                        {
                    292:                                DBG1(DBG_TLS, "received TLS intermediate certificate '%Y'",
                    293:                                         cert->get_subject(cert));
                    294:                                this->server_auth->add(this->server_auth,
                    295:                                                                           AUTH_HELPER_IM_CERT, cert);
                    296:                        }
                    297:                }
                    298:                else
                    299:                {
                    300:                        DBG1(DBG_TLS, "parsing TLS certificate failed, skipped");
                    301:                        this->alert->add(this->alert, TLS_WARNING, TLS_BAD_CERTIFICATE);
                    302:                }
                    303:        }
                    304:        certs->destroy(certs);
                    305:        this->state = STATE_CERT_RECEIVED;
                    306:        return NEED_MORE;
                    307: }
                    308: 
                    309: /**
                    310:  * Find a trusted public key to encrypt/verify key exchange data
                    311:  */
                    312: static public_key_t *find_public_key(private_tls_peer_t *this)
                    313: {
                    314:        public_key_t *public = NULL, *current;
                    315:        certificate_t *cert, *found;
                    316:        enumerator_t *enumerator;
                    317:        auth_cfg_t *auth;
                    318: 
                    319:        cert = this->server_auth->get(this->server_auth, AUTH_HELPER_SUBJECT_CERT);
                    320:        if (cert)
                    321:        {
                    322:                enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
                    323:                                                                                        KEY_ANY, cert->get_subject(cert),
                    324:                                                                                        this->server_auth, TRUE);
                    325:                while (enumerator->enumerate(enumerator, &current, &auth))
                    326:                {
                    327:                        found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
                    328:                        if (found && cert->equals(cert, found))
                    329:                        {
                    330:                                public = current->get_ref(current);
                    331:                                this->server_auth->merge(this->server_auth, auth, FALSE);
                    332:                                break;
                    333:                        }
                    334:                }
                    335:                enumerator->destroy(enumerator);
                    336:        }
                    337:        return public;
                    338: }
                    339: 
                    340: /**
                    341:  * Process a Key Exchange message using MODP Diffie Hellman
                    342:  */
                    343: static status_t process_modp_key_exchange(private_tls_peer_t *this,
                    344:                                                                                  bio_reader_t *reader)
                    345: {
                    346:        chunk_t prime, generator, pub, chunk;
                    347:        public_key_t *public;
                    348: 
                    349:        chunk = reader->peek(reader);
                    350:        if (!reader->read_data16(reader, &prime) ||
                    351:                !reader->read_data16(reader, &generator) ||
                    352:                !reader->read_data16(reader, &pub))
                    353:        {
                    354:                DBG1(DBG_TLS, "received invalid Server Key Exchange");
                    355:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    356:                return NEED_MORE;
                    357:        }
                    358:        /* reject (export) DH groups using primes smaller than 1024 bit */
                    359:        if (prime.len < 1024 / 8)
                    360:        {
                    361:                DBG1(DBG_TLS, "short DH prime received (%zu bytes)", prime.len);
                    362:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    363:                return NEED_MORE;
                    364:        }
                    365:        public = find_public_key(this);
                    366:        if (!public)
                    367:        {
                    368:                DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server);
                    369:                this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
                    370:                return NEED_MORE;
                    371:        }
                    372: 
                    373:        chunk.len = 2 + prime.len + 2 + generator.len + 2 + pub.len;
                    374:        chunk = chunk_cat("ccc", chunk_from_thing(this->client_random),
                    375:                                          chunk_from_thing(this->server_random), chunk);
                    376:        if (!this->crypto->verify(this->crypto, public, reader, chunk))
                    377:        {
                    378:                public->destroy(public);
                    379:                free(chunk.ptr);
                    380:                DBG1(DBG_TLS, "verifying DH parameters failed");
                    381:                this->alert->add(this->alert, TLS_FATAL, TLS_BAD_CERTIFICATE);
                    382:                return NEED_MORE;
                    383:        }
                    384:        public->destroy(public);
                    385:        free(chunk.ptr);
                    386: 
                    387:        this->dh = lib->crypto->create_dh(lib->crypto, MODP_CUSTOM,
                    388:                                                                          generator, prime);
                    389:        if (!this->dh)
                    390:        {
                    391:                DBG1(DBG_TLS, "custom DH parameters not supported");
                    392:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    393:                return NEED_MORE;
                    394:        }
                    395:        if (!this->dh->set_other_public_value(this->dh, pub))
                    396:        {
                    397:                DBG1(DBG_TLS, "applying DH public value failed");
                    398:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    399:                return NEED_MORE;
                    400:        }
                    401: 
                    402:        this->state = STATE_KEY_EXCHANGE_RECEIVED;
                    403:        return NEED_MORE;
                    404: }
                    405: 
                    406: /**
                    407:  * Get the EC group for a TLS named curve
                    408:  */
                    409: static diffie_hellman_group_t curve_to_ec_group(private_tls_peer_t *this,
                    410:                                                                                                tls_named_curve_t curve)
                    411: {
                    412:        diffie_hellman_group_t group;
                    413:        tls_named_curve_t current;
                    414:        enumerator_t *enumerator;
                    415: 
                    416:        enumerator = this->crypto->create_ec_enumerator(this->crypto);
                    417:        while (enumerator->enumerate(enumerator, &group, &current))
                    418:        {
                    419:                if (current == curve)
                    420:                {
                    421:                        enumerator->destroy(enumerator);
                    422:                        return group;
                    423:                }
                    424:        }
                    425:        enumerator->destroy(enumerator);
                    426:        return 0;
                    427: }
                    428: 
                    429: /**
                    430:  * Process a Key Exchange message using EC Diffie Hellman
                    431:  */
                    432: static status_t process_ec_key_exchange(private_tls_peer_t *this,
                    433:                                                                                bio_reader_t *reader)
                    434: {
                    435:        diffie_hellman_group_t group;
                    436:        public_key_t *public;
                    437:        uint8_t type;
                    438:        uint16_t curve;
                    439:        chunk_t pub, chunk;
                    440: 
                    441:        chunk = reader->peek(reader);
                    442:        if (!reader->read_uint8(reader, &type))
                    443:        {
                    444:                DBG1(DBG_TLS, "received invalid Server Key Exchange");
                    445:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    446:                return NEED_MORE;
                    447:        }
                    448:        if (type != TLS_ECC_NAMED_CURVE)
                    449:        {
                    450:                DBG1(DBG_TLS, "ECDH curve type %N not supported",
                    451:                         tls_ecc_curve_type_names, type);
                    452:                this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
                    453:                return NEED_MORE;
                    454:        }
                    455:        if (!reader->read_uint16(reader, &curve) ||
                    456:                !reader->read_data8(reader, &pub) || pub.len == 0)
                    457:        {
                    458:                DBG1(DBG_TLS, "received invalid Server Key Exchange");
                    459:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    460:                return NEED_MORE;
                    461:        }
                    462: 
                    463:        group = curve_to_ec_group(this, curve);
                    464:        if (!group)
                    465:        {
                    466:                DBG1(DBG_TLS, "ECDH curve %N not supported",
                    467:                         tls_named_curve_names, curve);
                    468:                this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
                    469:                return NEED_MORE;
                    470:        }
                    471: 
                    472:        public = find_public_key(this);
                    473:        if (!public)
                    474:        {
                    475:                DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server);
                    476:                this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
                    477:                return NEED_MORE;
                    478:        }
                    479: 
                    480:        chunk.len = 4 + pub.len;
                    481:        chunk = chunk_cat("ccc", chunk_from_thing(this->client_random),
                    482:                                          chunk_from_thing(this->server_random), chunk);
                    483:        if (!this->crypto->verify(this->crypto, public, reader, chunk))
                    484:        {
                    485:                public->destroy(public);
                    486:                free(chunk.ptr);
                    487:                DBG1(DBG_TLS, "verifying DH parameters failed");
                    488:                this->alert->add(this->alert, TLS_FATAL, TLS_BAD_CERTIFICATE);
                    489:                return NEED_MORE;
                    490:        }
                    491:        public->destroy(public);
                    492:        free(chunk.ptr);
                    493: 
                    494:        this->dh = lib->crypto->create_dh(lib->crypto, group);
                    495:        if (!this->dh)
                    496:        {
                    497:                DBG1(DBG_TLS, "DH group %N not supported",
                    498:                         diffie_hellman_group_names, group);
                    499:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    500:                return NEED_MORE;
                    501:        }
                    502: 
                    503:        if (pub.ptr[0] != TLS_ANSI_UNCOMPRESSED)
                    504:        {
                    505:                DBG1(DBG_TLS, "DH point format '%N' not supported",
                    506:                         tls_ansi_point_format_names, pub.ptr[0]);
                    507:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    508:                return NEED_MORE;
                    509:        }
                    510:        if (!this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1)))
                    511:        {
                    512:                DBG1(DBG_TLS, "applying DH public value failed");
                    513:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    514:                return NEED_MORE;
                    515:        }
                    516: 
                    517:        this->state = STATE_KEY_EXCHANGE_RECEIVED;
                    518:        return NEED_MORE;
                    519: }
                    520: 
                    521: /**
                    522:  * Process a Server Key Exchange
                    523:  */
                    524: static status_t process_key_exchange(private_tls_peer_t *this,
                    525:                                                                         bio_reader_t *reader)
                    526: {
                    527:        diffie_hellman_group_t group;
                    528: 
                    529:        this->crypto->append_handshake(this->crypto,
                    530:                                                                TLS_SERVER_KEY_EXCHANGE, reader->peek(reader));
                    531: 
                    532:        group = this->crypto->get_dh_group(this->crypto);
                    533:        if (group == MODP_NONE)
                    534:        {
                    535:                DBG1(DBG_TLS, "received Server Key Exchange, but not required "
                    536:                         "for current suite");
                    537:                this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
                    538:                return NEED_MORE;
                    539:        }
                    540:        if (diffie_hellman_group_is_ec(group))
                    541:        {
                    542:                return process_ec_key_exchange(this, reader);
                    543:        }
                    544:        return process_modp_key_exchange(this, reader);
                    545: }
                    546: 
                    547: /**
                    548:  * Process a Certificate Request message
                    549:  */
                    550: static status_t process_certreq(private_tls_peer_t *this, bio_reader_t *reader)
                    551: {
                    552:        chunk_t types, hashsig, data;
                    553:        bio_reader_t *authorities;
                    554:        identification_t *id;
                    555:        certificate_t *cert;
                    556: 
                    557:        if (!this->peer)
                    558:        {
                    559:                DBG1(DBG_TLS, "server requested a certificate, but client "
                    560:                         "authentication disabled");
                    561:        }
                    562:        this->crypto->append_handshake(this->crypto,
                    563:                                                                TLS_CERTIFICATE_REQUEST, reader->peek(reader));
                    564: 
                    565:        if (!reader->read_data8(reader, &types))
                    566:        {
                    567:                DBG1(DBG_TLS, "certreq message header invalid");
                    568:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    569:                return NEED_MORE;
                    570:        }
                    571:        this->cert_types = chunk_clone(types);
                    572:        if (this->tls->get_version(this->tls) >= TLS_1_2)
                    573:        {
                    574:                if (!reader->read_data16(reader, &hashsig))
                    575:                {
                    576:                        DBG1(DBG_TLS, "certreq message invalid");
                    577:                        this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    578:                        return NEED_MORE;
                    579:                }
                    580:                this->hashsig = chunk_clone(hashsig);
                    581:        }
                    582:        if (!reader->read_data16(reader, &data))
                    583:        {
                    584:                DBG1(DBG_TLS, "certreq message invalid");
                    585:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    586:                return NEED_MORE;
                    587:        }
                    588:        authorities = bio_reader_create(data);
                    589:        while (authorities->remaining(authorities))
                    590:        {
                    591:                if (!authorities->read_data16(authorities, &data))
                    592:                {
                    593:                        DBG1(DBG_TLS, "certreq message invalid");
                    594:                        this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    595:                        authorities->destroy(authorities);
                    596:                        return NEED_MORE;
                    597:                }
                    598:                if (this->peer)
                    599:                {
                    600:                        id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
                    601:                        cert = lib->credmgr->get_cert(lib->credmgr,
                    602:                                                                                  CERT_X509, KEY_ANY, id, TRUE);
                    603:                        if (cert)
                    604:                        {
                    605:                                DBG1(DBG_TLS, "received TLS cert request for '%Y", id);
                    606:                                this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
                    607:                        }
                    608:                        else
                    609:                        {
                    610:                                DBG1(DBG_TLS, "received TLS cert request for unknown CA '%Y'", id);
                    611:                        }
                    612:                        id->destroy(id);
                    613:                }
                    614:        }
                    615:        authorities->destroy(authorities);
                    616:        this->state = STATE_CERTREQ_RECEIVED;
                    617:        return NEED_MORE;
                    618: }
                    619: 
                    620: /**
                    621:  * Process Hello Done message
                    622:  */
                    623: static status_t process_hello_done(private_tls_peer_t *this,
                    624:                                                                   bio_reader_t *reader)
                    625: {
                    626:        this->crypto->append_handshake(this->crypto,
                    627:                                                                   TLS_SERVER_HELLO_DONE, reader->peek(reader));
                    628:        this->state = STATE_HELLO_DONE;
                    629:        return NEED_MORE;
                    630: }
                    631: 
                    632: /**
                    633:  * Process finished message
                    634:  */
                    635: static status_t process_finished(private_tls_peer_t *this, bio_reader_t *reader)
                    636: {
                    637:        chunk_t received;
                    638:        char buf[12];
                    639: 
                    640:        if (!reader->read_data(reader, sizeof(buf), &received))
                    641:        {
                    642:                DBG1(DBG_TLS, "received server finished too short");
                    643:                this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
                    644:                return NEED_MORE;
                    645:        }
                    646:        if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
                    647:        {
                    648:                DBG1(DBG_TLS, "calculating server finished failed");
                    649:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    650:                return NEED_MORE;
                    651:        }
                    652:        if (!chunk_equals_const(received, chunk_from_thing(buf)))
                    653:        {
                    654:                DBG1(DBG_TLS, "received server finished invalid");
                    655:                this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
                    656:                return NEED_MORE;
                    657:        }
                    658:        this->state = STATE_FINISHED_RECEIVED;
                    659:        this->crypto->append_handshake(this->crypto, TLS_FINISHED, received);
                    660: 
                    661:        return NEED_MORE;
                    662: }
                    663: 
                    664: METHOD(tls_handshake_t, process, status_t,
                    665:        private_tls_peer_t *this, tls_handshake_type_t type, bio_reader_t *reader)
                    666: {
                    667:        tls_handshake_type_t expected;
                    668: 
                    669:        switch (this->state)
                    670:        {
                    671:                case STATE_HELLO_SENT:
                    672:                        if (type == TLS_SERVER_HELLO)
                    673:                        {
                    674:                                return process_server_hello(this, reader);
                    675:                        }
                    676:                        expected = TLS_SERVER_HELLO;
                    677:                        break;
                    678:                case STATE_HELLO_RECEIVED:
                    679:                        if (type == TLS_CERTIFICATE)
                    680:                        {
                    681:                                return process_certificate(this, reader);
                    682:                        }
                    683:                        expected = TLS_CERTIFICATE;
                    684:                        break;
                    685:                case STATE_CERT_RECEIVED:
                    686:                        if (type == TLS_SERVER_KEY_EXCHANGE)
                    687:                        {
                    688:                                return process_key_exchange(this, reader);
                    689:                        }
                    690:                        /* fall through since TLS_SERVER_KEY_EXCHANGE is optional */
                    691:                case STATE_KEY_EXCHANGE_RECEIVED:
                    692:                        if (type == TLS_CERTIFICATE_REQUEST)
                    693:                        {
                    694:                                return process_certreq(this, reader);
                    695:                        }
                    696:                        /* no cert request, server does not want to authenticate us */
                    697:                        DESTROY_IF(this->peer);
                    698:                        this->peer = NULL;
                    699:                        /* fall through since TLS_CERTIFICATE_REQUEST is optional */
                    700:                case STATE_CERTREQ_RECEIVED:
                    701:                        if (type == TLS_SERVER_HELLO_DONE)
                    702:                        {
                    703:                                return process_hello_done(this, reader);
                    704:                        }
                    705:                        expected = TLS_SERVER_HELLO_DONE;
                    706:                        break;
                    707:                case STATE_CIPHERSPEC_CHANGED_IN:
                    708:                        if (type == TLS_FINISHED)
                    709:                        {
                    710:                                return process_finished(this, reader);
                    711:                        }
                    712:                        expected = TLS_FINISHED;
                    713:                        break;
                    714:                default:
                    715:                        DBG1(DBG_TLS, "TLS %N not expected in current state",
                    716:                                 tls_handshake_type_names, type);
                    717:                        this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
                    718:                        return NEED_MORE;
                    719:        }
                    720:        DBG1(DBG_TLS, "TLS %N expected, but received %N",
                    721:                 tls_handshake_type_names, expected, tls_handshake_type_names, type);
                    722:        this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE);
                    723:        return NEED_MORE;
                    724: }
                    725: 
                    726: /**
                    727:  * Send a client hello
                    728:  */
                    729: static status_t send_client_hello(private_tls_peer_t *this,
                    730:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                    731: {
                    732:        tls_cipher_suite_t *suites;
                    733:        bio_writer_t *extensions, *curves = NULL;
                    734:        tls_version_t version;
                    735:        tls_named_curve_t curve;
                    736:        enumerator_t *enumerator;
                    737:        int count, i;
                    738:        rng_t *rng;
                    739: 
                    740:        htoun32(&this->client_random, time(NULL));
                    741:        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
                    742:        if (!rng ||
                    743:                !rng->get_bytes(rng, sizeof(this->client_random) - 4,
                    744:                                                this->client_random + 4))
                    745:        {
                    746:                DBG1(DBG_TLS, "failed to generate client random");
                    747:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    748:                DESTROY_IF(rng);
                    749:                return NEED_MORE;
                    750:        }
                    751:        rng->destroy(rng);
                    752: 
                    753:        /* TLS version */
                    754:        version = this->tls->get_version(this->tls);
                    755:        this->hello_version = version;
                    756:        writer->write_uint16(writer, version);
                    757:        writer->write_data(writer, chunk_from_thing(this->client_random));
                    758: 
                    759:        /* session identifier */
                    760:        this->session = this->crypto->get_session(this->crypto, this->server);
                    761:        writer->write_data8(writer, this->session);
                    762: 
                    763:        /* add TLS cipher suites */
                    764:        count = this->crypto->get_cipher_suites(this->crypto, &suites);
                    765:        writer->write_uint16(writer, count * 2);
                    766:        for (i = 0; i < count; i++)
                    767:        {
                    768:                writer->write_uint16(writer, suites[i]);
                    769:        }
                    770: 
                    771:        /* NULL compression only */
                    772:        writer->write_uint8(writer, 1);
                    773:        writer->write_uint8(writer, 0);
                    774: 
                    775:        extensions = bio_writer_create(32);
                    776: 
                    777:        extensions->write_uint16(extensions, TLS_EXT_SIGNATURE_ALGORITHMS);
                    778:        this->crypto->get_signature_algorithms(this->crypto, extensions);
                    779: 
                    780:        /* add supported Elliptic Curves, if any */
                    781:        enumerator = this->crypto->create_ec_enumerator(this->crypto);
                    782:        while (enumerator->enumerate(enumerator, NULL, &curve))
                    783:        {
                    784:                if (!curves)
                    785:                {
                    786:                        extensions->write_uint16(extensions, TLS_EXT_ELLIPTIC_CURVES);
                    787:                        curves = bio_writer_create(16);
                    788:                }
                    789:                curves->write_uint16(curves, curve);
                    790:        }
                    791:        enumerator->destroy(enumerator);
                    792:        if (curves)
                    793:        {
                    794:                curves->wrap16(curves);
                    795:                extensions->write_data16(extensions, curves->get_buf(curves));
                    796:                curves->destroy(curves);
                    797: 
                    798:                /* if we support curves, add point format extension */
                    799:                extensions->write_uint16(extensions, TLS_EXT_EC_POINT_FORMATS);
                    800:                extensions->write_uint16(extensions, 2);
                    801:                extensions->write_uint8(extensions, 1);
                    802:                extensions->write_uint8(extensions, TLS_EC_POINT_UNCOMPRESSED);
                    803:        }
                    804:        if (this->server->get_type(this->server) == ID_FQDN)
                    805:        {
                    806:                bio_writer_t *names;
                    807: 
                    808:                DBG2(DBG_TLS, "sending Server Name Indication for '%Y'", this->server);
                    809: 
                    810:                names = bio_writer_create(8);
                    811:                names->write_uint8(names, TLS_NAME_TYPE_HOST_NAME);
                    812:                names->write_data16(names, this->server->get_encoding(this->server));
                    813:                names->wrap16(names);
                    814:                extensions->write_uint16(extensions, TLS_EXT_SERVER_NAME);
                    815:                extensions->write_data16(extensions, names->get_buf(names));
                    816:                names->destroy(names);
                    817:        }
                    818: 
                    819:        writer->write_data16(writer, extensions->get_buf(extensions));
                    820:        extensions->destroy(extensions);
                    821: 
                    822:        *type = TLS_CLIENT_HELLO;
                    823:        this->state = STATE_HELLO_SENT;
                    824:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                    825:        return NEED_MORE;
                    826: }
                    827: 
                    828: /**
                    829:  * Find a private key suitable to sign Certificate Verify
                    830:  */
                    831: static private_key_t *find_private_key(private_tls_peer_t *this)
                    832: {
                    833:        private_key_t *key = NULL;
                    834:        bio_reader_t *reader;
                    835:        key_type_t type;
                    836:        uint8_t cert;
                    837: 
                    838:        if (!this->peer)
                    839:        {
                    840:                return NULL;
                    841:        }
                    842:        reader = bio_reader_create(this->cert_types);
                    843:        while (reader->remaining(reader) && reader->read_uint8(reader, &cert))
                    844:        {
                    845:                switch (cert)
                    846:                {
                    847:                        case TLS_RSA_SIGN:
                    848:                                type = KEY_RSA;
                    849:                                break;
                    850:                        case TLS_ECDSA_SIGN:
                    851:                                type = KEY_ECDSA;
                    852:                                break;
                    853:                        default:
                    854:                                continue;
                    855:                }
                    856:                key = lib->credmgr->get_private(lib->credmgr, type,
                    857:                                                                                this->peer, this->peer_auth);
                    858:                if (key)
                    859:                {
                    860:                        break;
                    861:                }
                    862:        }
                    863:        reader->destroy(reader);
                    864:        return key;
                    865: }
                    866: 
                    867: /**
                    868:  * Send Certificate
                    869:  */
                    870: static status_t send_certificate(private_tls_peer_t *this,
                    871:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                    872: {
                    873:        enumerator_t *enumerator;
                    874:        certificate_t *cert;
                    875:        auth_rule_t rule;
                    876:        bio_writer_t *certs;
                    877:        chunk_t data;
                    878: 
                    879:        this->private = find_private_key(this);
                    880:        if (!this->private)
                    881:        {
                    882:                DBG1(DBG_TLS, "no TLS peer certificate found for '%Y', "
                    883:                         "skipping client authentication", this->peer);
                    884:                this->peer->destroy(this->peer);
                    885:                this->peer = NULL;
                    886:        }
                    887: 
                    888:        /* generate certificate payload */
                    889:        certs = bio_writer_create(256);
                    890:        if (this->peer)
                    891:        {
                    892:                cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
                    893:                if (cert)
                    894:                {
                    895:                        if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
                    896:                        {
                    897:                                DBG1(DBG_TLS, "sending TLS peer certificate '%Y'",
                    898:                                         cert->get_subject(cert));
                    899:                                certs->write_data24(certs, data);
                    900:                                free(data.ptr);
                    901:                        }
                    902:                }
                    903:                enumerator = this->peer_auth->create_enumerator(this->peer_auth);
                    904:                while (enumerator->enumerate(enumerator, &rule, &cert))
                    905:                {
                    906:                        if (rule == AUTH_RULE_IM_CERT)
                    907:                        {
                    908:                                if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
                    909:                                {
                    910:                                        DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'",
                    911:                                                 cert->get_subject(cert));
                    912:                                        certs->write_data24(certs, data);
                    913:                                        free(data.ptr);
                    914:                                }
                    915:                        }
                    916:                }
                    917:                enumerator->destroy(enumerator);
                    918:        }
                    919: 
                    920:        writer->write_data24(writer, certs->get_buf(certs));
                    921:        certs->destroy(certs);
                    922: 
                    923:        *type = TLS_CERTIFICATE;
                    924:        this->state = STATE_CERT_SENT;
                    925:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                    926:        return NEED_MORE;
                    927: }
                    928: 
                    929: /**
                    930:  * Send client key exchange, using premaster encryption
                    931:  */
                    932: static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
                    933:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                    934: {
                    935:        public_key_t *public;
                    936:        rng_t *rng;
                    937:        char premaster[48];
                    938:        chunk_t encrypted;
                    939: 
                    940:        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
                    941:        if (!rng || !rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2))
                    942:        {
                    943:                DBG1(DBG_TLS, "failed to generate TLS premaster secret");
                    944:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    945:                DESTROY_IF(rng);
                    946:                return NEED_MORE;
                    947:        }
                    948:        rng->destroy(rng);
                    949:        htoun16(premaster, this->hello_version);
                    950: 
                    951:        if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
                    952:                                                                          this->session, this->server,
                    953:                                                                          chunk_from_thing(this->client_random),
                    954:                                                                          chunk_from_thing(this->server_random)))
                    955:        {
                    956:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    957:                return NEED_MORE;
                    958:        }
                    959: 
                    960:        public = find_public_key(this);
                    961:        if (!public)
                    962:        {
                    963:                DBG1(DBG_TLS, "no TLS public key found for server '%Y'", this->server);
                    964:                this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN);
                    965:                return NEED_MORE;
                    966:        }
                    967:        if (!public->encrypt(public, ENCRYPT_RSA_PKCS1,
                    968:                                                 chunk_from_thing(premaster), &encrypted))
                    969:        {
                    970:                public->destroy(public);
                    971:                DBG1(DBG_TLS, "encrypting TLS premaster secret failed");
                    972:                this->alert->add(this->alert, TLS_FATAL, TLS_BAD_CERTIFICATE);
                    973:                return NEED_MORE;
                    974:        }
                    975:        public->destroy(public);
                    976: 
                    977:        writer->write_data16(writer, encrypted);
                    978:        free(encrypted.ptr);
                    979: 
                    980:        *type = TLS_CLIENT_KEY_EXCHANGE;
                    981:        this->state = STATE_KEY_EXCHANGE_SENT;
                    982:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                    983:        return NEED_MORE;
                    984: }
                    985: 
                    986: /**
                    987:  * Send client key exchange, using DHE exchange
                    988:  */
                    989: static status_t send_key_exchange_dhe(private_tls_peer_t *this,
                    990:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                    991: {
                    992:        chunk_t premaster, pub;
                    993: 
                    994:        if (!this->dh->get_shared_secret(this->dh, &premaster))
                    995:        {
                    996:                DBG1(DBG_TLS, "calculating premaster from DH failed");
                    997:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                    998:                return NEED_MORE;
                    999:        }
                   1000:        if (!this->crypto->derive_secrets(this->crypto, premaster,
                   1001:                                                                          this->session, this->server,
                   1002:                                                                          chunk_from_thing(this->client_random),
                   1003:                                                                          chunk_from_thing(this->server_random)))
                   1004:        {
                   1005:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                   1006:                chunk_clear(&premaster);
                   1007:                return NEED_MORE;
                   1008:        }
                   1009:        chunk_clear(&premaster);
                   1010: 
                   1011:        if (!this->dh->get_my_public_value(this->dh, &pub))
                   1012:        {
                   1013:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                   1014:                return NEED_MORE;
                   1015:        }
                   1016:        if (this->dh->get_dh_group(this->dh) == MODP_CUSTOM)
                   1017:        {
                   1018:                writer->write_data16(writer, pub);
                   1019:        }
                   1020:        else
                   1021:        {       /* ECP uses 8bit length header only, but a point format */
                   1022:                writer->write_uint8(writer, pub.len + 1);
                   1023:                writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED);
                   1024:                writer->write_data(writer, pub);
                   1025:        }
                   1026:        free(pub.ptr);
                   1027: 
                   1028:        *type = TLS_CLIENT_KEY_EXCHANGE;
                   1029:        this->state = STATE_KEY_EXCHANGE_SENT;
                   1030:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                   1031:        return NEED_MORE;
                   1032: }
                   1033: 
                   1034: /**
                   1035:  * Send client key exchange, depending on suite
                   1036:  */
                   1037: static status_t send_key_exchange(private_tls_peer_t *this,
                   1038:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                   1039: {
                   1040:        if (this->dh)
                   1041:        {
                   1042:                return send_key_exchange_dhe(this, type, writer);
                   1043:        }
                   1044:        return send_key_exchange_encrypt(this, type, writer);
                   1045: }
                   1046: 
                   1047: /**
                   1048:  * Send certificate verify
                   1049:  */
                   1050: static status_t send_certificate_verify(private_tls_peer_t *this,
                   1051:                                                        tls_handshake_type_t *type, bio_writer_t *writer)
                   1052: {
                   1053:        if (!this->private ||
                   1054:                !this->crypto->sign_handshake(this->crypto, this->private,
                   1055:                                                                          writer, this->hashsig))
                   1056:        {
                   1057:                DBG1(DBG_TLS, "creating TLS Certificate Verify signature failed");
                   1058:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                   1059:                return NEED_MORE;
                   1060:        }
                   1061: 
                   1062:        *type = TLS_CERTIFICATE_VERIFY;
                   1063:        this->state = STATE_VERIFY_SENT;
                   1064:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                   1065:        return NEED_MORE;
                   1066: }
                   1067: 
                   1068: /**
                   1069:  * Send Finished
                   1070:  */
                   1071: static status_t send_finished(private_tls_peer_t *this,
                   1072:                                                          tls_handshake_type_t *type, bio_writer_t *writer)
                   1073: {
                   1074:        char buf[12];
                   1075: 
                   1076:        if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
                   1077:        {
                   1078:                DBG1(DBG_TLS, "calculating client finished data failed");
                   1079:                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                   1080:                return NEED_MORE;
                   1081:        }
                   1082: 
                   1083:        writer->write_data(writer, chunk_from_thing(buf));
                   1084: 
                   1085:        *type = TLS_FINISHED;
                   1086:        this->state = STATE_FINISHED_SENT;
                   1087:        this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
                   1088:        return NEED_MORE;
                   1089: }
                   1090: 
                   1091: METHOD(tls_handshake_t, build, status_t,
                   1092:        private_tls_peer_t *this, tls_handshake_type_t *type, bio_writer_t *writer)
                   1093: {
                   1094:        switch (this->state)
                   1095:        {
                   1096:                case STATE_INIT:
                   1097:                        return send_client_hello(this, type, writer);
                   1098:                case STATE_HELLO_DONE:
                   1099:                        if (this->peer)
                   1100:                        {
                   1101:                                return send_certificate(this, type, writer);
                   1102:                        }
                   1103:                        /* otherwise fall through to next state */
                   1104:                case STATE_CERT_SENT:
                   1105:                        return send_key_exchange(this, type, writer);
                   1106:                case STATE_KEY_EXCHANGE_SENT:
                   1107:                        if (this->peer)
                   1108:                        {
                   1109:                                return send_certificate_verify(this, type, writer);
                   1110:                        }
                   1111:                        else
                   1112:                        {
                   1113:                                return INVALID_STATE;
                   1114:                        }
                   1115:                case STATE_CIPHERSPEC_CHANGED_OUT:
                   1116:                        return send_finished(this, type, writer);
                   1117:                default:
                   1118:                        return INVALID_STATE;
                   1119:        }
                   1120: }
                   1121: 
                   1122: METHOD(tls_handshake_t, cipherspec_changed, bool,
                   1123:        private_tls_peer_t *this, bool inbound)
                   1124: {
                   1125:        if (inbound)
                   1126:        {
                   1127:                if (this->resume)
                   1128:                {
                   1129:                        return this->state == STATE_HELLO_RECEIVED;
                   1130:                }
                   1131:                return this->state == STATE_FINISHED_SENT;
                   1132:        }
                   1133:        else
                   1134:        {
                   1135:                if (this->resume)
                   1136:                {
                   1137:                        return this->state == STATE_FINISHED_RECEIVED;
                   1138:                }
                   1139:                if (this->peer)
                   1140:                {
                   1141:                        return this->state == STATE_VERIFY_SENT;
                   1142:                }
                   1143:                return this->state == STATE_KEY_EXCHANGE_SENT;
                   1144:        }
                   1145: }
                   1146: 
                   1147: METHOD(tls_handshake_t, change_cipherspec, void,
                   1148:        private_tls_peer_t *this, bool inbound)
                   1149: {
                   1150:        this->crypto->change_cipher(this->crypto, inbound);
                   1151:        if (inbound)
                   1152:        {
                   1153:                this->state = STATE_CIPHERSPEC_CHANGED_IN;
                   1154:        }
                   1155:        else
                   1156:        {
                   1157:                this->state = STATE_CIPHERSPEC_CHANGED_OUT;
                   1158:        }
                   1159: }
                   1160: 
                   1161: METHOD(tls_handshake_t, finished, bool,
                   1162:        private_tls_peer_t *this)
                   1163: {
                   1164:        if (this->resume)
                   1165:        {
                   1166:                return this->state == STATE_FINISHED_SENT;
                   1167:        }
                   1168:        return this->state == STATE_FINISHED_RECEIVED;
                   1169: }
                   1170: 
                   1171: METHOD(tls_handshake_t, get_peer_id, identification_t*,
                   1172:        private_tls_peer_t *this)
                   1173: {
                   1174:        return this->peer;
                   1175: }
                   1176: 
                   1177: METHOD(tls_handshake_t, get_server_id, identification_t*,
                   1178:        private_tls_peer_t *this)
                   1179: {
                   1180:        return this->server;
                   1181: }
                   1182: 
                   1183: METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
                   1184:        private_tls_peer_t *this)
                   1185: {
                   1186:        return this->server_auth;
                   1187: }
                   1188: 
                   1189: METHOD(tls_handshake_t, destroy, void,
                   1190:        private_tls_peer_t *this)
                   1191: {
                   1192:        DESTROY_IF(this->private);
                   1193:        DESTROY_IF(this->dh);
                   1194:        DESTROY_IF(this->peer);
                   1195:        this->server->destroy(this->server);
                   1196:        this->peer_auth->destroy(this->peer_auth);
                   1197:        this->server_auth->destroy(this->server_auth);
                   1198:        free(this->hashsig.ptr);
                   1199:        free(this->cert_types.ptr);
                   1200:        free(this->session.ptr);
                   1201:        free(this);
                   1202: }
                   1203: 
                   1204: /**
                   1205:  * See header
                   1206:  */
                   1207: tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert,
                   1208:                                                        identification_t *peer, identification_t *server)
                   1209: {
                   1210:        private_tls_peer_t *this;
                   1211: 
                   1212:        INIT(this,
                   1213:                .public = {
                   1214:                        .handshake = {
                   1215:                                .process = _process,
                   1216:                                .build = _build,
                   1217:                                .cipherspec_changed = _cipherspec_changed,
                   1218:                                .change_cipherspec = _change_cipherspec,
                   1219:                                .finished = _finished,
                   1220:                                .get_peer_id = _get_peer_id,
                   1221:                                .get_server_id = _get_server_id,
                   1222:                                .get_auth = _get_auth,
                   1223:                                .destroy = _destroy,
                   1224:                        },
                   1225:                },
                   1226:                .state = STATE_INIT,
                   1227:                .tls = tls,
                   1228:                .crypto = crypto,
                   1229:                .alert = alert,
                   1230:                .peer = peer ? peer->clone(peer) : NULL,
                   1231:                .server = server->clone(server),
                   1232:                .peer_auth = auth_cfg_create(),
                   1233:                .server_auth = auth_cfg_create(),
                   1234:        );
                   1235: 
                   1236:        return &this->public;
                   1237: }

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