File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libtls / tls.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:20:09 2021 UTC (3 years, 5 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, HEAD
strongswan 5.9.2

    1: /*
    2:  * Copyright (C) 2021 Tobias Brunner
    3:  * Copyright (C) 2020-2021 Pascal Knecht
    4:  * HSR Hochschule fuer Technik Rapperswil
    5:  *
    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: 
   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,
   34: 	"SSLv2");
   35: ENUM_NEXT(tls_version_names, SSL_3_0, TLS_1_3, SSL_2_0,
   36: 	"SSLv3",
   37: 	"TLS 1.0",
   38: 	"TLS 1.1",
   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");
   51: 
   52: ENUM(tls_content_type_names, TLS_CHANGE_CIPHER_SPEC, TLS_APPLICATION_DATA,
   53: 	"ChangeCipherSpec",
   54: 	"Alert",
   55: 	"Handshake",
   56: 	"ApplicationData",
   57: );
   58: 
   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,
   63: 	"ClientHello",
   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");
   73: ENUM_NEXT(tls_handshake_type_names,
   74: 		TLS_CERTIFICATE, TLS_CLIENT_KEY_EXCHANGE, TLS_ENCRYPTED_EXTENSIONS,
   75: 	"Certificate",
   76: 	"ServerKeyExchange",
   77: 	"CertificateRequest",
   78: 	"ServerHelloDone",
   79: 	"CertificateVerify",
   80: 	"ClientKeyExchange");
   81: ENUM_NEXT(tls_handshake_type_names,
   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);
   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,
  101: 		TLS_EXT_SUPPORTED_GROUPS, TLS_EXT_EC_POINT_FORMATS,
  102: 		TLS_EXT_STATUS_REQUEST,
  103: 	"supported groups",
  104: 	"ec point formats");
  105: ENUM_NEXT(tls_extension_names,
  106: 		TLS_EXT_SIGNATURE_ALGORITHMS,
  107: 		TLS_EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
  108: 		TLS_EXT_EC_POINT_FORMATS,
  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");
  143: ENUM_NEXT(tls_extension_names,
  144: 		TLS_EXT_RENEGOTIATION_INFO, TLS_EXT_RENEGOTIATION_INFO,
  145: 		TLS_EXT_KEY_SHARE,
  146: 	"renegotiation info");
  147: ENUM_END(tls_extension_names, TLS_EXT_RENEGOTIATION_INFO);
  148: 
  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: 
  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: 	/**
  191: 	 * Negotiated TLS version and maximum supported TLS version
  192: 	 */
  193: 	tls_version_t version_max;
  194: 
  195: 	/**
  196: 	 * Minimal supported TLS version
  197: 	 */
  198: 	tls_version_t version_min;
  199: 
  200: 	/**
  201: 	 * TLS stack purpose, as given to constructor
  202: 	 */
  203: 	tls_purpose_t purpose;
  204: 
  205: 	/**
  206: 	 * Flags for this TLS stack
  207: 	 */
  208: 	tls_flag_t flags;
  209: 
  210: 	/**
  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;
  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: 					}
  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: 
  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,
  508: 	private_tls_t *this)
  509: {
  510: 	determine_versions(this);
  511: 	return this->version_min;
  512: }
  513: 
  514: METHOD(tls_t, set_version, bool,
  515: 	private_tls_t *this, tls_version_t min_version, tls_version_t max_version)
  516: {
  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)
  530: 	{
  531: 		return FALSE;
  532: 	}
  533: 
  534: 	this->version_min = min_version;
  535: 	this->version_max = max_version;
  536: 
  537: 	if (min_version != TLS_UNSPEC && min_version == max_version)
  538: 	{
  539: 		this->protection->set_version(this->protection, max_version);
  540: 	}
  541: 	return TRUE;
  542: }
  543: 
  544: METHOD(tls_t, get_purpose, tls_purpose_t,
  545: 	private_tls_t *this)
  546: {
  547: 	return this->purpose;
  548: }
  549: 
  550: METHOD(tls_t, get_flags, tls_flag_t,
  551: 	private_tls_t *this)
  552: {
  553: 	return this->flags;
  554: }
  555: 
  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,
  604: 				  tls_application_t *application, tls_cache_t *cache,
  605: 				  tls_flag_t flags)
  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,
  627: 			.get_version_max = _get_version_max,
  628: 			.get_version_min = _get_version_min,
  629: 			.set_version = _set_version,
  630: 			.get_purpose = _get_purpose,
  631: 			.get_flags = _get_flags,
  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,
  640: 		.flags = flags,
  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>