tls: remove non-RSA CipherSuites
[siplcs.git] / src / core / sipe-tls.c
blobf51d13e28f284962831413db75367fe41e5185d2
1 /**
2 * @file sipe-tls.c
4 * pidgin-sipe
6 * Copyright (C) 2011-2015 SIPE Project <http://sipe.sourceforge.net/>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * TLS Protocol Version 1.0/1.1/1.2 - Handshake Messages
26 * TLS-DSK uses the handshake messages during authentication and session key
27 * exchange. This module *ONLY* implements this part of the TLS specification!
29 * Specification references:
31 * - RFC2246: http://www.ietf.org/rfc/rfc2246.txt
32 * - RFC3546: http://www.ietf.org/rfc/rfc3546.txt
33 * - RFC4346: http://www.ietf.org/rfc/rfc4346.txt
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdarg.h>
40 #include <glib.h>
42 #include "sipe-common.h"
43 #include "sipe-backend.h"
44 #include "sipe-cert-crypto.h"
45 #include "sipe-crypt.h"
46 #include "sipe-digest.h"
47 #include "sipe-svc.h"
48 #include "sipe-tls.h"
51 * Private part of TLS state tracking
53 enum tls_handshake_state {
54 TLS_HANDSHAKE_STATE_START,
55 TLS_HANDSHAKE_STATE_SERVER_HELLO,
56 TLS_HANDSHAKE_STATE_FINISHED,
57 TLS_HANDSHAKE_STATE_COMPLETED,
58 TLS_HANDSHAKE_STATE_FAILED
61 struct tls_internal_state {
62 struct sipe_tls_state common;
63 gpointer certificate;
64 enum tls_handshake_state state;
65 guchar *msg_current;
66 gsize msg_remainder;
67 GHashTable *data;
68 GString *debug;
69 guint cipher_type;
70 gpointer md5_context;
71 gpointer sha1_context;
72 gpointer server_certificate;
73 struct sipe_tls_random client_random;
74 struct sipe_tls_random server_random;
75 struct sipe_tls_random pre_master_secret;
76 gsize mac_length;
77 gsize key_length;
78 guchar *master_secret;
79 guchar *key_block;
80 guchar *tls_dsk_key_block;
81 const guchar *client_write_mac_secret;
82 const guchar *server_write_mac_secret;
83 const guchar *client_write_secret;
84 const guchar *server_write_secret;
85 void (*mac_func)(const guchar *key, gsize key_length,
86 const guchar *data, gsize data_length,
87 guchar *digest);
88 gpointer cipher_context;
89 guint64 sequence_number;
90 gboolean encrypted;
94 * TLS messages & layout descriptors
97 /* constants */
98 #define TLS_VECTOR_MAX8 255 /* 2^8 - 1 */
99 #define TLS_VECTOR_MAX16 65535 /* 2^16 - 1 */
100 #define TLS_VECTOR_MAX24 16777215 /* 2^24 - 1 */
102 #define TLS_PROTOCOL_VERSION_1_0 0x0301
103 #define TLS_PROTOCOL_VERSION_1_1 0x0302
104 #define TLS_PROTOCOL_VERSION_1_2 0x0303
106 /* CipherSuites */
107 #define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
108 #define TLS_RSA_WITH_RC4_128_MD5 0x0004
109 #define TLS_RSA_WITH_RC4_128_SHA 0x0005
110 #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014
112 /* CompressionMethods */
113 #define TLS_COMP_METHOD_NULL 0
115 /* various array lengths */
116 #define TLS_ARRAY_RANDOM_LENGTH 32
117 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
118 #define TLS_ARRAY_VERIFY_LENGTH 12
120 #define TLS_RECORD_HEADER_LENGTH 5
121 #define TLS_RECORD_OFFSET_TYPE 0
122 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
123 #define TLS_RECORD_TYPE_HANDSHAKE 22
124 #define TLS_RECORD_OFFSET_VERSION 1
125 #define TLS_RECORD_OFFSET_LENGTH 3
127 #define TLS_HANDSHAKE_HEADER_LENGTH 4
128 #define TLS_HANDSHAKE_OFFSET_TYPE 0
129 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
130 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
131 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
132 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
133 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
134 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
135 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
136 #define TLS_HANDSHAKE_TYPE_FINISHED 20
137 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
139 struct layout_descriptor;
140 typedef gboolean parse_func(struct tls_internal_state *state,
141 const struct layout_descriptor *desc);
143 /* Defines the strictest alignment requirement */
144 struct tls_compile_integer;
145 typedef void compile_func(struct tls_internal_state *state,
146 const struct layout_descriptor *desc,
147 const struct tls_compile_integer *data);
149 struct layout_descriptor {
150 const gchar *label;
151 parse_func *parser;
152 compile_func *compiler;
153 gsize min; /* 0 for fixed/array */
154 gsize max;
155 gsize offset;
158 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
159 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
161 struct msg_descriptor {
162 const struct msg_descriptor *next;
163 const gchar *description;
164 const struct layout_descriptor *layouts;
165 guint type;
168 /* parsed data */
169 struct tls_parsed_integer {
170 guint value;
173 struct tls_parsed_array {
174 gsize length; /* bytes */
175 const guchar data[0];
178 /* compile data */
179 struct tls_compile_integer {
180 gsize value;
183 struct tls_compile_array {
184 gsize elements; /* unused */
185 guchar placeholder[];
188 struct tls_compile_random {
189 gsize elements; /* unused */
190 guchar random[TLS_ARRAY_RANDOM_LENGTH];
193 struct tls_compile_verify {
194 gsize elements; /* unused */
195 guchar verify[TLS_ARRAY_VERIFY_LENGTH];
198 struct tls_compile_vector {
199 gsize elements; /* VECTOR */
200 guint placeholder[];
203 struct tls_compile_sessionid {
204 gsize elements; /* VECTOR */
207 struct tls_compile_cipher {
208 gsize elements; /* VECTOR */
209 guint suites[4];
212 struct tls_compile_compression {
213 gsize elements; /* VECTOR */
214 guint methods[1];
217 /* compiled message */
218 struct tls_compiled_message {
219 gsize size;
220 guchar data[];
224 * Random byte buffers
226 void sipe_tls_fill_random(struct sipe_tls_random *random,
227 guint bits)
229 guint bytes = ((bits + 15) / 16) * 2;
230 guint16 *p = g_malloc(bytes);
232 SIPE_DEBUG_INFO("sipe_tls_fill_random: %d bits -> %d bytes",
233 bits, bytes);
235 random->buffer = (guint8*) p;
236 random->length = bytes;
238 for (bytes /= 2; bytes; bytes--)
239 *p++ = rand() & 0xFFFF;
242 void sipe_tls_free_random(struct sipe_tls_random *random)
244 g_free(random->buffer);
248 * TLS message debugging
250 static void debug_hex(struct tls_internal_state *state,
251 gsize alternative_length)
253 GString *str = state->debug;
254 const guchar *bytes;
255 gsize length;
256 gint count;
258 if (!str) return;
260 bytes = state->msg_current;
261 length = alternative_length ? alternative_length : state->msg_remainder;
262 count = -1;
264 while (length-- > 0) {
265 if (++count == 0) {
266 /* do nothing */;
267 } else if ((count % 16) == 0) {
268 g_string_append(str, "\n");
269 } else if ((count % 8) == 0) {
270 g_string_append(str, " ");
272 g_string_append_printf(str, " %02X", *bytes++);
274 g_string_append(str, "\n");
277 #define debug_print(state, string) \
278 if (state->debug) g_string_append(state->debug, string)
279 #define debug_printf(state, format, ...) \
280 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
282 /* Analyzer only needs the debugging functions */
283 #ifndef _SIPE_COMPILING_ANALYZER
285 static void debug_secrets(struct tls_internal_state *state,
286 const gchar *label,
287 const guchar *secret,
288 gsize secret_length)
290 if (state->debug && secret) {
291 g_string_append_printf(state->debug, "%s (%3" G_GSIZE_FORMAT ") = ",
292 label, secret_length);
293 while (secret_length--)
294 g_string_append_printf(state->debug, "%02X", *secret++);
295 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
296 g_string_truncate(state->debug, 0);
301 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
303 static guchar *sipe_tls_p_md5(const guchar *secret,
304 gsize secret_length,
305 const guchar *seed,
306 gsize seed_length,
307 gsize output_length)
309 guchar *output = NULL;
312 * output_length == 0 -> illegal
313 * output_length == 1..16 -> iterations = 1
314 * output_length == 17..32 -> iterations = 2
316 if (secret && seed && (output_length > 0)) {
317 guint iterations = (output_length + SIPE_DIGEST_HMAC_MD5_LENGTH - 1) / SIPE_DIGEST_HMAC_MD5_LENGTH;
318 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length);
319 guchar A[SIPE_DIGEST_HMAC_MD5_LENGTH];
320 guchar *p;
322 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
323 secret_length, seed_length);
324 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
325 output_length, iterations);
327 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
328 sipe_digest_hmac_md5(secret, secret_length,
329 seed, seed_length,
332 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
333 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_MD5_LENGTH);
335 while (iterations-- > 0) {
336 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
337 guchar P[SIPE_DIGEST_HMAC_MD5_LENGTH];
338 memcpy(concat, A, SIPE_DIGEST_HMAC_MD5_LENGTH);
339 memcpy(concat + SIPE_DIGEST_HMAC_MD5_LENGTH, seed, seed_length);
340 sipe_digest_hmac_md5(secret, secret_length,
341 concat, SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length,
343 memcpy(p, P, SIPE_DIGEST_HMAC_MD5_LENGTH);
344 p += SIPE_DIGEST_HMAC_MD5_LENGTH;
346 /* A(i+1) = HMAC_MD5(secret, A(i)) */
347 sipe_digest_hmac_md5(secret, secret_length,
348 A, SIPE_DIGEST_HMAC_MD5_LENGTH,
351 g_free(concat);
354 return(output);
357 guchar *sipe_tls_p_sha1(const guchar *secret,
358 gsize secret_length,
359 const guchar *seed,
360 gsize seed_length,
361 gsize output_length)
363 guchar *output = NULL;
366 * output_length == 0 -> illegal
367 * output_length == 1..20 -> iterations = 1
368 * output_length == 21..40 -> iterations = 2
370 if (secret && seed && (output_length > 0)) {
371 guint iterations = (output_length + SIPE_DIGEST_HMAC_SHA1_LENGTH - 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH;
372 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length);
373 guchar A[SIPE_DIGEST_HMAC_SHA1_LENGTH];
374 guchar *p;
376 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
377 secret_length, seed_length);
378 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
379 output_length, iterations);
381 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
382 sipe_digest_hmac_sha1(secret, secret_length,
383 seed, seed_length,
386 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
387 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_SHA1_LENGTH);
389 while (iterations-- > 0) {
390 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
391 guchar P[SIPE_DIGEST_HMAC_SHA1_LENGTH];
392 memcpy(concat, A, SIPE_DIGEST_HMAC_SHA1_LENGTH);
393 memcpy(concat + SIPE_DIGEST_HMAC_SHA1_LENGTH, seed, seed_length);
394 sipe_digest_hmac_sha1(secret, secret_length,
395 concat, SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length,
397 memcpy(p, P, SIPE_DIGEST_HMAC_SHA1_LENGTH);
398 p += SIPE_DIGEST_HMAC_SHA1_LENGTH;
400 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
401 sipe_digest_hmac_sha1(secret, secret_length,
402 A, SIPE_DIGEST_HMAC_SHA1_LENGTH,
405 g_free(concat);
408 return(output);
411 static guchar *sipe_tls_prf(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
412 const guchar *secret,
413 gsize secret_length,
414 const guchar *label,
415 gsize label_length,
416 const guchar *seed,
417 gsize seed_length,
418 gsize output_length)
420 gsize half = (secret_length + 1) / 2;
421 gsize newseed_length = label_length + seed_length;
422 /* secret: used as S1; secret2: last half of original secret (S2) */
423 guchar *secret2 = g_memdup(secret + secret_length - half, half);
424 guchar *newseed = g_malloc(newseed_length);
425 guchar *md5, *dest;
426 guchar *sha1, *src;
427 gsize count;
429 /* make Coverity happy - lengths could be 0 */
430 if (!secret2 || !newseed) {
431 g_free(secret2);
432 g_free(newseed);
433 return(NULL);
437 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
438 * P_SHA-1(S2, label + seed);
440 memcpy(newseed, label, label_length);
441 memcpy(newseed + label_length, seed, seed_length);
442 #undef __SIPE_TLS_CRYPTO_DEBUG
443 #ifdef __SIPE_TLS_CRYPTO_DEBUG
444 debug_secrets(state, "sipe_tls_prf: secret ",
445 secret, secret_length);
446 debug_secrets(state, "sipe_tls_prf: combined seed ",
447 newseed, newseed_length);
448 SIPE_DEBUG_INFO("total seed length %" G_GSIZE_FORMAT,
449 newseed_length);
450 debug_secrets(state, "sipe_tls_prf: S1 ",
451 secret, half);
452 debug_secrets(state, "sipe_tls_prf: S2 ",
453 secret2, half);
454 #endif
455 md5 = sipe_tls_p_md5(secret, half, newseed, newseed_length, output_length);
456 sha1 = sipe_tls_p_sha1(secret2, half, newseed, newseed_length, output_length);
457 #ifdef __SIPE_TLS_CRYPTO_DEBUG
458 debug_secrets(state, "sipe_tls_prf: P_md5() ",
459 md5, output_length);
460 debug_secrets(state, "sipe_tls_prf: P_sha1() ",
461 sha1, output_length);
462 #endif
463 for (dest = md5, src = sha1, count = output_length;
464 count > 0;
465 count--)
466 *dest++ ^= *src++;
468 g_free(sha1);
469 g_free(newseed);
470 g_free(secret2);
472 #ifdef __SIPE_TLS_CRYPTO_DEBUG
473 debug_secrets(state, "sipe_tls_prf: PRF() ",
474 md5, output_length);
475 #endif
477 return(md5);
480 #endif /* !_SIPE_COMPILING_ANALYZER */
483 * TLS data parsers
485 * Low-level data conversion routines
487 * - host alignment agnostic, i.e. can fetch a word from uneven address
488 * - TLS -> host endianess conversion
489 * - no length check, caller has to do it
490 * - don't modify state
492 static guint lowlevel_integer_to_host(const guchar *bytes,
493 gsize length)
495 guint sum = 0;
496 while (length--) sum = (sum << 8) + *bytes++;
497 return(sum);
501 * Generic data type parser routines
503 static gboolean msg_remainder_check(struct tls_internal_state *state,
504 const gchar *label,
505 gsize length)
507 if (length > state->msg_remainder) {
508 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT,
509 label, length, state->msg_remainder);
510 return(FALSE);
512 return(TRUE);
515 static gboolean parse_integer_quiet(struct tls_internal_state *state,
516 const gchar *label,
517 gsize length,
518 guint *result)
520 if (!msg_remainder_check(state, label, length)) return(FALSE);
521 *result = lowlevel_integer_to_host(state->msg_current, length);
522 state->msg_current += length;
523 state->msg_remainder -= length;
524 return(TRUE);
527 static gboolean parse_integer(struct tls_internal_state *state,
528 const struct layout_descriptor *desc)
530 guint value;
531 if (!parse_integer_quiet(state, desc->label, desc->max, &value))
532 return(FALSE);
533 debug_printf(state, "%s/INTEGER%" G_GSIZE_FORMAT " = %d\n",
534 desc->label, desc->max, value);
535 if (state->data) {
536 struct tls_parsed_integer *save = g_new0(struct tls_parsed_integer, 1);
537 save->value = value;
538 g_hash_table_insert(state->data, (gpointer) desc->label, save);
540 return(TRUE);
543 static gboolean parse_array(struct tls_internal_state *state,
544 const struct layout_descriptor *desc)
546 if (!msg_remainder_check(state, desc->label, desc->max))
547 return(FALSE);
548 debug_printf(state, "%s/ARRAY[%" G_GSIZE_FORMAT "]\n",
549 desc->label, desc->max);
550 #ifdef _SIPE_COMPILING_ANALYZER
551 if (desc->max)
552 debug_hex(state, desc->max);
553 #endif
554 if (state->data) {
555 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
556 desc->max);
557 save->length = desc->max;
558 memcpy((guchar *)save->data, state->msg_current, desc->max);
559 g_hash_table_insert(state->data, (gpointer) desc->label, save);
562 state->msg_current += desc->max;
563 state->msg_remainder -= desc->max;
564 return(TRUE);
567 static gboolean parse_vector(struct tls_internal_state *state,
568 const struct layout_descriptor *desc)
570 guint length;
571 if (!parse_integer_quiet(state, desc->label,
572 (desc->max > TLS_VECTOR_MAX16) ? 3 :
573 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1,
574 &length))
575 return(FALSE);
576 if (length < desc->min) {
577 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT,
578 desc->label, length, desc->min);
579 return(FALSE);
581 debug_printf(state, "%s/VECTOR<%d>\n", desc->label, length);
582 #ifdef _SIPE_COMPILING_ANALYZER
583 if (length)
584 debug_hex(state, length);
585 #endif
586 if (state->data) {
587 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
588 length);
589 save->length = length;
590 memcpy((guchar *)save->data, state->msg_current, length);
591 g_hash_table_insert(state->data, (gpointer) desc->label, save);
593 state->msg_current += length;
594 state->msg_remainder -= length;
595 return(TRUE);
599 * Specific data type parser routines
602 /* TBD... */
605 * TLS data compilers
607 * Low-level data conversion routines
609 * - host alignment agnostic, i.e. can fetch a word from uneven address
610 * - host -> TLS host endianess conversion
611 * - don't modify state
613 static void lowlevel_integer_to_tls(guchar *bytes,
614 gsize length,
615 guint value)
617 while (length--) {
618 bytes[length] = value & 0xFF;
619 value >>= 8;
624 * Generic data type compiler routines
626 static void compile_integer(struct tls_internal_state *state,
627 const struct layout_descriptor *desc,
628 const struct tls_compile_integer *data)
630 lowlevel_integer_to_tls(state->msg_current, desc->max, data->value);
631 state->msg_current += desc->max;
634 static void compile_array(struct tls_internal_state *state,
635 const struct layout_descriptor *desc,
636 const struct tls_compile_integer *data)
638 const struct tls_compile_array *array = (struct tls_compile_array *) data;
639 memcpy(state->msg_current, array->placeholder, desc->max);
640 state->msg_current += desc->max;
643 static void compile_vector(struct tls_internal_state *state,
644 const struct layout_descriptor *desc,
645 const struct tls_compile_integer *data)
647 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
648 gsize length = vector->elements;
649 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
650 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
652 lowlevel_integer_to_tls(state->msg_current, length_field, length);
653 state->msg_current += length_field;
654 memcpy(state->msg_current, vector->placeholder, length);
655 state->msg_current += length;
658 static void compile_vector_int2(struct tls_internal_state *state,
659 const struct layout_descriptor *desc,
660 const struct tls_compile_integer *data)
662 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
663 gsize elements = vector->elements;
664 gsize length = elements * sizeof(guint16);
665 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
666 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
667 const guint *p = vector->placeholder;
669 lowlevel_integer_to_tls(state->msg_current, length_field, length);
670 state->msg_current += length_field;
671 while (elements--) {
672 lowlevel_integer_to_tls(state->msg_current, sizeof(guint16), *p++);
673 state->msg_current += sizeof(guint16);
678 * Specific data type compiler routines
681 /* TBD... */
684 * TLS handshake message layout descriptors
686 struct ClientHello_host {
687 struct tls_compile_integer protocol_version;
688 struct tls_compile_random random;
689 struct tls_compile_sessionid sessionid;
690 struct tls_compile_cipher cipher;
691 struct tls_compile_compression compression;
693 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
695 static const struct layout_descriptor ClientHello_l[] = {
696 { "Client Protocol Version", parse_integer, compile_integer, 0, 2, CLIENTHELLO_OFFSET(protocol_version) },
697 { "Random", parse_array, compile_array, 0, TLS_ARRAY_RANDOM_LENGTH, CLIENTHELLO_OFFSET(random) },
698 { "SessionID", parse_vector, compile_vector, 0, 32, CLIENTHELLO_OFFSET(sessionid) },
699 { "CipherSuite", parse_vector, compile_vector_int2, 2, TLS_VECTOR_MAX16, CLIENTHELLO_OFFSET(cipher)},
700 { "CompressionMethod", parse_vector, compile_vector, 1, TLS_VECTOR_MAX8, CLIENTHELLO_OFFSET(compression) },
701 TLS_LAYOUT_DESCRIPTOR_END
703 static const struct msg_descriptor ClientHello_m = {
704 NULL, "Client Hello", ClientHello_l, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
707 static const struct layout_descriptor ServerHello_l[] = {
708 { "Server Protocol Version", parse_integer, NULL, 0, 2, 0 },
709 { "Random", parse_array, NULL, 0, TLS_ARRAY_RANDOM_LENGTH, 0 },
710 { "SessionID", parse_vector, NULL, 0, 32, 0 },
711 { "CipherSuite", parse_integer, NULL, 0, 2, 0 },
712 { "CompressionMethod", parse_integer, NULL, 0, 1, 0 },
713 TLS_LAYOUT_DESCRIPTOR_END
715 static const struct msg_descriptor ServerHello_m = {
716 &ClientHello_m, "Server Hello", ServerHello_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO
719 struct Certificate_host {
720 struct tls_compile_vector certificate;
722 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
724 static const struct layout_descriptor Certificate_l[] = {
725 { "Certificate", parse_vector, compile_vector, 0, TLS_VECTOR_MAX24, CERTIFICATE_OFFSET(certificate) },
726 TLS_LAYOUT_DESCRIPTOR_END
728 static const struct msg_descriptor Certificate_m = {
729 &ServerHello_m, "Certificate", Certificate_l, TLS_HANDSHAKE_TYPE_CERTIFICATE
732 static const struct layout_descriptor CertificateRequest_l[] = {
733 { "CertificateType", parse_vector, NULL, 1, TLS_VECTOR_MAX8, 0 },
734 { "DistinguishedName", parse_vector, NULL, 0, TLS_VECTOR_MAX16, 0 },
735 TLS_LAYOUT_DESCRIPTOR_END
737 static const struct msg_descriptor CertificateRequest_m = {
738 &Certificate_m, "Certificate Request", CertificateRequest_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
741 static const struct layout_descriptor ServerHelloDone_l[] = {
742 TLS_LAYOUT_DESCRIPTOR_END
744 static const struct msg_descriptor ServerHelloDone_m = {
745 &CertificateRequest_m, "Server Hello Done", ServerHelloDone_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
748 struct ClientKeyExchange_host {
749 struct tls_compile_vector secret;
751 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
753 static const struct layout_descriptor ClientKeyExchange_l[] = {
754 { "Exchange Keys", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CLIENTKEYEXCHANGE_OFFSET(secret) },
755 TLS_LAYOUT_DESCRIPTOR_END
757 static const struct msg_descriptor ClientKeyExchange_m = {
758 &ServerHelloDone_m, "Client Key Exchange", ClientKeyExchange_l, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
761 struct CertificateVerify_host {
762 struct tls_compile_vector signature;
764 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
766 static const struct layout_descriptor CertificateVerify_l[] = {
767 { "Signature", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CERTIFICATEVERIFY_OFFSET(signature) },
768 TLS_LAYOUT_DESCRIPTOR_END
770 static const struct msg_descriptor CertificateVerify_m = {
771 &ClientKeyExchange_m, "Certificate Verify", CertificateVerify_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
774 struct Finished_host {
775 struct tls_compile_verify verify;
777 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
779 static const struct layout_descriptor Finished_l[] = {
780 { "Verify Data", parse_array, compile_array, 0, TLS_ARRAY_VERIFY_LENGTH, FINISHED_OFFSET(verify) },
781 TLS_LAYOUT_DESCRIPTOR_END
783 static const struct msg_descriptor Finished_m = {
784 &CertificateVerify_m, "Finished", Finished_l, TLS_HANDSHAKE_TYPE_FINISHED
787 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
790 * TLS message parsers
792 static gboolean handshake_parse(struct tls_internal_state *state)
794 const guchar *bytes = state->msg_current;
795 gsize length = state->msg_remainder;
796 gboolean success = FALSE;
798 while (length > 0) {
799 const struct msg_descriptor *desc;
800 gsize msg_length;
801 guint msg_type;
803 /* header check */
804 if (length < TLS_HANDSHAKE_HEADER_LENGTH) {
805 debug_print(state, "CORRUPTED HANDSHAKE HEADER");
806 break;
809 /* msg length check */
810 msg_length = lowlevel_integer_to_host(bytes + TLS_HANDSHAKE_OFFSET_LENGTH,
812 if (msg_length > length) {
813 debug_print(state, "HANDSHAKE MESSAGE TOO LONG");
814 break;
817 /* msg type */
818 msg_type = bytes[TLS_HANDSHAKE_OFFSET_TYPE];
819 for (desc = HANDSHAKE_MSG_DESCRIPTORS;
820 desc;
821 desc = desc->next)
822 if (msg_type == desc->type)
823 break;
825 debug_printf(state, "TLS handshake (%" G_GSIZE_FORMAT " bytes) (%d)",
826 msg_length, msg_type);
828 state->msg_current = (guchar *) bytes + TLS_HANDSHAKE_HEADER_LENGTH;
829 state->msg_remainder = msg_length;
831 if (desc && desc->layouts) {
832 const struct layout_descriptor *ldesc = desc->layouts;
834 debug_printf(state, "%s\n", desc->description);
835 while (TLS_LAYOUT_IS_VALID(ldesc)) {
836 success = ldesc->parser(state, ldesc);
837 if (!success)
838 break;
839 ldesc++;
841 if (!success)
842 break;
843 } else {
844 debug_print(state, "ignored\n");
845 debug_hex(state, 0);
848 /* next message */
849 bytes += TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
850 length -= TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
851 if (length > 0) {
852 debug_print(state, "------\n");
853 } else {
854 success = TRUE;
858 return(success);
861 static void free_parse_data(struct tls_internal_state *state)
863 if (state->data) {
864 g_hash_table_destroy(state->data);
865 state->data = NULL;
869 static gboolean tls_record_parse(struct tls_internal_state *state,
870 gboolean incoming)
872 const guchar *bytes = incoming ? state->common.in_buffer : state->common.out_buffer;
873 gsize length = incoming ? state->common.in_length : state->common.out_length;
874 guint version;
875 const gchar *version_str;
876 gsize record_length;
877 gboolean success = TRUE;
879 /* reject empty incoming messages */
880 if (incoming && (length == 0)) {
881 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: empty TLS message received");
882 return(FALSE);
885 #ifndef _SIPE_COMPILING_ANALYZER
886 debug_printf(state, "TLS MESSAGE %s\n", incoming ? "INCOMING" : "OUTGOING");
887 #endif
889 /* Collect parser data for incoming messages */
890 if (incoming)
891 state->data = g_hash_table_new_full(g_str_hash, g_str_equal,
892 NULL, g_free);
894 while (success && (length > 0)) {
896 /* truncated header check */
897 if (length < TLS_RECORD_HEADER_LENGTH) {
898 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT " bytes)",
899 length);
900 success = FALSE;
901 break;
904 /* protocol version check */
905 version = lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_VERSION, 2);
906 if (version < TLS_PROTOCOL_VERSION_1_0) {
907 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
908 success = FALSE;
909 break;
911 switch (version) {
912 case TLS_PROTOCOL_VERSION_1_0:
913 version_str = "1.0 (RFC2246)";
914 break;
915 case TLS_PROTOCOL_VERSION_1_1:
916 version_str = "1.1 (RFC4346)";
917 break;
918 case TLS_PROTOCOL_VERSION_1_2:
919 version_str = "1.2 (RFC5246)";
920 break;
921 default:
922 version_str = "<future protocol version>";
923 break;
926 /* record length check */
927 record_length = TLS_RECORD_HEADER_LENGTH +
928 lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_LENGTH, 2);
929 if (record_length > length) {
930 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
931 success = FALSE;
932 break;
935 /* TLS record header OK */
936 debug_printf(state, "TLS %s record (%" G_GSIZE_FORMAT " bytes)\n",
937 version_str, record_length);
938 state->msg_current = (guchar *) bytes + TLS_RECORD_HEADER_LENGTH;
939 state->msg_remainder = record_length - TLS_RECORD_HEADER_LENGTH;
941 /* Analyzer only needs the debugging functions */
942 #ifndef _SIPE_COMPILING_ANALYZER
943 /* Add incoming message contents to digest contexts */
944 if (incoming) {
945 sipe_digest_md5_update(state->md5_context,
946 state->msg_current,
947 state->msg_remainder);
948 sipe_digest_sha1_update(state->sha1_context,
949 state->msg_current,
950 state->msg_remainder);
952 #endif /* !_SIPE_COMPILING_ANALYZER */
954 switch (bytes[TLS_RECORD_OFFSET_TYPE]) {
955 case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:
956 debug_print(state, "Change Cipher Spec\n");
957 if (incoming) state->encrypted = TRUE;
958 break;
960 case TLS_RECORD_TYPE_HANDSHAKE:
961 if (incoming && state->encrypted) {
962 debug_print(state, "Encrypted handshake message\n");
963 debug_hex(state, 0);
964 } else {
965 success = handshake_parse(state);
967 break;
969 default:
970 debug_print(state, "Unsupported TLS message\n");
971 debug_hex(state, 0);
972 break;
975 /* next fragment */
976 bytes += record_length;
977 length -= record_length;
980 if (!success)
981 free_parse_data(state);
983 if (state->debug) {
984 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
985 g_string_truncate(state->debug, 0);
988 return(success);
991 /* Analyzer only needs the debugging functions */
992 #ifndef _SIPE_COMPILING_ANALYZER
995 * TLS message compiler
997 static void compile_tls_record(struct tls_internal_state *state,
998 ...)
1000 gsize total_size = 0;
1001 guchar *current;
1002 va_list ap;
1004 /* calculate message size */
1005 va_start(ap, state);
1006 while (1) {
1007 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1008 if (!msg) break;
1009 total_size += msg->size;
1011 va_end(ap);
1013 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT,
1014 total_size);
1016 state->common.out_buffer = current = g_malloc(total_size + TLS_RECORD_HEADER_LENGTH);
1017 state->common.out_length = total_size + TLS_RECORD_HEADER_LENGTH;
1019 /* add TLS record header */
1020 current[TLS_RECORD_OFFSET_TYPE] = TLS_RECORD_TYPE_HANDSHAKE;
1021 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_VERSION, 2,
1022 TLS_PROTOCOL_VERSION_1_0);
1023 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_LENGTH, 2,
1024 total_size);
1025 current += TLS_RECORD_HEADER_LENGTH;
1027 /* copy messages */
1028 va_start(ap, state);
1029 while (1) {
1030 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1031 if (!msg) break;
1033 memcpy(current, msg->data, msg->size);
1034 current += msg->size;
1036 va_end(ap);
1039 static void compile_encrypted_tls_record(struct tls_internal_state *state,
1040 const struct tls_compiled_message *msg)
1042 guchar *plaintext;
1043 gsize plaintext_length;
1044 guchar *mac;
1045 gsize mac_length;
1046 guchar *message;
1047 guchar *encrypted;
1048 gsize encrypted_length;
1050 /* Create plaintext TLS record */
1051 compile_tls_record(state, msg, NULL);
1052 plaintext = state->common.out_buffer;
1053 plaintext_length = state->common.out_length;
1054 if (plaintext_length == 0) /* make Coverity happy */
1055 return;
1057 /* Prepare encryption buffer */
1058 encrypted_length = plaintext_length + state->mac_length;
1059 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT,
1060 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1061 message = g_malloc(encrypted_length);
1062 memcpy(message, plaintext, plaintext_length);
1063 lowlevel_integer_to_tls(message + TLS_RECORD_OFFSET_LENGTH, 2,
1064 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1067 * Calculate MAC
1069 * HMAC_hash(client_write_mac_secret,
1070 * sequence_number + type + version + length + fragment)
1071 * \--- == original TLS record ---/
1073 mac_length = sizeof(guint64) + plaintext_length;
1074 mac = g_malloc(mac_length);
1075 lowlevel_integer_to_tls(mac,
1076 sizeof(guint64),
1077 state->sequence_number++);
1078 memcpy(mac + sizeof(guint64), plaintext, plaintext_length);
1079 g_free(plaintext);
1080 state->mac_func(state->client_write_mac_secret,
1081 state->mac_length,
1082 mac,
1083 mac_length,
1084 message + plaintext_length);
1085 g_free(mac);
1087 /* Encrypt message + MAC */
1088 encrypted = g_malloc(encrypted_length);
1089 memcpy(encrypted, message, TLS_RECORD_HEADER_LENGTH);
1090 sipe_crypt_tls_stream(state->cipher_context,
1091 message + TLS_RECORD_HEADER_LENGTH,
1092 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1093 encrypted + TLS_RECORD_HEADER_LENGTH);
1094 g_free(message);
1096 /* swap buffers */
1097 state->common.out_buffer = encrypted;
1098 state->common.out_length = encrypted_length;
1101 static struct tls_compiled_message *compile_handshake_msg(struct tls_internal_state *state,
1102 const struct msg_descriptor *desc,
1103 gpointer data,
1104 gsize size)
1107 * Estimate the size of the compiled message
1109 * The data structures in the host format have zero or more padding
1110 * bytes added by the compiler to ensure correct element alignments.
1111 * So the sizeof() of the data structure is always equal or greater
1112 * than the space needed for the compiled data. By adding the space
1113 * required for the headers we arrive at a safe estimate
1115 * Therefore we don't need space checks in the compiler functions
1117 gsize total_size = sizeof(struct tls_compiled_message) +
1118 size + TLS_HANDSHAKE_HEADER_LENGTH;
1119 struct tls_compiled_message *msg = g_malloc(total_size);
1120 guchar *handshake = msg->data;
1121 const struct layout_descriptor *ldesc = desc->layouts;
1122 gsize length;
1124 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT,
1125 total_size);
1127 /* add TLS handshake header */
1128 handshake[TLS_HANDSHAKE_OFFSET_TYPE] = desc->type;
1129 state->msg_current = handshake + TLS_HANDSHAKE_HEADER_LENGTH;
1131 while (TLS_LAYOUT_IS_VALID(ldesc)) {
1133 * Avoid "cast increases required alignment" errors
1135 * (void *) tells the compiler that we know what we're
1136 * doing, i.e. we know that the calculated address
1137 * points to correctly aligned data.
1139 ldesc->compiler(state, ldesc,
1140 (void *) ((guchar *) data + ldesc->offset));
1141 ldesc++;
1144 length = state->msg_current - handshake - TLS_HANDSHAKE_HEADER_LENGTH;
1145 lowlevel_integer_to_tls(handshake + TLS_HANDSHAKE_OFFSET_LENGTH,
1146 3, length);
1147 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT,
1148 desc->type, desc->description, length);
1150 msg->size = length + TLS_HANDSHAKE_HEADER_LENGTH;
1152 /* update digest contexts */
1153 sipe_digest_md5_update(state->md5_context, handshake, msg->size);
1154 sipe_digest_sha1_update(state->sha1_context, handshake, msg->size);
1156 return(msg);
1160 * Specific TLS data verficiation & message compilers
1162 static struct tls_compiled_message *tls_client_certificate(struct tls_internal_state *state)
1164 struct Certificate_host *certificate;
1165 gsize certificate_length = sipe_cert_crypto_raw_length(state->certificate);
1166 struct tls_compiled_message *msg;
1168 /* setup our response */
1169 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1170 certificate = g_malloc0(sizeof(struct Certificate_host) + 3 +
1171 certificate_length);
1172 certificate->certificate.elements = certificate_length + 3;
1173 lowlevel_integer_to_tls((guchar *) certificate->certificate.placeholder, 3,
1174 certificate_length);
1175 memcpy((guchar *) certificate->certificate.placeholder + 3,
1176 sipe_cert_crypto_raw(state->certificate),
1177 certificate_length);
1179 msg = compile_handshake_msg(state, &Certificate_m, certificate,
1180 sizeof(struct Certificate_host) + certificate_length + 3);
1181 g_free(certificate);
1183 return(msg);
1186 static gboolean check_cipher_suite(struct tls_internal_state *state)
1188 struct tls_parsed_integer *cipher_suite = g_hash_table_lookup(state->data,
1189 "CipherSuite");
1190 const gchar *label = NULL;
1192 if (!cipher_suite) {
1193 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1194 return(FALSE);
1197 switch (cipher_suite->value) {
1198 case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
1199 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1200 state->key_length = 40 / 8;
1201 state->mac_func = sipe_digest_hmac_md5;
1202 label = "MD5";
1203 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1204 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1205 break;
1207 case TLS_RSA_WITH_RC4_128_MD5:
1208 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1209 state->key_length = 128 / 8;
1210 state->mac_func = sipe_digest_hmac_md5;
1211 label = "MD5";
1212 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1213 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1214 break;
1216 case TLS_RSA_WITH_RC4_128_SHA:
1217 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1218 state->key_length = 128 / 8;
1219 state->mac_func = sipe_digest_hmac_sha1;
1220 label = "SHA-1";
1221 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1222 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1223 break;
1225 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
1226 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1227 state->key_length = 256 / 8;
1228 state->mac_func = sipe_digest_hmac_sha1;
1229 label = "SHA-1";
1230 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1231 state->cipher_type = SIPE_CRYPT_STREAM_AES_CBC;
1232 break;
1234 default:
1235 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1236 cipher_suite->value);
1237 break;
1240 if (label)
1241 SIPE_DEBUG_INFO("check_cipher_suite: KEY(stream cipher RC4) %" G_GSIZE_FORMAT ", MAC(%s) %" G_GSIZE_FORMAT,
1242 state->key_length, label, state->mac_length);
1244 return(label != NULL);
1247 static void tls_calculate_secrets(struct tls_internal_state *state)
1249 gsize length = 2 * (state->mac_length + state->key_length);
1250 guchar *random;
1252 /* Generate pre-master secret */
1253 sipe_tls_fill_random(&state->pre_master_secret,
1254 TLS_ARRAY_MASTER_SECRET_LENGTH * 8); /* bits */
1255 lowlevel_integer_to_tls(state->pre_master_secret.buffer, 2,
1256 TLS_PROTOCOL_VERSION_1_0);
1257 debug_secrets(state, "tls_calculate_secrets: pre-master secret",
1258 state->pre_master_secret.buffer,
1259 state->pre_master_secret.length);
1262 * Calculate master secret
1264 * master_secret = PRF(pre_master_secret,
1265 * "master secret",
1266 * ClientHello.random + ServerHello.random)
1268 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1269 memcpy(random,
1270 state->client_random.buffer,
1271 TLS_ARRAY_RANDOM_LENGTH);
1272 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1273 state->server_random.buffer,
1274 TLS_ARRAY_RANDOM_LENGTH);
1275 state->master_secret = sipe_tls_prf(state,
1276 state->pre_master_secret.buffer,
1277 state->pre_master_secret.length,
1278 (guchar *) "master secret",
1280 random,
1281 TLS_ARRAY_RANDOM_LENGTH * 2,
1282 TLS_ARRAY_MASTER_SECRET_LENGTH);
1283 debug_secrets(state, "tls_calculate_secrets: master secret ",
1284 state->master_secret,
1285 TLS_ARRAY_MASTER_SECRET_LENGTH);
1288 * Calculate session key material
1290 * key_block = PRF(master_secret,
1291 * "key expansion",
1292 * ServerHello.random + ClientHello.random)
1294 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT,
1295 length);
1296 memcpy(random,
1297 state->server_random.buffer,
1298 TLS_ARRAY_RANDOM_LENGTH);
1299 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1300 state->client_random.buffer,
1301 TLS_ARRAY_RANDOM_LENGTH);
1302 state->key_block = sipe_tls_prf(state,
1303 state->master_secret,
1304 TLS_ARRAY_MASTER_SECRET_LENGTH,
1305 (guchar *) "key expansion",
1307 random,
1308 TLS_ARRAY_RANDOM_LENGTH * 2,
1309 length);
1310 g_free(random);
1311 debug_secrets(state, "tls_calculate_secrets: key block ",
1312 state->key_block, length);
1314 /* partition key block */
1315 state->client_write_mac_secret = state->key_block;
1316 state->server_write_mac_secret = state->key_block + state->mac_length;
1317 state->client_write_secret = state->key_block + 2 * state->mac_length;
1318 state->server_write_secret = state->key_block + 2 * state->mac_length + state->key_length;
1320 /* initialize cipher context */
1321 state->cipher_context = sipe_crypt_tls_start(state->cipher_type,
1322 state->client_write_secret,
1323 state->key_length);
1326 #if 0 /* NOT NEEDED? */
1327 /* signing */
1328 static guchar *tls_pkcs1_private_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1329 const guchar *data,
1330 gsize data_length,
1331 gsize buffer_length)
1333 gsize pad_length;
1334 guchar *pad_buffer;
1336 if (data_length + 3 > buffer_length) ||
1337 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */)
1338 return(NULL);
1340 pad_length = buffer_length - data_length - 3;
1341 pad_buffer = g_malloc(buffer_length);
1343 /* PKCS1 private key block padding */
1344 pad_buffer[0] = 0; /* +1 */
1345 pad_buffer[1] = 1; /* +2 */
1346 memset(pad_buffer + 2, 0xFF, pad_length);
1347 pad_buffer[2 + pad_length] = 0; /* +3 */
1348 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1350 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1351 debug_secrets(state, "tls_pkcs1_private_padding: ",
1352 pad_buffer, buffer_length);
1353 #endif
1355 return(pad_buffer);
1357 #endif
1359 /* encryption */
1360 static guchar *tls_pkcs1_public_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1361 const guchar *data,
1362 gsize data_length,
1363 gsize buffer_length)
1365 gsize pad_length, random_count;
1366 guchar *pad_buffer, *random;
1368 if ((data_length + 3 > buffer_length) ||
1369 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */
1370 return(NULL);
1372 pad_length = buffer_length - data_length - 3;
1373 pad_buffer = g_malloc(buffer_length);
1375 /* PKCS1 public key block padding */
1376 pad_buffer[0] = 0; /* +1 */
1377 pad_buffer[1] = 2; /* +2 */
1378 for (random = pad_buffer + 2, random_count = pad_length;
1379 random_count > 0;
1380 random_count--) {
1381 guchar byte;
1382 /* non-zero random byte */
1383 while ((byte = rand() & 0xFF) == 0);
1384 *random++ = byte;
1386 pad_buffer[2 + pad_length] = 0; /* +3 */
1387 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1389 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1390 debug_secrets(state, "tls_pkcs1_private_padding: ",
1391 pad_buffer, buffer_length);
1392 #endif
1394 return(pad_buffer);
1397 static struct tls_compiled_message *tls_client_key_exchange(struct tls_internal_state *state)
1399 struct tls_parsed_array *server_random;
1400 struct tls_parsed_array *server_certificate;
1401 struct ClientKeyExchange_host *exchange;
1402 gsize server_certificate_length;
1403 guchar *padded;
1404 struct tls_compiled_message *msg;
1406 /* check for required data fields */
1407 if (!check_cipher_suite(state))
1408 return(NULL);
1409 server_random = g_hash_table_lookup(state->data, "Random");
1410 if (!server_random) {
1411 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1412 return(NULL);
1414 server_certificate = g_hash_table_lookup(state->data, "Certificate");
1415 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1416 if (!server_certificate || (server_certificate->length < 3)) {
1417 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1418 return(FALSE);
1420 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT" bytes",
1421 server_certificate->length);
1422 /* first certificate is the server certificate */
1423 server_certificate_length = lowlevel_integer_to_host(server_certificate->data,
1425 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT" bytes",
1426 server_certificate_length);
1427 if ((server_certificate_length + 3) > server_certificate->length) {
1428 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1430 state->server_certificate = sipe_cert_crypto_import(server_certificate->data + 3,
1431 server_certificate_length);
1432 if (!state->server_certificate) {
1433 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1434 return(FALSE);
1436 /* server public key modulus length */
1437 server_certificate_length = sipe_cert_crypto_modulus_length(state->server_certificate);
1438 if (server_certificate_length < TLS_ARRAY_MASTER_SECRET_LENGTH) {
1439 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT ")",
1440 server_certificate_length);
1441 return(FALSE);
1443 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT,
1444 server_certificate_length);
1446 /* found all the required fields */
1447 state->server_random.length = server_random->length;
1448 state->server_random.buffer = g_memdup(server_random->data,
1449 server_random->length);
1450 tls_calculate_secrets(state);
1452 /* ClientKeyExchange */
1453 padded = tls_pkcs1_public_padding(state,
1454 state->pre_master_secret.buffer,
1455 state->pre_master_secret.length,
1456 server_certificate_length);
1457 if (!padded) {
1458 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: padding of pre-master secret failed");
1459 return(NULL);
1461 exchange = g_malloc0(sizeof(struct ClientKeyExchange_host) +
1462 server_certificate_length);
1463 exchange->secret.elements = server_certificate_length;
1464 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state->server_certificate),
1465 server_certificate_length,
1466 padded,
1467 (guchar *) exchange->secret.placeholder)) {
1468 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1469 g_free(exchange);
1470 g_free(padded);
1471 return(NULL);
1473 g_free(padded);
1475 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1476 debug_secrets(state, "tls_client_key_exchange: secret (encr) ",
1477 (guchar *) exchange->secret.placeholder,
1478 server_certificate_length);
1479 #endif
1481 msg = compile_handshake_msg(state, &ClientKeyExchange_m, exchange,
1482 sizeof(struct ClientKeyExchange_host) + server_certificate_length);
1483 g_free(exchange);
1485 return(msg);
1488 static struct tls_compiled_message *tls_certificate_verify(struct tls_internal_state *state)
1490 struct CertificateVerify_host *verify;
1491 struct tls_compiled_message *msg;
1492 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1493 guchar *signature;
1494 gsize length;
1496 /* calculate digests */
1497 sipe_digest_md5_end(state->md5_context, digests);
1498 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1500 /* sign digests */
1501 signature = sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state->certificate),
1502 digests,
1503 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1504 &length);
1505 g_free(digests);
1506 if (!signature) {
1507 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1508 return(NULL);
1511 /* CertificateVerify */
1512 verify = g_malloc0(sizeof(struct CertificateVerify_host) +
1513 length);
1514 verify->signature.elements = length;
1515 memcpy(verify->signature.placeholder, signature, length);
1516 g_free(signature);
1518 msg = compile_handshake_msg(state, &CertificateVerify_m, verify,
1519 sizeof(struct CertificateVerify_host) + length);
1520 g_free(verify);
1522 return(msg);
1525 static struct tls_compiled_message *tls_client_finished(struct tls_internal_state *state)
1527 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1528 guchar *verify;
1529 struct tls_compiled_message *cmsg;
1530 struct Finished_host msg;
1532 /* calculate digests */
1533 sipe_digest_md5_end(state->md5_context, digests);
1534 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1537 * verify_data = PRF(master_secret, "client finished",
1538 * MD5(handshake_messages) +
1539 * SHA-1(handshake_messages)) [0..11];
1541 verify = sipe_tls_prf(state,
1542 state->master_secret,
1543 TLS_ARRAY_MASTER_SECRET_LENGTH,
1544 (guchar *) "client finished",
1546 digests,
1547 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1548 TLS_ARRAY_VERIFY_LENGTH);
1549 g_free(digests);
1550 memcpy(msg.verify.verify, verify, TLS_ARRAY_VERIFY_LENGTH);
1551 g_free(verify);
1553 cmsg = compile_handshake_msg(state, &Finished_m, &msg, sizeof(msg));
1555 return(cmsg);
1559 * TLS state handling
1562 static gboolean tls_client_hello(struct tls_internal_state *state)
1564 guint32 now = time(NULL);
1565 guint32 now_N = GUINT32_TO_BE(now);
1566 struct ClientHello_host msg = {
1567 { TLS_PROTOCOL_VERSION_1_0 },
1568 { 0, { 0 } },
1569 { 0 /* empty SessionID */ },
1570 { 4,
1572 TLS_RSA_WITH_RC4_128_MD5,
1573 TLS_RSA_WITH_RC4_128_SHA,
1574 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1575 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1578 { 1,
1580 TLS_COMP_METHOD_NULL
1584 struct tls_compiled_message *cmsg;
1586 /* First 4 bytes of client_random is the current timestamp */
1587 sipe_tls_fill_random(&state->client_random,
1588 TLS_ARRAY_RANDOM_LENGTH * 8); /* -> bits */
1589 memcpy(state->client_random.buffer, &now_N, sizeof(now_N));
1590 memcpy(msg.random.random, state->client_random.buffer,
1591 TLS_ARRAY_RANDOM_LENGTH);
1593 cmsg = compile_handshake_msg(state, &ClientHello_m, &msg, sizeof(msg));
1594 compile_tls_record(state, cmsg, NULL);
1595 g_free(cmsg);
1597 if (sipe_backend_debug_enabled())
1598 state->debug = g_string_new("");
1600 state->state = TLS_HANDSHAKE_STATE_SERVER_HELLO;
1601 return(tls_record_parse(state, FALSE));
1604 static gboolean tls_server_hello(struct tls_internal_state *state)
1606 struct tls_compiled_message *certificate = NULL;
1607 struct tls_compiled_message *exchange = NULL;
1608 struct tls_compiled_message *verify = NULL;
1609 struct tls_compiled_message *finished = NULL;
1610 gboolean success = FALSE;
1612 if (!tls_record_parse(state, TRUE))
1613 return(FALSE);
1615 if (((certificate = tls_client_certificate(state)) != NULL) &&
1616 ((exchange = tls_client_key_exchange(state)) != NULL) &&
1617 ((verify = tls_certificate_verify(state)) != NULL) &&
1618 ((finished = tls_client_finished(state)) != NULL)) {
1620 /* Part 1 */
1621 compile_tls_record(state, certificate, exchange, verify, NULL);
1623 success = tls_record_parse(state, FALSE);
1624 if (success) {
1625 guchar *part1 = state->common.out_buffer;
1626 gsize part1_length = state->common.out_length;
1627 guchar *part3;
1628 gsize part3_length;
1629 guchar *merged;
1630 gsize length;
1631 /* ChangeCipherSpec is always the same */
1632 static const guchar part2[] = {
1633 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC,
1634 (TLS_PROTOCOL_VERSION_1_0 >> 8) & 0xFF,
1635 TLS_PROTOCOL_VERSION_1_0 & 0xFF,
1636 0x00, 0x01, /* length: 1 byte */
1637 0x01 /* change_cipher_spec(1) */
1640 state->common.out_buffer = NULL;
1642 /* Part 3 - this is the first encrypted record */
1643 compile_encrypted_tls_record(state, finished);
1644 part3 = state->common.out_buffer;
1645 part3_length = state->common.out_length;
1647 /* merge TLS records */
1648 length = part1_length + sizeof(part2) + part3_length;
1649 merged = g_malloc(length);
1651 memcpy(merged, part1, part1_length);
1652 memcpy(merged + part1_length, part2, sizeof(part2));
1653 memcpy(merged + part1_length + sizeof(part2), part3, part3_length);
1654 g_free(part3);
1655 g_free(part1);
1657 /* replace output buffer with merged message */
1658 state->common.out_buffer = merged;
1659 state->common.out_length = length;
1661 state->state = TLS_HANDSHAKE_STATE_FINISHED;
1665 g_free(finished);
1666 g_free(verify);
1667 g_free(exchange);
1668 g_free(certificate);
1669 free_parse_data(state);
1671 return(success);
1674 static gboolean tls_finished(struct tls_internal_state *state)
1676 guchar *random;
1678 if (!tls_record_parse(state, TRUE))
1679 return(FALSE);
1681 /* we don't need the data */
1682 free_parse_data(state);
1685 * Calculate session keys [MS-SIPAE section 3.2.5.1]
1687 * key_material = PRF (master_secret,
1688 * "client EAP encryption",
1689 * ClientHello.random + ServerHello.random)[128]
1690 * = 4 x 32 Bytes
1692 * client key = key_material[3rd 32 Bytes]
1693 * server key = key_material[4th 32 Bytes]
1695 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1696 memcpy(random,
1697 state->client_random.buffer,
1698 TLS_ARRAY_RANDOM_LENGTH);
1699 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1700 state->server_random.buffer,
1701 TLS_ARRAY_RANDOM_LENGTH);
1702 state->tls_dsk_key_block = sipe_tls_prf(state,
1703 state->master_secret,
1704 TLS_ARRAY_MASTER_SECRET_LENGTH,
1705 (guchar *) "client EAP encryption",
1707 random,
1708 TLS_ARRAY_RANDOM_LENGTH * 2,
1709 4 * 32);
1710 g_free(random);
1712 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1713 debug_secrets(state, "tls_finished: TLS-DSK key block ",
1714 state->tls_dsk_key_block, 4 * 32);
1715 #endif
1717 state->common.client_key = state->tls_dsk_key_block + 2 * 32;
1718 state->common.server_key = state->tls_dsk_key_block + 3 * 32;
1719 state->common.key_length = 32;
1721 debug_secrets(state, "tls_finished: TLS-DSK client key ",
1722 state->common.client_key,
1723 state->common.key_length);
1724 debug_secrets(state, "tls_finished: TLS-DSK server key ",
1725 state->common.server_key,
1726 state->common.key_length);
1728 state->common.out_buffer = NULL;
1729 state->common.out_length = 0;
1730 state->state = TLS_HANDSHAKE_STATE_COMPLETED;
1732 return(TRUE);
1736 * TLS public API
1739 struct sipe_tls_state *sipe_tls_start(gpointer certificate)
1741 struct tls_internal_state *state;
1743 if (!certificate)
1744 return(NULL);
1746 state = g_new0(struct tls_internal_state, 1);
1747 state->certificate = certificate;
1748 state->state = TLS_HANDSHAKE_STATE_START;
1749 state->md5_context = sipe_digest_md5_start();
1750 state->sha1_context = sipe_digest_sha1_start();
1751 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_NONE;
1753 return((struct sipe_tls_state *) state);
1756 gboolean sipe_tls_next(struct sipe_tls_state *state)
1758 /* Avoid "cast increases required alignment" errors */
1759 struct tls_internal_state *internal = (void *) state;
1760 gboolean success = FALSE;
1762 if (!state)
1763 return(FALSE);
1765 state->out_buffer = NULL;
1767 switch (internal->state) {
1768 case TLS_HANDSHAKE_STATE_START:
1769 success = tls_client_hello(internal);
1770 break;
1772 case TLS_HANDSHAKE_STATE_SERVER_HELLO:
1773 success = tls_server_hello(internal);
1774 break;
1776 case TLS_HANDSHAKE_STATE_FINISHED:
1777 success = tls_finished(internal);
1778 break;
1780 case TLS_HANDSHAKE_STATE_COMPLETED:
1781 case TLS_HANDSHAKE_STATE_FAILED:
1782 /* This should not happen */
1783 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1784 break;
1787 if (!success) {
1788 internal->state = TLS_HANDSHAKE_STATE_FAILED;
1791 return(success);
1794 guint sipe_tls_expires(struct sipe_tls_state *state)
1796 /* Avoid "cast increases required alignment" errors */
1797 struct tls_internal_state *internal = (void *) state;
1799 if (!state)
1800 return(0);
1802 return(sipe_cert_crypto_expires(internal->certificate));
1805 void sipe_tls_free(struct sipe_tls_state *state)
1807 if (state) {
1808 /* Avoid "cast increases required alignment" errors */
1809 struct tls_internal_state *internal = (void *) state;
1811 free_parse_data(internal);
1812 if (internal->debug)
1813 g_string_free(internal->debug, TRUE);
1814 g_free(internal->tls_dsk_key_block);
1815 g_free(internal->key_block);
1816 g_free(internal->master_secret);
1817 sipe_tls_free_random(&internal->pre_master_secret);
1818 sipe_tls_free_random(&internal->client_random);
1819 sipe_tls_free_random(&internal->server_random);
1820 if (internal->cipher_context)
1821 sipe_crypt_tls_destroy(internal->cipher_context);
1822 if (internal->md5_context)
1823 sipe_digest_md5_destroy(internal->md5_context);
1824 if (internal->sha1_context)
1825 sipe_digest_sha1_destroy(internal->sha1_context);
1826 sipe_cert_crypto_destroy(internal->server_certificate);
1827 g_free(state->out_buffer);
1828 g_free(state);
1832 #endif /* !_SIPE_COMPILING_ANALYZER */
1835 Local Variables:
1836 mode: c
1837 c-file-style: "bsd"
1838 indent-tabs-mode: t
1839 tab-width: 8
1840 End: