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