crypt: add TLS stream cipher type
[siplcs.git] / src / core / sipe-tls.c
blobf8e48393a1120f2a21492c1fa06306a93464600d
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_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038
111 #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014
112 #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A
114 /* CompressionMethods */
115 #define TLS_COMP_METHOD_NULL 0
117 /* various array lengths */
118 #define TLS_ARRAY_RANDOM_LENGTH 32
119 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
120 #define TLS_ARRAY_VERIFY_LENGTH 12
122 #define TLS_RECORD_HEADER_LENGTH 5
123 #define TLS_RECORD_OFFSET_TYPE 0
124 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
125 #define TLS_RECORD_TYPE_HANDSHAKE 22
126 #define TLS_RECORD_OFFSET_VERSION 1
127 #define TLS_RECORD_OFFSET_LENGTH 3
129 #define TLS_HANDSHAKE_HEADER_LENGTH 4
130 #define TLS_HANDSHAKE_OFFSET_TYPE 0
131 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
132 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
133 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
134 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
135 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
136 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
137 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
138 #define TLS_HANDSHAKE_TYPE_FINISHED 20
139 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
141 struct layout_descriptor;
142 typedef gboolean parse_func(struct tls_internal_state *state,
143 const struct layout_descriptor *desc);
145 /* Defines the strictest alignment requirement */
146 struct tls_compile_integer;
147 typedef void compile_func(struct tls_internal_state *state,
148 const struct layout_descriptor *desc,
149 const struct tls_compile_integer *data);
151 struct layout_descriptor {
152 const gchar *label;
153 parse_func *parser;
154 compile_func *compiler;
155 gsize min; /* 0 for fixed/array */
156 gsize max;
157 gsize offset;
160 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
161 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
163 struct msg_descriptor {
164 const struct msg_descriptor *next;
165 const gchar *description;
166 const struct layout_descriptor *layouts;
167 guint type;
170 /* parsed data */
171 struct tls_parsed_integer {
172 guint value;
175 struct tls_parsed_array {
176 gsize length; /* bytes */
177 const guchar data[0];
180 /* compile data */
181 struct tls_compile_integer {
182 gsize value;
185 struct tls_compile_array {
186 gsize elements; /* unused */
187 guchar placeholder[];
190 struct tls_compile_random {
191 gsize elements; /* unused */
192 guchar random[TLS_ARRAY_RANDOM_LENGTH];
195 struct tls_compile_verify {
196 gsize elements; /* unused */
197 guchar verify[TLS_ARRAY_VERIFY_LENGTH];
200 struct tls_compile_vector {
201 gsize elements; /* VECTOR */
202 guint placeholder[];
205 struct tls_compile_sessionid {
206 gsize elements; /* VECTOR */
209 struct tls_compile_cipher {
210 gsize elements; /* VECTOR */
211 guint suites[6];
214 struct tls_compile_compression {
215 gsize elements; /* VECTOR */
216 guint methods[1];
219 /* compiled message */
220 struct tls_compiled_message {
221 gsize size;
222 guchar data[];
226 * Random byte buffers
228 void sipe_tls_fill_random(struct sipe_tls_random *random,
229 guint bits)
231 guint bytes = ((bits + 15) / 16) * 2;
232 guint16 *p = g_malloc(bytes);
234 SIPE_DEBUG_INFO("sipe_tls_fill_random: %d bits -> %d bytes",
235 bits, bytes);
237 random->buffer = (guint8*) p;
238 random->length = bytes;
240 for (bytes /= 2; bytes; bytes--)
241 *p++ = rand() & 0xFFFF;
244 void sipe_tls_free_random(struct sipe_tls_random *random)
246 g_free(random->buffer);
250 * TLS message debugging
252 static void debug_hex(struct tls_internal_state *state,
253 gsize alternative_length)
255 GString *str = state->debug;
256 const guchar *bytes;
257 gsize length;
258 gint count;
260 if (!str) return;
262 bytes = state->msg_current;
263 length = alternative_length ? alternative_length : state->msg_remainder;
264 count = -1;
266 while (length-- > 0) {
267 if (++count == 0) {
268 /* do nothing */;
269 } else if ((count % 16) == 0) {
270 g_string_append(str, "\n");
271 } else if ((count % 8) == 0) {
272 g_string_append(str, " ");
274 g_string_append_printf(str, " %02X", *bytes++);
276 g_string_append(str, "\n");
279 #define debug_print(state, string) \
280 if (state->debug) g_string_append(state->debug, string)
281 #define debug_printf(state, format, ...) \
282 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
284 /* Analyzer only needs the debugging functions */
285 #ifndef _SIPE_COMPILING_ANALYZER
287 static void debug_secrets(struct tls_internal_state *state,
288 const gchar *label,
289 const guchar *secret,
290 gsize secret_length)
292 if (state->debug && secret) {
293 g_string_append_printf(state->debug, "%s (%3" G_GSIZE_FORMAT ") = ",
294 label, secret_length);
295 while (secret_length--)
296 g_string_append_printf(state->debug, "%02X", *secret++);
297 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
298 g_string_truncate(state->debug, 0);
303 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
305 static guchar *sipe_tls_p_md5(const guchar *secret,
306 gsize secret_length,
307 const guchar *seed,
308 gsize seed_length,
309 gsize output_length)
311 guchar *output = NULL;
314 * output_length == 0 -> illegal
315 * output_length == 1..16 -> iterations = 1
316 * output_length == 17..32 -> iterations = 2
318 if (secret && seed && (output_length > 0)) {
319 guint iterations = (output_length + SIPE_DIGEST_HMAC_MD5_LENGTH - 1) / SIPE_DIGEST_HMAC_MD5_LENGTH;
320 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length);
321 guchar A[SIPE_DIGEST_HMAC_MD5_LENGTH];
322 guchar *p;
324 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
325 secret_length, seed_length);
326 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
327 output_length, iterations);
329 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
330 sipe_digest_hmac_md5(secret, secret_length,
331 seed, seed_length,
334 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
335 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_MD5_LENGTH);
337 while (iterations-- > 0) {
338 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
339 guchar P[SIPE_DIGEST_HMAC_MD5_LENGTH];
340 memcpy(concat, A, SIPE_DIGEST_HMAC_MD5_LENGTH);
341 memcpy(concat + SIPE_DIGEST_HMAC_MD5_LENGTH, seed, seed_length);
342 sipe_digest_hmac_md5(secret, secret_length,
343 concat, SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length,
345 memcpy(p, P, SIPE_DIGEST_HMAC_MD5_LENGTH);
346 p += SIPE_DIGEST_HMAC_MD5_LENGTH;
348 /* A(i+1) = HMAC_MD5(secret, A(i)) */
349 sipe_digest_hmac_md5(secret, secret_length,
350 A, SIPE_DIGEST_HMAC_MD5_LENGTH,
353 g_free(concat);
356 return(output);
359 guchar *sipe_tls_p_sha1(const guchar *secret,
360 gsize secret_length,
361 const guchar *seed,
362 gsize seed_length,
363 gsize output_length)
365 guchar *output = NULL;
368 * output_length == 0 -> illegal
369 * output_length == 1..20 -> iterations = 1
370 * output_length == 21..40 -> iterations = 2
372 if (secret && seed && (output_length > 0)) {
373 guint iterations = (output_length + SIPE_DIGEST_HMAC_SHA1_LENGTH - 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH;
374 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length);
375 guchar A[SIPE_DIGEST_HMAC_SHA1_LENGTH];
376 guchar *p;
378 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
379 secret_length, seed_length);
380 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
381 output_length, iterations);
383 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
384 sipe_digest_hmac_sha1(secret, secret_length,
385 seed, seed_length,
388 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
389 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_SHA1_LENGTH);
391 while (iterations-- > 0) {
392 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
393 guchar P[SIPE_DIGEST_HMAC_SHA1_LENGTH];
394 memcpy(concat, A, SIPE_DIGEST_HMAC_SHA1_LENGTH);
395 memcpy(concat + SIPE_DIGEST_HMAC_SHA1_LENGTH, seed, seed_length);
396 sipe_digest_hmac_sha1(secret, secret_length,
397 concat, SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length,
399 memcpy(p, P, SIPE_DIGEST_HMAC_SHA1_LENGTH);
400 p += SIPE_DIGEST_HMAC_SHA1_LENGTH;
402 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
403 sipe_digest_hmac_sha1(secret, secret_length,
404 A, SIPE_DIGEST_HMAC_SHA1_LENGTH,
407 g_free(concat);
410 return(output);
413 static guchar *sipe_tls_prf(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
414 const guchar *secret,
415 gsize secret_length,
416 const guchar *label,
417 gsize label_length,
418 const guchar *seed,
419 gsize seed_length,
420 gsize output_length)
422 gsize half = (secret_length + 1) / 2;
423 gsize newseed_length = label_length + seed_length;
424 /* secret: used as S1; secret2: last half of original secret (S2) */
425 guchar *secret2 = g_memdup(secret + secret_length - half, half);
426 guchar *newseed = g_malloc(newseed_length);
427 guchar *md5, *dest;
428 guchar *sha1, *src;
429 gsize count;
431 /* make Coverity happy - lengths could be 0 */
432 if (!secret2 || !newseed) {
433 g_free(secret2);
434 g_free(newseed);
435 return(NULL);
439 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
440 * P_SHA-1(S2, label + seed);
442 memcpy(newseed, label, label_length);
443 memcpy(newseed + label_length, seed, seed_length);
444 #undef __SIPE_TLS_CRYPTO_DEBUG
445 #ifdef __SIPE_TLS_CRYPTO_DEBUG
446 debug_secrets(state, "sipe_tls_prf: secret ",
447 secret, secret_length);
448 debug_secrets(state, "sipe_tls_prf: combined seed ",
449 newseed, newseed_length);
450 SIPE_DEBUG_INFO("total seed length %" G_GSIZE_FORMAT,
451 newseed_length);
452 debug_secrets(state, "sipe_tls_prf: S1 ",
453 secret, half);
454 debug_secrets(state, "sipe_tls_prf: S2 ",
455 secret2, half);
456 #endif
457 md5 = sipe_tls_p_md5(secret, half, newseed, newseed_length, output_length);
458 sha1 = sipe_tls_p_sha1(secret2, half, newseed, newseed_length, output_length);
459 #ifdef __SIPE_TLS_CRYPTO_DEBUG
460 debug_secrets(state, "sipe_tls_prf: P_md5() ",
461 md5, output_length);
462 debug_secrets(state, "sipe_tls_prf: P_sha1() ",
463 sha1, output_length);
464 #endif
465 for (dest = md5, src = sha1, count = output_length;
466 count > 0;
467 count--)
468 *dest++ ^= *src++;
470 g_free(sha1);
471 g_free(newseed);
472 g_free(secret2);
474 #ifdef __SIPE_TLS_CRYPTO_DEBUG
475 debug_secrets(state, "sipe_tls_prf: PRF() ",
476 md5, output_length);
477 #endif
479 return(md5);
482 #endif /* !_SIPE_COMPILING_ANALYZER */
485 * TLS data parsers
487 * Low-level data conversion routines
489 * - host alignment agnostic, i.e. can fetch a word from uneven address
490 * - TLS -> host endianess conversion
491 * - no length check, caller has to do it
492 * - don't modify state
494 static guint lowlevel_integer_to_host(const guchar *bytes,
495 gsize length)
497 guint sum = 0;
498 while (length--) sum = (sum << 8) + *bytes++;
499 return(sum);
503 * Generic data type parser routines
505 static gboolean msg_remainder_check(struct tls_internal_state *state,
506 const gchar *label,
507 gsize length)
509 if (length > state->msg_remainder) {
510 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT,
511 label, length, state->msg_remainder);
512 return(FALSE);
514 return(TRUE);
517 static gboolean parse_integer_quiet(struct tls_internal_state *state,
518 const gchar *label,
519 gsize length,
520 guint *result)
522 if (!msg_remainder_check(state, label, length)) return(FALSE);
523 *result = lowlevel_integer_to_host(state->msg_current, length);
524 state->msg_current += length;
525 state->msg_remainder -= length;
526 return(TRUE);
529 static gboolean parse_integer(struct tls_internal_state *state,
530 const struct layout_descriptor *desc)
532 guint value;
533 if (!parse_integer_quiet(state, desc->label, desc->max, &value))
534 return(FALSE);
535 debug_printf(state, "%s/INTEGER%" G_GSIZE_FORMAT " = %d\n",
536 desc->label, desc->max, value);
537 if (state->data) {
538 struct tls_parsed_integer *save = g_new0(struct tls_parsed_integer, 1);
539 save->value = value;
540 g_hash_table_insert(state->data, (gpointer) desc->label, save);
542 return(TRUE);
545 static gboolean parse_array(struct tls_internal_state *state,
546 const struct layout_descriptor *desc)
548 if (!msg_remainder_check(state, desc->label, desc->max))
549 return(FALSE);
550 debug_printf(state, "%s/ARRAY[%" G_GSIZE_FORMAT "]\n",
551 desc->label, desc->max);
552 #ifdef _SIPE_COMPILING_ANALYZER
553 if (desc->max)
554 debug_hex(state, desc->max);
555 #endif
556 if (state->data) {
557 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
558 desc->max);
559 save->length = desc->max;
560 memcpy((guchar *)save->data, state->msg_current, desc->max);
561 g_hash_table_insert(state->data, (gpointer) desc->label, save);
564 state->msg_current += desc->max;
565 state->msg_remainder -= desc->max;
566 return(TRUE);
569 static gboolean parse_vector(struct tls_internal_state *state,
570 const struct layout_descriptor *desc)
572 guint length;
573 if (!parse_integer_quiet(state, desc->label,
574 (desc->max > TLS_VECTOR_MAX16) ? 3 :
575 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1,
576 &length))
577 return(FALSE);
578 if (length < desc->min) {
579 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT,
580 desc->label, length, desc->min);
581 return(FALSE);
583 debug_printf(state, "%s/VECTOR<%d>\n", desc->label, length);
584 #ifdef _SIPE_COMPILING_ANALYZER
585 if (length)
586 debug_hex(state, length);
587 #endif
588 if (state->data) {
589 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
590 length);
591 save->length = length;
592 memcpy((guchar *)save->data, state->msg_current, length);
593 g_hash_table_insert(state->data, (gpointer) desc->label, save);
595 state->msg_current += length;
596 state->msg_remainder -= length;
597 return(TRUE);
601 * Specific data type parser routines
604 /* TBD... */
607 * TLS data compilers
609 * Low-level data conversion routines
611 * - host alignment agnostic, i.e. can fetch a word from uneven address
612 * - host -> TLS host endianess conversion
613 * - don't modify state
615 static void lowlevel_integer_to_tls(guchar *bytes,
616 gsize length,
617 guint value)
619 while (length--) {
620 bytes[length] = value & 0xFF;
621 value >>= 8;
626 * Generic data type compiler routines
628 static void compile_integer(struct tls_internal_state *state,
629 const struct layout_descriptor *desc,
630 const struct tls_compile_integer *data)
632 lowlevel_integer_to_tls(state->msg_current, desc->max, data->value);
633 state->msg_current += desc->max;
636 static void compile_array(struct tls_internal_state *state,
637 const struct layout_descriptor *desc,
638 const struct tls_compile_integer *data)
640 const struct tls_compile_array *array = (struct tls_compile_array *) data;
641 memcpy(state->msg_current, array->placeholder, desc->max);
642 state->msg_current += desc->max;
645 static void compile_vector(struct tls_internal_state *state,
646 const struct layout_descriptor *desc,
647 const struct tls_compile_integer *data)
649 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
650 gsize length = vector->elements;
651 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
652 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
654 lowlevel_integer_to_tls(state->msg_current, length_field, length);
655 state->msg_current += length_field;
656 memcpy(state->msg_current, vector->placeholder, length);
657 state->msg_current += length;
660 static void compile_vector_int2(struct tls_internal_state *state,
661 const struct layout_descriptor *desc,
662 const struct tls_compile_integer *data)
664 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
665 gsize elements = vector->elements;
666 gsize length = elements * sizeof(guint16);
667 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
668 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
669 const guint *p = vector->placeholder;
671 lowlevel_integer_to_tls(state->msg_current, length_field, length);
672 state->msg_current += length_field;
673 while (elements--) {
674 lowlevel_integer_to_tls(state->msg_current, sizeof(guint16), *p++);
675 state->msg_current += sizeof(guint16);
680 * Specific data type compiler routines
683 /* TBD... */
686 * TLS handshake message layout descriptors
688 struct ClientHello_host {
689 struct tls_compile_integer protocol_version;
690 struct tls_compile_random random;
691 struct tls_compile_sessionid sessionid;
692 struct tls_compile_cipher cipher;
693 struct tls_compile_compression compression;
695 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
697 static const struct layout_descriptor ClientHello_l[] = {
698 { "Client Protocol Version", parse_integer, compile_integer, 0, 2, CLIENTHELLO_OFFSET(protocol_version) },
699 { "Random", parse_array, compile_array, 0, TLS_ARRAY_RANDOM_LENGTH, CLIENTHELLO_OFFSET(random) },
700 { "SessionID", parse_vector, compile_vector, 0, 32, CLIENTHELLO_OFFSET(sessionid) },
701 { "CipherSuite", parse_vector, compile_vector_int2, 2, TLS_VECTOR_MAX16, CLIENTHELLO_OFFSET(cipher)},
702 { "CompressionMethod", parse_vector, compile_vector, 1, TLS_VECTOR_MAX8, CLIENTHELLO_OFFSET(compression) },
703 TLS_LAYOUT_DESCRIPTOR_END
705 static const struct msg_descriptor ClientHello_m = {
706 NULL, "Client Hello", ClientHello_l, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
709 static const struct layout_descriptor ServerHello_l[] = {
710 { "Server Protocol Version", parse_integer, NULL, 0, 2, 0 },
711 { "Random", parse_array, NULL, 0, TLS_ARRAY_RANDOM_LENGTH, 0 },
712 { "SessionID", parse_vector, NULL, 0, 32, 0 },
713 { "CipherSuite", parse_integer, NULL, 0, 2, 0 },
714 { "CompressionMethod", parse_integer, NULL, 0, 1, 0 },
715 TLS_LAYOUT_DESCRIPTOR_END
717 static const struct msg_descriptor ServerHello_m = {
718 &ClientHello_m, "Server Hello", ServerHello_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO
721 struct Certificate_host {
722 struct tls_compile_vector certificate;
724 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
726 static const struct layout_descriptor Certificate_l[] = {
727 { "Certificate", parse_vector, compile_vector, 0, TLS_VECTOR_MAX24, CERTIFICATE_OFFSET(certificate) },
728 TLS_LAYOUT_DESCRIPTOR_END
730 static const struct msg_descriptor Certificate_m = {
731 &ServerHello_m, "Certificate", Certificate_l, TLS_HANDSHAKE_TYPE_CERTIFICATE
734 static const struct layout_descriptor CertificateRequest_l[] = {
735 { "CertificateType", parse_vector, NULL, 1, TLS_VECTOR_MAX8, 0 },
736 { "DistinguishedName", parse_vector, NULL, 0, TLS_VECTOR_MAX16, 0 },
737 TLS_LAYOUT_DESCRIPTOR_END
739 static const struct msg_descriptor CertificateRequest_m = {
740 &Certificate_m, "Certificate Request", CertificateRequest_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
743 static const struct layout_descriptor ServerHelloDone_l[] = {
744 TLS_LAYOUT_DESCRIPTOR_END
746 static const struct msg_descriptor ServerHelloDone_m = {
747 &CertificateRequest_m, "Server Hello Done", ServerHelloDone_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
750 struct ClientKeyExchange_host {
751 struct tls_compile_vector secret;
753 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
755 static const struct layout_descriptor ClientKeyExchange_l[] = {
756 { "Exchange Keys", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CLIENTKEYEXCHANGE_OFFSET(secret) },
757 TLS_LAYOUT_DESCRIPTOR_END
759 static const struct msg_descriptor ClientKeyExchange_m = {
760 &ServerHelloDone_m, "Client Key Exchange", ClientKeyExchange_l, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
763 struct CertificateVerify_host {
764 struct tls_compile_vector signature;
766 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
768 static const struct layout_descriptor CertificateVerify_l[] = {
769 { "Signature", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CERTIFICATEVERIFY_OFFSET(signature) },
770 TLS_LAYOUT_DESCRIPTOR_END
772 static const struct msg_descriptor CertificateVerify_m = {
773 &ClientKeyExchange_m, "Certificate Verify", CertificateVerify_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
776 struct Finished_host {
777 struct tls_compile_verify verify;
779 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
781 static const struct layout_descriptor Finished_l[] = {
782 { "Verify Data", parse_array, compile_array, 0, TLS_ARRAY_VERIFY_LENGTH, FINISHED_OFFSET(verify) },
783 TLS_LAYOUT_DESCRIPTOR_END
785 static const struct msg_descriptor Finished_m = {
786 &CertificateVerify_m, "Finished", Finished_l, TLS_HANDSHAKE_TYPE_FINISHED
789 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
792 * TLS message parsers
794 static gboolean handshake_parse(struct tls_internal_state *state)
796 const guchar *bytes = state->msg_current;
797 gsize length = state->msg_remainder;
798 gboolean success = FALSE;
800 while (length > 0) {
801 const struct msg_descriptor *desc;
802 gsize msg_length;
803 guint msg_type;
805 /* header check */
806 if (length < TLS_HANDSHAKE_HEADER_LENGTH) {
807 debug_print(state, "CORRUPTED HANDSHAKE HEADER");
808 break;
811 /* msg length check */
812 msg_length = lowlevel_integer_to_host(bytes + TLS_HANDSHAKE_OFFSET_LENGTH,
814 if (msg_length > length) {
815 debug_print(state, "HANDSHAKE MESSAGE TOO LONG");
816 break;
819 /* msg type */
820 msg_type = bytes[TLS_HANDSHAKE_OFFSET_TYPE];
821 for (desc = HANDSHAKE_MSG_DESCRIPTORS;
822 desc;
823 desc = desc->next)
824 if (msg_type == desc->type)
825 break;
827 debug_printf(state, "TLS handshake (%" G_GSIZE_FORMAT " bytes) (%d)",
828 msg_length, msg_type);
830 state->msg_current = (guchar *) bytes + TLS_HANDSHAKE_HEADER_LENGTH;
831 state->msg_remainder = msg_length;
833 if (desc && desc->layouts) {
834 const struct layout_descriptor *ldesc = desc->layouts;
836 debug_printf(state, "%s\n", desc->description);
837 while (TLS_LAYOUT_IS_VALID(ldesc)) {
838 success = ldesc->parser(state, ldesc);
839 if (!success)
840 break;
841 ldesc++;
843 if (!success)
844 break;
845 } else {
846 debug_print(state, "ignored\n");
847 debug_hex(state, 0);
850 /* next message */
851 bytes += TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
852 length -= TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
853 if (length > 0) {
854 debug_print(state, "------\n");
855 } else {
856 success = TRUE;
860 return(success);
863 static void free_parse_data(struct tls_internal_state *state)
865 if (state->data) {
866 g_hash_table_destroy(state->data);
867 state->data = NULL;
871 static gboolean tls_record_parse(struct tls_internal_state *state,
872 gboolean incoming)
874 const guchar *bytes = incoming ? state->common.in_buffer : state->common.out_buffer;
875 gsize length = incoming ? state->common.in_length : state->common.out_length;
876 guint version;
877 const gchar *version_str;
878 gsize record_length;
879 gboolean success = TRUE;
881 /* reject empty incoming messages */
882 if (incoming && (length == 0)) {
883 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: empty TLS message received");
884 return(FALSE);
887 #ifndef _SIPE_COMPILING_ANALYZER
888 debug_printf(state, "TLS MESSAGE %s\n", incoming ? "INCOMING" : "OUTGOING");
889 #endif
891 /* Collect parser data for incoming messages */
892 if (incoming)
893 state->data = g_hash_table_new_full(g_str_hash, g_str_equal,
894 NULL, g_free);
896 while (success && (length > 0)) {
898 /* truncated header check */
899 if (length < TLS_RECORD_HEADER_LENGTH) {
900 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT " bytes)",
901 length);
902 success = FALSE;
903 break;
906 /* protocol version check */
907 version = lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_VERSION, 2);
908 if (version < TLS_PROTOCOL_VERSION_1_0) {
909 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
910 success = FALSE;
911 break;
913 switch (version) {
914 case TLS_PROTOCOL_VERSION_1_0:
915 version_str = "1.0 (RFC2246)";
916 break;
917 case TLS_PROTOCOL_VERSION_1_1:
918 version_str = "1.1 (RFC4346)";
919 break;
920 case TLS_PROTOCOL_VERSION_1_2:
921 version_str = "1.2 (RFC5246)";
922 break;
923 default:
924 version_str = "<future protocol version>";
925 break;
928 /* record length check */
929 record_length = TLS_RECORD_HEADER_LENGTH +
930 lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_LENGTH, 2);
931 if (record_length > length) {
932 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
933 success = FALSE;
934 break;
937 /* TLS record header OK */
938 debug_printf(state, "TLS %s record (%" G_GSIZE_FORMAT " bytes)\n",
939 version_str, record_length);
940 state->msg_current = (guchar *) bytes + TLS_RECORD_HEADER_LENGTH;
941 state->msg_remainder = record_length - TLS_RECORD_HEADER_LENGTH;
943 /* Analyzer only needs the debugging functions */
944 #ifndef _SIPE_COMPILING_ANALYZER
945 /* Add incoming message contents to digest contexts */
946 if (incoming) {
947 sipe_digest_md5_update(state->md5_context,
948 state->msg_current,
949 state->msg_remainder);
950 sipe_digest_sha1_update(state->sha1_context,
951 state->msg_current,
952 state->msg_remainder);
954 #endif /* !_SIPE_COMPILING_ANALYZER */
956 switch (bytes[TLS_RECORD_OFFSET_TYPE]) {
957 case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:
958 debug_print(state, "Change Cipher Spec\n");
959 if (incoming) state->encrypted = TRUE;
960 break;
962 case TLS_RECORD_TYPE_HANDSHAKE:
963 if (incoming && state->encrypted) {
964 debug_print(state, "Encrypted handshake message\n");
965 debug_hex(state, 0);
966 } else {
967 success = handshake_parse(state);
969 break;
971 default:
972 debug_print(state, "Unsupported TLS message\n");
973 debug_hex(state, 0);
974 break;
977 /* next fragment */
978 bytes += record_length;
979 length -= record_length;
982 if (!success)
983 free_parse_data(state);
985 if (state->debug) {
986 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
987 g_string_truncate(state->debug, 0);
990 return(success);
993 /* Analyzer only needs the debugging functions */
994 #ifndef _SIPE_COMPILING_ANALYZER
997 * TLS message compiler
999 static void compile_tls_record(struct tls_internal_state *state,
1000 ...)
1002 gsize total_size = 0;
1003 guchar *current;
1004 va_list ap;
1006 /* calculate message size */
1007 va_start(ap, state);
1008 while (1) {
1009 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1010 if (!msg) break;
1011 total_size += msg->size;
1013 va_end(ap);
1015 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT,
1016 total_size);
1018 state->common.out_buffer = current = g_malloc(total_size + TLS_RECORD_HEADER_LENGTH);
1019 state->common.out_length = total_size + TLS_RECORD_HEADER_LENGTH;
1021 /* add TLS record header */
1022 current[TLS_RECORD_OFFSET_TYPE] = TLS_RECORD_TYPE_HANDSHAKE;
1023 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_VERSION, 2,
1024 TLS_PROTOCOL_VERSION_1_0);
1025 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_LENGTH, 2,
1026 total_size);
1027 current += TLS_RECORD_HEADER_LENGTH;
1029 /* copy messages */
1030 va_start(ap, state);
1031 while (1) {
1032 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1033 if (!msg) break;
1035 memcpy(current, msg->data, msg->size);
1036 current += msg->size;
1038 va_end(ap);
1041 static void compile_encrypted_tls_record(struct tls_internal_state *state,
1042 const struct tls_compiled_message *msg)
1044 guchar *plaintext;
1045 gsize plaintext_length;
1046 guchar *mac;
1047 gsize mac_length;
1048 guchar *message;
1049 guchar *encrypted;
1050 gsize encrypted_length;
1052 /* Create plaintext TLS record */
1053 compile_tls_record(state, msg, NULL);
1054 plaintext = state->common.out_buffer;
1055 plaintext_length = state->common.out_length;
1056 if (plaintext_length == 0) /* make Coverity happy */
1057 return;
1059 /* Prepare encryption buffer */
1060 encrypted_length = plaintext_length + state->mac_length;
1061 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT,
1062 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1063 message = g_malloc(encrypted_length);
1064 memcpy(message, plaintext, plaintext_length);
1065 lowlevel_integer_to_tls(message + TLS_RECORD_OFFSET_LENGTH, 2,
1066 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1069 * Calculate MAC
1071 * HMAC_hash(client_write_mac_secret,
1072 * sequence_number + type + version + length + fragment)
1073 * \--- == original TLS record ---/
1075 mac_length = sizeof(guint64) + plaintext_length;
1076 mac = g_malloc(mac_length);
1077 lowlevel_integer_to_tls(mac,
1078 sizeof(guint64),
1079 state->sequence_number++);
1080 memcpy(mac + sizeof(guint64), plaintext, plaintext_length);
1081 g_free(plaintext);
1082 state->mac_func(state->client_write_mac_secret,
1083 state->mac_length,
1084 mac,
1085 mac_length,
1086 message + plaintext_length);
1087 g_free(mac);
1089 /* Encrypt message + MAC */
1090 encrypted = g_malloc(encrypted_length);
1091 memcpy(encrypted, message, TLS_RECORD_HEADER_LENGTH);
1092 sipe_crypt_tls_stream(state->cipher_context,
1093 message + TLS_RECORD_HEADER_LENGTH,
1094 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1095 encrypted + TLS_RECORD_HEADER_LENGTH);
1096 g_free(message);
1098 /* swap buffers */
1099 state->common.out_buffer = encrypted;
1100 state->common.out_length = encrypted_length;
1103 static struct tls_compiled_message *compile_handshake_msg(struct tls_internal_state *state,
1104 const struct msg_descriptor *desc,
1105 gpointer data,
1106 gsize size)
1109 * Estimate the size of the compiled message
1111 * The data structures in the host format have zero or more padding
1112 * bytes added by the compiler to ensure correct element alignments.
1113 * So the sizeof() of the data structure is always equal or greater
1114 * than the space needed for the compiled data. By adding the space
1115 * required for the headers we arrive at a safe estimate
1117 * Therefore we don't need space checks in the compiler functions
1119 gsize total_size = sizeof(struct tls_compiled_message) +
1120 size + TLS_HANDSHAKE_HEADER_LENGTH;
1121 struct tls_compiled_message *msg = g_malloc(total_size);
1122 guchar *handshake = msg->data;
1123 const struct layout_descriptor *ldesc = desc->layouts;
1124 gsize length;
1126 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT,
1127 total_size);
1129 /* add TLS handshake header */
1130 handshake[TLS_HANDSHAKE_OFFSET_TYPE] = desc->type;
1131 state->msg_current = handshake + TLS_HANDSHAKE_HEADER_LENGTH;
1133 while (TLS_LAYOUT_IS_VALID(ldesc)) {
1135 * Avoid "cast increases required alignment" errors
1137 * (void *) tells the compiler that we know what we're
1138 * doing, i.e. we know that the calculated address
1139 * points to correctly aligned data.
1141 ldesc->compiler(state, ldesc,
1142 (void *) ((guchar *) data + ldesc->offset));
1143 ldesc++;
1146 length = state->msg_current - handshake - TLS_HANDSHAKE_HEADER_LENGTH;
1147 lowlevel_integer_to_tls(handshake + TLS_HANDSHAKE_OFFSET_LENGTH,
1148 3, length);
1149 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT,
1150 desc->type, desc->description, length);
1152 msg->size = length + TLS_HANDSHAKE_HEADER_LENGTH;
1154 /* update digest contexts */
1155 sipe_digest_md5_update(state->md5_context, handshake, msg->size);
1156 sipe_digest_sha1_update(state->sha1_context, handshake, msg->size);
1158 return(msg);
1162 * Specific TLS data verficiation & message compilers
1164 static struct tls_compiled_message *tls_client_certificate(struct tls_internal_state *state)
1166 struct Certificate_host *certificate;
1167 gsize certificate_length = sipe_cert_crypto_raw_length(state->certificate);
1168 struct tls_compiled_message *msg;
1170 /* setup our response */
1171 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1172 certificate = g_malloc0(sizeof(struct Certificate_host) + 3 +
1173 certificate_length);
1174 certificate->certificate.elements = certificate_length + 3;
1175 lowlevel_integer_to_tls((guchar *) certificate->certificate.placeholder, 3,
1176 certificate_length);
1177 memcpy((guchar *) certificate->certificate.placeholder + 3,
1178 sipe_cert_crypto_raw(state->certificate),
1179 certificate_length);
1181 msg = compile_handshake_msg(state, &Certificate_m, certificate,
1182 sizeof(struct Certificate_host) + certificate_length + 3);
1183 g_free(certificate);
1185 return(msg);
1188 static gboolean check_cipher_suite(struct tls_internal_state *state)
1190 struct tls_parsed_integer *cipher_suite = g_hash_table_lookup(state->data,
1191 "CipherSuite");
1192 const gchar *label = NULL;
1194 if (!cipher_suite) {
1195 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1196 return(FALSE);
1199 switch (cipher_suite->value) {
1200 case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
1201 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1202 state->key_length = 40 / 8;
1203 state->mac_func = sipe_digest_hmac_md5;
1204 label = "MD5";
1205 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1206 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1207 break;
1209 case TLS_RSA_WITH_RC4_128_MD5:
1210 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1211 state->key_length = 128 / 8;
1212 state->mac_func = sipe_digest_hmac_md5;
1213 label = "MD5";
1214 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1215 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1216 break;
1218 case TLS_RSA_WITH_RC4_128_SHA:
1219 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1220 state->key_length = 128 / 8;
1221 state->mac_func = sipe_digest_hmac_sha1;
1222 label = "SHA-1";
1223 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1224 state->cipher_type = SIPE_CRYPT_STREAM_RC4;
1225 break;
1227 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
1228 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
1229 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
1230 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1231 state->key_length = 256 / 8;
1232 state->mac_func = sipe_digest_hmac_sha1;
1233 label = "SHA-1";
1234 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1235 state->cipher_type = SIPE_CRYPT_STREAM_AES_CBC;
1236 break;
1238 default:
1239 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1240 cipher_suite->value);
1241 break;
1244 if (label)
1245 SIPE_DEBUG_INFO("check_cipher_suite: KEY(stream cipher RC4) %" G_GSIZE_FORMAT ", MAC(%s) %" G_GSIZE_FORMAT,
1246 state->key_length, label, state->mac_length);
1248 return(label != NULL);
1251 static void tls_calculate_secrets(struct tls_internal_state *state)
1253 gsize length = 2 * (state->mac_length + state->key_length);
1254 guchar *random;
1256 /* Generate pre-master secret */
1257 sipe_tls_fill_random(&state->pre_master_secret,
1258 TLS_ARRAY_MASTER_SECRET_LENGTH * 8); /* bits */
1259 lowlevel_integer_to_tls(state->pre_master_secret.buffer, 2,
1260 TLS_PROTOCOL_VERSION_1_0);
1261 debug_secrets(state, "tls_calculate_secrets: pre-master secret",
1262 state->pre_master_secret.buffer,
1263 state->pre_master_secret.length);
1266 * Calculate master secret
1268 * master_secret = PRF(pre_master_secret,
1269 * "master secret",
1270 * ClientHello.random + ServerHello.random)
1272 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1273 memcpy(random,
1274 state->client_random.buffer,
1275 TLS_ARRAY_RANDOM_LENGTH);
1276 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1277 state->server_random.buffer,
1278 TLS_ARRAY_RANDOM_LENGTH);
1279 state->master_secret = sipe_tls_prf(state,
1280 state->pre_master_secret.buffer,
1281 state->pre_master_secret.length,
1282 (guchar *) "master secret",
1284 random,
1285 TLS_ARRAY_RANDOM_LENGTH * 2,
1286 TLS_ARRAY_MASTER_SECRET_LENGTH);
1287 debug_secrets(state, "tls_calculate_secrets: master secret ",
1288 state->master_secret,
1289 TLS_ARRAY_MASTER_SECRET_LENGTH);
1292 * Calculate session key material
1294 * key_block = PRF(master_secret,
1295 * "key expansion",
1296 * ServerHello.random + ClientHello.random)
1298 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT,
1299 length);
1300 memcpy(random,
1301 state->server_random.buffer,
1302 TLS_ARRAY_RANDOM_LENGTH);
1303 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1304 state->client_random.buffer,
1305 TLS_ARRAY_RANDOM_LENGTH);
1306 state->key_block = sipe_tls_prf(state,
1307 state->master_secret,
1308 TLS_ARRAY_MASTER_SECRET_LENGTH,
1309 (guchar *) "key expansion",
1311 random,
1312 TLS_ARRAY_RANDOM_LENGTH * 2,
1313 length);
1314 g_free(random);
1315 debug_secrets(state, "tls_calculate_secrets: key block ",
1316 state->key_block, length);
1318 /* partition key block */
1319 state->client_write_mac_secret = state->key_block;
1320 state->server_write_mac_secret = state->key_block + state->mac_length;
1321 state->client_write_secret = state->key_block + 2 * state->mac_length;
1322 state->server_write_secret = state->key_block + 2 * state->mac_length + state->key_length;
1324 /* initialize cipher context */
1325 state->cipher_context = sipe_crypt_tls_start(state->cipher_type,
1326 state->client_write_secret,
1327 state->key_length);
1330 #if 0 /* NOT NEEDED? */
1331 /* signing */
1332 static guchar *tls_pkcs1_private_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1333 const guchar *data,
1334 gsize data_length,
1335 gsize buffer_length)
1337 gsize pad_length;
1338 guchar *pad_buffer;
1340 if (data_length + 3 > buffer_length) ||
1341 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */)
1342 return(NULL);
1344 pad_length = buffer_length - data_length - 3;
1345 pad_buffer = g_malloc(buffer_length);
1347 /* PKCS1 private key block padding */
1348 pad_buffer[0] = 0; /* +1 */
1349 pad_buffer[1] = 1; /* +2 */
1350 memset(pad_buffer + 2, 0xFF, pad_length);
1351 pad_buffer[2 + pad_length] = 0; /* +3 */
1352 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1354 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1355 debug_secrets(state, "tls_pkcs1_private_padding: ",
1356 pad_buffer, buffer_length);
1357 #endif
1359 return(pad_buffer);
1361 #endif
1363 /* encryption */
1364 static guchar *tls_pkcs1_public_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1365 const guchar *data,
1366 gsize data_length,
1367 gsize buffer_length)
1369 gsize pad_length, random_count;
1370 guchar *pad_buffer, *random;
1372 if ((data_length + 3 > buffer_length) ||
1373 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */
1374 return(NULL);
1376 pad_length = buffer_length - data_length - 3;
1377 pad_buffer = g_malloc(buffer_length);
1379 /* PKCS1 public key block padding */
1380 pad_buffer[0] = 0; /* +1 */
1381 pad_buffer[1] = 2; /* +2 */
1382 for (random = pad_buffer + 2, random_count = pad_length;
1383 random_count > 0;
1384 random_count--) {
1385 guchar byte;
1386 /* non-zero random byte */
1387 while ((byte = rand() & 0xFF) == 0);
1388 *random++ = byte;
1390 pad_buffer[2 + pad_length] = 0; /* +3 */
1391 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1393 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1394 debug_secrets(state, "tls_pkcs1_private_padding: ",
1395 pad_buffer, buffer_length);
1396 #endif
1398 return(pad_buffer);
1401 static struct tls_compiled_message *tls_client_key_exchange(struct tls_internal_state *state)
1403 struct tls_parsed_array *server_random;
1404 struct tls_parsed_array *server_certificate;
1405 struct ClientKeyExchange_host *exchange;
1406 gsize server_certificate_length;
1407 guchar *padded;
1408 struct tls_compiled_message *msg;
1410 /* check for required data fields */
1411 if (!check_cipher_suite(state))
1412 return(NULL);
1413 server_random = g_hash_table_lookup(state->data, "Random");
1414 if (!server_random) {
1415 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1416 return(NULL);
1418 server_certificate = g_hash_table_lookup(state->data, "Certificate");
1419 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1420 if (!server_certificate || (server_certificate->length < 3)) {
1421 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1422 return(FALSE);
1424 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT" bytes",
1425 server_certificate->length);
1426 /* first certificate is the server certificate */
1427 server_certificate_length = lowlevel_integer_to_host(server_certificate->data,
1429 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT" bytes",
1430 server_certificate_length);
1431 if ((server_certificate_length + 3) > server_certificate->length) {
1432 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1434 state->server_certificate = sipe_cert_crypto_import(server_certificate->data + 3,
1435 server_certificate_length);
1436 if (!state->server_certificate) {
1437 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1438 return(FALSE);
1440 /* server public key modulus length */
1441 server_certificate_length = sipe_cert_crypto_modulus_length(state->server_certificate);
1442 if (server_certificate_length < TLS_ARRAY_MASTER_SECRET_LENGTH) {
1443 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT ")",
1444 server_certificate_length);
1445 return(FALSE);
1447 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT,
1448 server_certificate_length);
1450 /* found all the required fields */
1451 state->server_random.length = server_random->length;
1452 state->server_random.buffer = g_memdup(server_random->data,
1453 server_random->length);
1454 tls_calculate_secrets(state);
1456 /* ClientKeyExchange */
1457 padded = tls_pkcs1_public_padding(state,
1458 state->pre_master_secret.buffer,
1459 state->pre_master_secret.length,
1460 server_certificate_length);
1461 if (!padded) {
1462 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: padding of pre-master secret failed");
1463 return(NULL);
1465 exchange = g_malloc0(sizeof(struct ClientKeyExchange_host) +
1466 server_certificate_length);
1467 exchange->secret.elements = server_certificate_length;
1468 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state->server_certificate),
1469 server_certificate_length,
1470 padded,
1471 (guchar *) exchange->secret.placeholder)) {
1472 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1473 g_free(exchange);
1474 g_free(padded);
1475 return(NULL);
1477 g_free(padded);
1479 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1480 debug_secrets(state, "tls_client_key_exchange: secret (encr) ",
1481 (guchar *) exchange->secret.placeholder,
1482 server_certificate_length);
1483 #endif
1485 msg = compile_handshake_msg(state, &ClientKeyExchange_m, exchange,
1486 sizeof(struct ClientKeyExchange_host) + server_certificate_length);
1487 g_free(exchange);
1489 return(msg);
1492 static struct tls_compiled_message *tls_certificate_verify(struct tls_internal_state *state)
1494 struct CertificateVerify_host *verify;
1495 struct tls_compiled_message *msg;
1496 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1497 guchar *signature;
1498 gsize length;
1500 /* calculate digests */
1501 sipe_digest_md5_end(state->md5_context, digests);
1502 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1504 /* sign digests */
1505 signature = sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state->certificate),
1506 digests,
1507 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1508 &length);
1509 g_free(digests);
1510 if (!signature) {
1511 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1512 return(NULL);
1515 /* CertificateVerify */
1516 verify = g_malloc0(sizeof(struct CertificateVerify_host) +
1517 length);
1518 verify->signature.elements = length;
1519 memcpy(verify->signature.placeholder, signature, length);
1520 g_free(signature);
1522 msg = compile_handshake_msg(state, &CertificateVerify_m, verify,
1523 sizeof(struct CertificateVerify_host) + length);
1524 g_free(verify);
1526 return(msg);
1529 static struct tls_compiled_message *tls_client_finished(struct tls_internal_state *state)
1531 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1532 guchar *verify;
1533 struct tls_compiled_message *cmsg;
1534 struct Finished_host msg;
1536 /* calculate digests */
1537 sipe_digest_md5_end(state->md5_context, digests);
1538 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1541 * verify_data = PRF(master_secret, "client finished",
1542 * MD5(handshake_messages) +
1543 * SHA-1(handshake_messages)) [0..11];
1545 verify = sipe_tls_prf(state,
1546 state->master_secret,
1547 TLS_ARRAY_MASTER_SECRET_LENGTH,
1548 (guchar *) "client finished",
1550 digests,
1551 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1552 TLS_ARRAY_VERIFY_LENGTH);
1553 g_free(digests);
1554 memcpy(msg.verify.verify, verify, TLS_ARRAY_VERIFY_LENGTH);
1555 g_free(verify);
1557 cmsg = compile_handshake_msg(state, &Finished_m, &msg, sizeof(msg));
1559 return(cmsg);
1563 * TLS state handling
1566 static gboolean tls_client_hello(struct tls_internal_state *state)
1568 guint32 now = time(NULL);
1569 guint32 now_N = GUINT32_TO_BE(now);
1570 struct ClientHello_host msg = {
1571 { TLS_PROTOCOL_VERSION_1_0 },
1572 { 0, { 0 } },
1573 { 0 /* empty SessionID */ },
1574 { 6,
1576 TLS_RSA_WITH_RC4_128_MD5,
1577 TLS_RSA_WITH_RC4_128_SHA,
1578 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1579 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
1580 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
1581 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1584 { 1,
1586 TLS_COMP_METHOD_NULL
1590 struct tls_compiled_message *cmsg;
1592 /* First 4 bytes of client_random is the current timestamp */
1593 sipe_tls_fill_random(&state->client_random,
1594 TLS_ARRAY_RANDOM_LENGTH * 8); /* -> bits */
1595 memcpy(state->client_random.buffer, &now_N, sizeof(now_N));
1596 memcpy(msg.random.random, state->client_random.buffer,
1597 TLS_ARRAY_RANDOM_LENGTH);
1599 cmsg = compile_handshake_msg(state, &ClientHello_m, &msg, sizeof(msg));
1600 compile_tls_record(state, cmsg, NULL);
1601 g_free(cmsg);
1603 if (sipe_backend_debug_enabled())
1604 state->debug = g_string_new("");
1606 state->state = TLS_HANDSHAKE_STATE_SERVER_HELLO;
1607 return(tls_record_parse(state, FALSE));
1610 static gboolean tls_server_hello(struct tls_internal_state *state)
1612 struct tls_compiled_message *certificate = NULL;
1613 struct tls_compiled_message *exchange = NULL;
1614 struct tls_compiled_message *verify = NULL;
1615 struct tls_compiled_message *finished = NULL;
1616 gboolean success = FALSE;
1618 if (!tls_record_parse(state, TRUE))
1619 return(FALSE);
1621 if (((certificate = tls_client_certificate(state)) != NULL) &&
1622 ((exchange = tls_client_key_exchange(state)) != NULL) &&
1623 ((verify = tls_certificate_verify(state)) != NULL) &&
1624 ((finished = tls_client_finished(state)) != NULL)) {
1626 /* Part 1 */
1627 compile_tls_record(state, certificate, exchange, verify, NULL);
1629 success = tls_record_parse(state, FALSE);
1630 if (success) {
1631 guchar *part1 = state->common.out_buffer;
1632 gsize part1_length = state->common.out_length;
1633 guchar *part3;
1634 gsize part3_length;
1635 guchar *merged;
1636 gsize length;
1637 /* ChangeCipherSpec is always the same */
1638 static const guchar part2[] = {
1639 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC,
1640 (TLS_PROTOCOL_VERSION_1_0 >> 8) & 0xFF,
1641 TLS_PROTOCOL_VERSION_1_0 & 0xFF,
1642 0x00, 0x01, /* length: 1 byte */
1643 0x01 /* change_cipher_spec(1) */
1646 state->common.out_buffer = NULL;
1648 /* Part 3 - this is the first encrypted record */
1649 compile_encrypted_tls_record(state, finished);
1650 part3 = state->common.out_buffer;
1651 part3_length = state->common.out_length;
1653 /* merge TLS records */
1654 length = part1_length + sizeof(part2) + part3_length;
1655 merged = g_malloc(length);
1657 memcpy(merged, part1, part1_length);
1658 memcpy(merged + part1_length, part2, sizeof(part2));
1659 memcpy(merged + part1_length + sizeof(part2), part3, part3_length);
1660 g_free(part3);
1661 g_free(part1);
1663 /* replace output buffer with merged message */
1664 state->common.out_buffer = merged;
1665 state->common.out_length = length;
1667 state->state = TLS_HANDSHAKE_STATE_FINISHED;
1671 g_free(finished);
1672 g_free(verify);
1673 g_free(exchange);
1674 g_free(certificate);
1675 free_parse_data(state);
1677 return(success);
1680 static gboolean tls_finished(struct tls_internal_state *state)
1682 guchar *random;
1684 if (!tls_record_parse(state, TRUE))
1685 return(FALSE);
1687 /* we don't need the data */
1688 free_parse_data(state);
1691 * Calculate session keys [MS-SIPAE section 3.2.5.1]
1693 * key_material = PRF (master_secret,
1694 * "client EAP encryption",
1695 * ClientHello.random + ServerHello.random)[128]
1696 * = 4 x 32 Bytes
1698 * client key = key_material[3rd 32 Bytes]
1699 * server key = key_material[4th 32 Bytes]
1701 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1702 memcpy(random,
1703 state->client_random.buffer,
1704 TLS_ARRAY_RANDOM_LENGTH);
1705 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1706 state->server_random.buffer,
1707 TLS_ARRAY_RANDOM_LENGTH);
1708 state->tls_dsk_key_block = sipe_tls_prf(state,
1709 state->master_secret,
1710 TLS_ARRAY_MASTER_SECRET_LENGTH,
1711 (guchar *) "client EAP encryption",
1713 random,
1714 TLS_ARRAY_RANDOM_LENGTH * 2,
1715 4 * 32);
1716 g_free(random);
1718 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1719 debug_secrets(state, "tls_finished: TLS-DSK key block ",
1720 state->tls_dsk_key_block, 4 * 32);
1721 #endif
1723 state->common.client_key = state->tls_dsk_key_block + 2 * 32;
1724 state->common.server_key = state->tls_dsk_key_block + 3 * 32;
1725 state->common.key_length = 32;
1727 debug_secrets(state, "tls_finished: TLS-DSK client key ",
1728 state->common.client_key,
1729 state->common.key_length);
1730 debug_secrets(state, "tls_finished: TLS-DSK server key ",
1731 state->common.server_key,
1732 state->common.key_length);
1734 state->common.out_buffer = NULL;
1735 state->common.out_length = 0;
1736 state->state = TLS_HANDSHAKE_STATE_COMPLETED;
1738 return(TRUE);
1742 * TLS public API
1745 struct sipe_tls_state *sipe_tls_start(gpointer certificate)
1747 struct tls_internal_state *state;
1749 if (!certificate)
1750 return(NULL);
1752 state = g_new0(struct tls_internal_state, 1);
1753 state->certificate = certificate;
1754 state->state = TLS_HANDSHAKE_STATE_START;
1755 state->md5_context = sipe_digest_md5_start();
1756 state->sha1_context = sipe_digest_sha1_start();
1757 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_NONE;
1759 return((struct sipe_tls_state *) state);
1762 gboolean sipe_tls_next(struct sipe_tls_state *state)
1764 /* Avoid "cast increases required alignment" errors */
1765 struct tls_internal_state *internal = (void *) state;
1766 gboolean success = FALSE;
1768 if (!state)
1769 return(FALSE);
1771 state->out_buffer = NULL;
1773 switch (internal->state) {
1774 case TLS_HANDSHAKE_STATE_START:
1775 success = tls_client_hello(internal);
1776 break;
1778 case TLS_HANDSHAKE_STATE_SERVER_HELLO:
1779 success = tls_server_hello(internal);
1780 break;
1782 case TLS_HANDSHAKE_STATE_FINISHED:
1783 success = tls_finished(internal);
1784 break;
1786 case TLS_HANDSHAKE_STATE_COMPLETED:
1787 case TLS_HANDSHAKE_STATE_FAILED:
1788 /* This should not happen */
1789 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1790 break;
1793 if (!success) {
1794 internal->state = TLS_HANDSHAKE_STATE_FAILED;
1797 return(success);
1800 guint sipe_tls_expires(struct sipe_tls_state *state)
1802 /* Avoid "cast increases required alignment" errors */
1803 struct tls_internal_state *internal = (void *) state;
1805 if (!state)
1806 return(0);
1808 return(sipe_cert_crypto_expires(internal->certificate));
1811 void sipe_tls_free(struct sipe_tls_state *state)
1813 if (state) {
1814 /* Avoid "cast increases required alignment" errors */
1815 struct tls_internal_state *internal = (void *) state;
1817 free_parse_data(internal);
1818 if (internal->debug)
1819 g_string_free(internal->debug, TRUE);
1820 g_free(internal->tls_dsk_key_block);
1821 g_free(internal->key_block);
1822 g_free(internal->master_secret);
1823 sipe_tls_free_random(&internal->pre_master_secret);
1824 sipe_tls_free_random(&internal->client_random);
1825 sipe_tls_free_random(&internal->server_random);
1826 if (internal->cipher_context)
1827 sipe_crypt_tls_destroy(internal->cipher_context);
1828 if (internal->md5_context)
1829 sipe_digest_md5_destroy(internal->md5_context);
1830 if (internal->sha1_context)
1831 sipe_digest_sha1_destroy(internal->sha1_context);
1832 sipe_cert_crypto_destroy(internal->server_certificate);
1833 g_free(state->out_buffer);
1834 g_free(state);
1838 #endif /* !_SIPE_COMPILING_ANALYZER */
1841 Local Variables:
1842 mode: c
1843 c-file-style: "bsd"
1844 indent-tabs-mode: t
1845 tab-width: 8
1846 End: