crypt: refactor TLS encryption API
[siplcs.git] / src / core / sipe-tls.c
blob4f138b64700a875c045efee8676fd38d8e3d445b
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 gpointer md5_context;
70 gpointer sha1_context;
71 gpointer server_certificate;
72 struct sipe_tls_random client_random;
73 struct sipe_tls_random server_random;
74 struct sipe_tls_random pre_master_secret;
75 gsize mac_length;
76 gsize key_length;
77 guchar *master_secret;
78 guchar *key_block;
79 guchar *tls_dsk_key_block;
80 const guchar *client_write_mac_secret;
81 const guchar *server_write_mac_secret;
82 const guchar *client_write_secret;
83 const guchar *server_write_secret;
84 void (*mac_func)(const guchar *key, gsize key_length,
85 const guchar *data, gsize data_length,
86 guchar *digest);
87 gpointer cipher_context;
88 guint64 sequence_number;
89 gboolean encrypted;
90 gboolean expected;
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_RSA_WITH_AES_128_CBC_SHA 0x002F
111 #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
113 /* CompressionMethods */
114 #define TLS_COMP_METHOD_NULL 0
116 /* various array lengths */
117 #define TLS_ARRAY_RANDOM_LENGTH 32
118 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
119 #define TLS_ARRAY_VERIFY_LENGTH 12
121 #define TLS_RECORD_HEADER_LENGTH 5
122 #define TLS_RECORD_OFFSET_TYPE 0
123 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
124 #define TLS_RECORD_TYPE_HANDSHAKE 22
125 #define TLS_RECORD_OFFSET_VERSION 1
126 #define TLS_RECORD_OFFSET_LENGTH 3
128 #define TLS_HANDSHAKE_HEADER_LENGTH 4
129 #define TLS_HANDSHAKE_OFFSET_TYPE 0
130 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
131 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
132 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
133 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
134 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
135 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
136 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
137 #define TLS_HANDSHAKE_TYPE_FINISHED 20
138 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
140 struct layout_descriptor;
141 typedef gboolean parse_func(struct tls_internal_state *state,
142 const struct layout_descriptor *desc);
144 /* Defines the strictest alignment requirement */
145 struct tls_compile_integer;
146 typedef void compile_func(struct tls_internal_state *state,
147 const struct layout_descriptor *desc,
148 const struct tls_compile_integer *data);
150 struct layout_descriptor {
151 const gchar *label;
152 parse_func *parser;
153 compile_func *compiler;
154 gsize min; /* 0 for fixed/array */
155 gsize max;
156 gsize offset;
159 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
160 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
162 struct msg_descriptor {
163 const struct msg_descriptor *next;
164 const gchar *description;
165 const struct layout_descriptor *layouts;
166 guint type;
169 /* parsed data */
170 struct tls_parsed_integer {
171 guint value;
174 struct tls_parsed_array {
175 gsize length; /* bytes */
176 const guchar data[0];
179 /* compile data */
180 struct tls_compile_integer {
181 gsize value;
184 struct tls_compile_array {
185 gsize elements; /* unused */
186 guchar placeholder[];
189 struct tls_compile_random {
190 gsize elements; /* unused */
191 guchar random[TLS_ARRAY_RANDOM_LENGTH];
194 struct tls_compile_verify {
195 gsize elements; /* unused */
196 guchar verify[TLS_ARRAY_VERIFY_LENGTH];
199 struct tls_compile_vector {
200 gsize elements; /* VECTOR */
201 guint placeholder[];
204 struct tls_compile_sessionid {
205 gsize elements; /* VECTOR */
208 struct tls_compile_cipher {
209 gsize elements; /* VECTOR */
210 guint suites[5];
213 struct tls_compile_compression {
214 gsize elements; /* VECTOR */
215 guint methods[1];
218 /* compiled message */
219 struct tls_compiled_message {
220 gsize size;
221 guchar data[];
225 * Random byte buffers
227 void sipe_tls_fill_random(struct sipe_tls_random *random,
228 guint bits)
230 guint bytes = ((bits + 15) / 16) * 2;
231 guint16 *p = g_malloc(bytes);
233 SIPE_DEBUG_INFO("sipe_tls_fill_random: %d bits -> %d bytes",
234 bits, bytes);
236 random->buffer = (guint8*) p;
237 random->length = bytes;
239 for (bytes /= 2; bytes; bytes--)
240 *p++ = rand() & 0xFFFF;
243 void sipe_tls_free_random(struct sipe_tls_random *random)
245 g_free(random->buffer);
249 * TLS message debugging
251 static void debug_hex(struct tls_internal_state *state,
252 gsize alternative_length)
254 GString *str = state->debug;
255 const guchar *bytes;
256 gsize length;
257 gint count;
259 if (!str) return;
261 bytes = state->msg_current;
262 length = alternative_length ? alternative_length : state->msg_remainder;
263 count = -1;
265 while (length-- > 0) {
266 if (++count == 0) {
267 /* do nothing */;
268 } else if ((count % 16) == 0) {
269 g_string_append(str, "\n");
270 } else if ((count % 8) == 0) {
271 g_string_append(str, " ");
273 g_string_append_printf(str, " %02X", *bytes++);
275 g_string_append(str, "\n");
278 #define debug_print(state, string) \
279 if (state->debug) g_string_append(state->debug, string)
280 #define debug_printf(state, format, ...) \
281 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
283 /* Analyzer only needs the debugging functions */
284 #ifndef _SIPE_COMPILING_ANALYZER
286 static void debug_secrets(struct tls_internal_state *state,
287 const gchar *label,
288 const guchar *secret,
289 gsize secret_length)
291 if (state->debug && secret) {
292 g_string_append_printf(state->debug, "%s (%3" G_GSIZE_FORMAT ") = ",
293 label, secret_length);
294 while (secret_length--)
295 g_string_append_printf(state->debug, "%02X", *secret++);
296 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
297 g_string_truncate(state->debug, 0);
302 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
304 static guchar *sipe_tls_p_md5(const guchar *secret,
305 gsize secret_length,
306 const guchar *seed,
307 gsize seed_length,
308 gsize output_length)
310 guchar *output = NULL;
313 * output_length == 0 -> illegal
314 * output_length == 1..16 -> iterations = 1
315 * output_length == 17..32 -> iterations = 2
317 if (secret && seed && (output_length > 0)) {
318 guint iterations = (output_length + SIPE_DIGEST_HMAC_MD5_LENGTH - 1) / SIPE_DIGEST_HMAC_MD5_LENGTH;
319 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length);
320 guchar A[SIPE_DIGEST_HMAC_MD5_LENGTH];
321 guchar *p;
323 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
324 secret_length, seed_length);
325 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
326 output_length, iterations);
328 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
329 sipe_digest_hmac_md5(secret, secret_length,
330 seed, seed_length,
333 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
334 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_MD5_LENGTH);
336 while (iterations-- > 0) {
337 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
338 guchar P[SIPE_DIGEST_HMAC_MD5_LENGTH];
339 memcpy(concat, A, SIPE_DIGEST_HMAC_MD5_LENGTH);
340 memcpy(concat + SIPE_DIGEST_HMAC_MD5_LENGTH, seed, seed_length);
341 sipe_digest_hmac_md5(secret, secret_length,
342 concat, SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length,
344 memcpy(p, P, SIPE_DIGEST_HMAC_MD5_LENGTH);
345 p += SIPE_DIGEST_HMAC_MD5_LENGTH;
347 /* A(i+1) = HMAC_MD5(secret, A(i)) */
348 sipe_digest_hmac_md5(secret, secret_length,
349 A, SIPE_DIGEST_HMAC_MD5_LENGTH,
352 g_free(concat);
355 return(output);
358 guchar *sipe_tls_p_sha1(const guchar *secret,
359 gsize secret_length,
360 const guchar *seed,
361 gsize seed_length,
362 gsize output_length)
364 guchar *output = NULL;
367 * output_length == 0 -> illegal
368 * output_length == 1..20 -> iterations = 1
369 * output_length == 21..40 -> iterations = 2
371 if (secret && seed && (output_length > 0)) {
372 guint iterations = (output_length + SIPE_DIGEST_HMAC_SHA1_LENGTH - 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH;
373 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length);
374 guchar A[SIPE_DIGEST_HMAC_SHA1_LENGTH];
375 guchar *p;
377 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
378 secret_length, seed_length);
379 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
380 output_length, iterations);
382 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
383 sipe_digest_hmac_sha1(secret, secret_length,
384 seed, seed_length,
387 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
388 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_SHA1_LENGTH);
390 while (iterations-- > 0) {
391 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
392 guchar P[SIPE_DIGEST_HMAC_SHA1_LENGTH];
393 memcpy(concat, A, SIPE_DIGEST_HMAC_SHA1_LENGTH);
394 memcpy(concat + SIPE_DIGEST_HMAC_SHA1_LENGTH, seed, seed_length);
395 sipe_digest_hmac_sha1(secret, secret_length,
396 concat, SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length,
398 memcpy(p, P, SIPE_DIGEST_HMAC_SHA1_LENGTH);
399 p += SIPE_DIGEST_HMAC_SHA1_LENGTH;
401 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
402 sipe_digest_hmac_sha1(secret, secret_length,
403 A, SIPE_DIGEST_HMAC_SHA1_LENGTH,
406 g_free(concat);
409 return(output);
412 static guchar *sipe_tls_prf(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
413 const guchar *secret,
414 gsize secret_length,
415 const guchar *label,
416 gsize label_length,
417 const guchar *seed,
418 gsize seed_length,
419 gsize output_length)
421 gsize half = (secret_length + 1) / 2;
422 gsize newseed_length = label_length + seed_length;
423 /* secret: used as S1; secret2: last half of original secret (S2) */
424 guchar *secret2 = g_memdup(secret + secret_length - half, half);
425 guchar *newseed = g_malloc(newseed_length);
426 guchar *md5, *dest;
427 guchar *sha1, *src;
428 gsize count;
430 /* make Coverity happy - lengths could be 0 */
431 if (!secret2 || !newseed) {
432 g_free(secret2);
433 g_free(newseed);
434 return(NULL);
438 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
439 * P_SHA-1(S2, label + seed);
441 memcpy(newseed, label, label_length);
442 memcpy(newseed + label_length, seed, seed_length);
443 #undef __SIPE_TLS_CRYPTO_DEBUG
444 #ifdef __SIPE_TLS_CRYPTO_DEBUG
445 debug_secrets(state, "sipe_tls_prf: secret ",
446 secret, secret_length);
447 debug_secrets(state, "sipe_tls_prf: combined seed ",
448 newseed, newseed_length);
449 SIPE_DEBUG_INFO("total seed length %" G_GSIZE_FORMAT,
450 newseed_length);
451 debug_secrets(state, "sipe_tls_prf: S1 ",
452 secret, half);
453 debug_secrets(state, "sipe_tls_prf: S2 ",
454 secret2, half);
455 #endif
456 md5 = sipe_tls_p_md5(secret, half, newseed, newseed_length, output_length);
457 sha1 = sipe_tls_p_sha1(secret2, half, newseed, newseed_length, output_length);
458 #ifdef __SIPE_TLS_CRYPTO_DEBUG
459 debug_secrets(state, "sipe_tls_prf: P_md5() ",
460 md5, output_length);
461 debug_secrets(state, "sipe_tls_prf: P_sha1() ",
462 sha1, output_length);
463 #endif
464 for (dest = md5, src = sha1, count = output_length;
465 count > 0;
466 count--)
467 *dest++ ^= *src++;
469 g_free(sha1);
470 g_free(newseed);
471 g_free(secret2);
473 #ifdef __SIPE_TLS_CRYPTO_DEBUG
474 debug_secrets(state, "sipe_tls_prf: PRF() ",
475 md5, output_length);
476 #endif
478 return(md5);
481 #endif /* !_SIPE_COMPILING_ANALYZER */
484 * TLS data parsers
486 * Low-level data conversion routines
488 * - host alignment agnostic, i.e. can fetch a word from uneven address
489 * - TLS -> host endianess conversion
490 * - no length check, caller has to do it
491 * - don't modify state
493 static guint lowlevel_integer_to_host(const guchar *bytes,
494 gsize length)
496 guint sum = 0;
497 while (length--) sum = (sum << 8) + *bytes++;
498 return(sum);
502 * Generic data type parser routines
504 static gboolean msg_remainder_check(struct tls_internal_state *state,
505 const gchar *label,
506 gsize length)
508 if (length > state->msg_remainder) {
509 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT,
510 label, length, state->msg_remainder);
511 return(FALSE);
513 return(TRUE);
516 static gboolean parse_integer_quiet(struct tls_internal_state *state,
517 const gchar *label,
518 gsize length,
519 guint *result)
521 if (!msg_remainder_check(state, label, length)) return(FALSE);
522 *result = lowlevel_integer_to_host(state->msg_current, length);
523 state->msg_current += length;
524 state->msg_remainder -= length;
525 return(TRUE);
528 static gboolean parse_integer(struct tls_internal_state *state,
529 const struct layout_descriptor *desc)
531 guint value;
532 if (!parse_integer_quiet(state, desc->label, desc->max, &value))
533 return(FALSE);
534 debug_printf(state, "%s/INTEGER%" G_GSIZE_FORMAT " = %d\n",
535 desc->label, desc->max, value);
536 if (state->data) {
537 struct tls_parsed_integer *save = g_new0(struct tls_parsed_integer, 1);
538 save->value = value;
539 g_hash_table_insert(state->data, (gpointer) desc->label, save);
541 return(TRUE);
544 static gboolean parse_array(struct tls_internal_state *state,
545 const struct layout_descriptor *desc)
547 if (!msg_remainder_check(state, desc->label, desc->max))
548 return(FALSE);
549 debug_printf(state, "%s/ARRAY[%" G_GSIZE_FORMAT "]\n",
550 desc->label, desc->max);
551 #ifdef _SIPE_COMPILING_ANALYZER
552 if (desc->max)
553 debug_hex(state, desc->max);
554 #endif
555 if (state->data) {
556 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
557 desc->max);
558 save->length = desc->max;
559 memcpy((guchar *)save->data, state->msg_current, desc->max);
560 g_hash_table_insert(state->data, (gpointer) desc->label, save);
563 state->msg_current += desc->max;
564 state->msg_remainder -= desc->max;
565 return(TRUE);
568 static gboolean parse_vector(struct tls_internal_state *state,
569 const struct layout_descriptor *desc)
571 guint length;
572 if (!parse_integer_quiet(state, desc->label,
573 (desc->max > TLS_VECTOR_MAX16) ? 3 :
574 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1,
575 &length))
576 return(FALSE);
577 if (length < desc->min) {
578 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT,
579 desc->label, length, desc->min);
580 return(FALSE);
582 debug_printf(state, "%s/VECTOR<%d>\n", desc->label, length);
583 #ifdef _SIPE_COMPILING_ANALYZER
584 if (length)
585 debug_hex(state, length);
586 #endif
587 if (state->data) {
588 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
589 length);
590 save->length = length;
591 memcpy((guchar *)save->data, state->msg_current, length);
592 g_hash_table_insert(state->data, (gpointer) desc->label, save);
594 state->msg_current += length;
595 state->msg_remainder -= length;
596 return(TRUE);
600 * Specific data type parser routines
603 /* TBD... */
606 * TLS data compilers
608 * Low-level data conversion routines
610 * - host alignment agnostic, i.e. can fetch a word from uneven address
611 * - host -> TLS host endianess conversion
612 * - don't modify state
614 static void lowlevel_integer_to_tls(guchar *bytes,
615 gsize length,
616 guint value)
618 while (length--) {
619 bytes[length] = value & 0xFF;
620 value >>= 8;
625 * Generic data type compiler routines
627 static void compile_integer(struct tls_internal_state *state,
628 const struct layout_descriptor *desc,
629 const struct tls_compile_integer *data)
631 lowlevel_integer_to_tls(state->msg_current, desc->max, data->value);
632 state->msg_current += desc->max;
635 static void compile_array(struct tls_internal_state *state,
636 const struct layout_descriptor *desc,
637 const struct tls_compile_integer *data)
639 const struct tls_compile_array *array = (struct tls_compile_array *) data;
640 memcpy(state->msg_current, array->placeholder, desc->max);
641 state->msg_current += desc->max;
644 static void compile_vector(struct tls_internal_state *state,
645 const struct layout_descriptor *desc,
646 const struct tls_compile_integer *data)
648 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
649 gsize length = vector->elements;
650 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
651 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
653 lowlevel_integer_to_tls(state->msg_current, length_field, length);
654 state->msg_current += length_field;
655 memcpy(state->msg_current, vector->placeholder, length);
656 state->msg_current += length;
659 static void compile_vector_int2(struct tls_internal_state *state,
660 const struct layout_descriptor *desc,
661 const struct tls_compile_integer *data)
663 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
664 gsize elements = vector->elements;
665 gsize length = elements * sizeof(guint16);
666 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
667 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
668 const guint *p = vector->placeholder;
670 lowlevel_integer_to_tls(state->msg_current, length_field, length);
671 state->msg_current += length_field;
672 while (elements--) {
673 lowlevel_integer_to_tls(state->msg_current, sizeof(guint16), *p++);
674 state->msg_current += sizeof(guint16);
679 * Specific data type compiler routines
682 /* TBD... */
685 * TLS handshake message layout descriptors
687 struct ClientHello_host {
688 struct tls_compile_integer protocol_version;
689 struct tls_compile_random random;
690 struct tls_compile_sessionid sessionid;
691 struct tls_compile_cipher cipher;
692 struct tls_compile_compression compression;
694 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
696 static const struct layout_descriptor ClientHello_l[] = {
697 { "Client Protocol Version", parse_integer, compile_integer, 0, 2, CLIENTHELLO_OFFSET(protocol_version) },
698 { "Random", parse_array, compile_array, 0, TLS_ARRAY_RANDOM_LENGTH, CLIENTHELLO_OFFSET(random) },
699 { "SessionID", parse_vector, compile_vector, 0, 32, CLIENTHELLO_OFFSET(sessionid) },
700 { "CipherSuite", parse_vector, compile_vector_int2, 2, TLS_VECTOR_MAX16, CLIENTHELLO_OFFSET(cipher)},
701 { "CompressionMethod", parse_vector, compile_vector, 1, TLS_VECTOR_MAX8, CLIENTHELLO_OFFSET(compression) },
702 TLS_LAYOUT_DESCRIPTOR_END
704 static const struct msg_descriptor ClientHello_m = {
705 NULL, "Client Hello", ClientHello_l, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
708 static const struct layout_descriptor ServerHello_l[] = {
709 { "Server Protocol Version", parse_integer, NULL, 0, 2, 0 },
710 { "Random", parse_array, NULL, 0, TLS_ARRAY_RANDOM_LENGTH, 0 },
711 { "SessionID", parse_vector, NULL, 0, 32, 0 },
712 { "CipherSuite", parse_integer, NULL, 0, 2, 0 },
713 { "CompressionMethod", parse_integer, NULL, 0, 1, 0 },
714 TLS_LAYOUT_DESCRIPTOR_END
716 static const struct msg_descriptor ServerHello_m = {
717 &ClientHello_m, "Server Hello", ServerHello_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO
720 struct Certificate_host {
721 struct tls_compile_vector certificate;
723 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
725 static const struct layout_descriptor Certificate_l[] = {
726 { "Certificate", parse_vector, compile_vector, 0, TLS_VECTOR_MAX24, CERTIFICATE_OFFSET(certificate) },
727 TLS_LAYOUT_DESCRIPTOR_END
729 static const struct msg_descriptor Certificate_m = {
730 &ServerHello_m, "Certificate", Certificate_l, TLS_HANDSHAKE_TYPE_CERTIFICATE
733 static const struct layout_descriptor CertificateRequest_l[] = {
734 { "CertificateType", parse_vector, NULL, 1, TLS_VECTOR_MAX8, 0 },
735 { "DistinguishedName", parse_vector, NULL, 0, TLS_VECTOR_MAX16, 0 },
736 TLS_LAYOUT_DESCRIPTOR_END
738 static const struct msg_descriptor CertificateRequest_m = {
739 &Certificate_m, "Certificate Request", CertificateRequest_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
742 static const struct layout_descriptor ServerHelloDone_l[] = {
743 TLS_LAYOUT_DESCRIPTOR_END
745 static const struct msg_descriptor ServerHelloDone_m = {
746 &CertificateRequest_m, "Server Hello Done", ServerHelloDone_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
749 struct ClientKeyExchange_host {
750 struct tls_compile_vector secret;
752 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
754 static const struct layout_descriptor ClientKeyExchange_l[] = {
755 { "Exchange Keys", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CLIENTKEYEXCHANGE_OFFSET(secret) },
756 TLS_LAYOUT_DESCRIPTOR_END
758 static const struct msg_descriptor ClientKeyExchange_m = {
759 &ServerHelloDone_m, "Client Key Exchange", ClientKeyExchange_l, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
762 struct CertificateVerify_host {
763 struct tls_compile_vector signature;
765 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
767 static const struct layout_descriptor CertificateVerify_l[] = {
768 { "Signature", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CERTIFICATEVERIFY_OFFSET(signature) },
769 TLS_LAYOUT_DESCRIPTOR_END
771 static const struct msg_descriptor CertificateVerify_m = {
772 &ClientKeyExchange_m, "Certificate Verify", CertificateVerify_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
775 struct Finished_host {
776 struct tls_compile_verify verify;
778 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
780 static const struct layout_descriptor Finished_l[] = {
781 { "Verify Data", parse_array, compile_array, 0, TLS_ARRAY_VERIFY_LENGTH, FINISHED_OFFSET(verify) },
782 TLS_LAYOUT_DESCRIPTOR_END
784 static const struct msg_descriptor Finished_m = {
785 &CertificateVerify_m, "Finished", Finished_l, TLS_HANDSHAKE_TYPE_FINISHED
788 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
791 * TLS message parsers
793 static gboolean handshake_parse(struct tls_internal_state *state,
794 guint expected_type)
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 if (msg_type == expected_type)
831 state->expected = TRUE;
833 state->msg_current = (guchar *) bytes + TLS_HANDSHAKE_HEADER_LENGTH;
834 state->msg_remainder = msg_length;
836 if (desc && desc->layouts) {
837 const struct layout_descriptor *ldesc = desc->layouts;
839 debug_printf(state, "%s\n", desc->description);
841 while (TLS_LAYOUT_IS_VALID(ldesc)) {
842 success = ldesc->parser(state, ldesc);
843 if (!success)
844 break;
845 ldesc++;
847 if (!success)
848 break;
849 } else {
850 debug_print(state, "ignored\n");
851 debug_hex(state, 0);
854 /* next message */
855 bytes += TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
856 length -= TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
857 if (length > 0) {
858 debug_print(state, "------\n");
859 } else {
860 success = TRUE;
864 return(success);
867 static void free_parse_data(struct tls_internal_state *state)
869 if (state->data) {
870 g_hash_table_destroy(state->data);
871 state->data = NULL;
875 static gboolean tls_record_parse(struct tls_internal_state *state,
876 gboolean incoming,
877 guint expected)
879 const guchar *bytes = incoming ? state->common.in_buffer : state->common.out_buffer;
880 gsize length = incoming ? state->common.in_length : state->common.out_length;
881 guint version;
882 const gchar *version_str;
883 gsize record_length;
884 gboolean success = TRUE;
886 /* reject empty incoming messages */
887 if (incoming && (length == 0)) {
888 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: empty TLS message received");
889 return(FALSE);
892 #ifndef _SIPE_COMPILING_ANALYZER
893 debug_printf(state, "TLS MESSAGE %s\n", incoming ? "INCOMING" : "OUTGOING");
894 #endif
896 /* Collect parser data for incoming messages */
897 if (incoming)
898 state->data = g_hash_table_new_full(g_str_hash, g_str_equal,
899 NULL, g_free);
901 state->expected = FALSE;
902 while (success && (length > 0)) {
904 /* truncated header check */
905 if (length < TLS_RECORD_HEADER_LENGTH) {
906 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT " bytes)",
907 length);
908 success = FALSE;
909 break;
912 /* protocol version check */
913 version = lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_VERSION, 2);
914 if (version < TLS_PROTOCOL_VERSION_1_0) {
915 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
916 success = FALSE;
917 break;
919 switch (version) {
920 case TLS_PROTOCOL_VERSION_1_0:
921 version_str = "1.0 (RFC2246)";
922 break;
923 case TLS_PROTOCOL_VERSION_1_1:
924 version_str = "1.1 (RFC4346)";
925 break;
926 case TLS_PROTOCOL_VERSION_1_2:
927 version_str = "1.2 (RFC5246)";
928 break;
929 default:
930 version_str = "<future protocol version>";
931 break;
934 /* record length check */
935 record_length = TLS_RECORD_HEADER_LENGTH +
936 lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_LENGTH, 2);
937 if (record_length > length) {
938 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
939 success = FALSE;
940 break;
943 /* TLS record header OK */
944 debug_printf(state, "TLS %s record (%" G_GSIZE_FORMAT " bytes)\n",
945 version_str, record_length);
946 state->msg_current = (guchar *) bytes + TLS_RECORD_HEADER_LENGTH;
947 state->msg_remainder = record_length - TLS_RECORD_HEADER_LENGTH;
949 /* Analyzer only needs the debugging functions */
950 #ifndef _SIPE_COMPILING_ANALYZER
951 /* Add incoming message contents to digest contexts */
952 if (incoming) {
953 sipe_digest_md5_update(state->md5_context,
954 state->msg_current,
955 state->msg_remainder);
956 sipe_digest_sha1_update(state->sha1_context,
957 state->msg_current,
958 state->msg_remainder);
960 #endif /* !_SIPE_COMPILING_ANALYZER */
962 switch (bytes[TLS_RECORD_OFFSET_TYPE]) {
963 case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:
964 debug_print(state, "Change Cipher Spec\n");
965 if (incoming)
966 state->encrypted = TRUE;
967 if (expected == TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC)
968 state->expected = TRUE;
969 break;
971 case TLS_RECORD_TYPE_HANDSHAKE:
972 if (incoming && state->encrypted) {
973 debug_print(state, "Encrypted handshake message\n");
974 debug_hex(state, 0);
975 } else {
976 success = handshake_parse(state, expected);
978 break;
980 default:
981 debug_print(state, "Unsupported TLS message\n");
982 debug_hex(state, 0);
983 break;
986 /* next fragment */
987 bytes += record_length;
988 length -= record_length;
991 #ifndef _SIPE_COMPILING_ANALYZER
992 if (incoming && !state->expected) {
993 SIPE_DEBUG_ERROR("tls_record_parse: did not find expected msg type %d",
994 expected);
995 success = FALSE;
997 #endif
999 if (!success)
1000 free_parse_data(state);
1002 if (state->debug) {
1003 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
1004 g_string_truncate(state->debug, 0);
1007 return(success);
1010 /* Analyzer only needs the debugging functions */
1011 #ifndef _SIPE_COMPILING_ANALYZER
1014 * TLS message compiler
1016 static void compile_tls_record(struct tls_internal_state *state,
1017 ...)
1019 gsize total_size = 0;
1020 guchar *current;
1021 va_list ap;
1023 /* calculate message size */
1024 va_start(ap, state);
1025 while (1) {
1026 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1027 if (!msg) break;
1028 total_size += msg->size;
1030 va_end(ap);
1032 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT,
1033 total_size);
1035 state->common.out_buffer = current = g_malloc(total_size + TLS_RECORD_HEADER_LENGTH);
1036 state->common.out_length = total_size + TLS_RECORD_HEADER_LENGTH;
1038 /* add TLS record header */
1039 current[TLS_RECORD_OFFSET_TYPE] = TLS_RECORD_TYPE_HANDSHAKE;
1040 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_VERSION, 2,
1041 TLS_PROTOCOL_VERSION_1_0);
1042 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_LENGTH, 2,
1043 total_size);
1044 current += TLS_RECORD_HEADER_LENGTH;
1046 /* copy messages */
1047 va_start(ap, state);
1048 while (1) {
1049 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1050 if (!msg) break;
1052 memcpy(current, msg->data, msg->size);
1053 current += msg->size;
1055 va_end(ap);
1058 static void compile_encrypted_tls_record(struct tls_internal_state *state,
1059 const struct tls_compiled_message *msg)
1061 guchar *plaintext;
1062 gsize plaintext_length;
1063 guchar *mac;
1064 gsize mac_length;
1065 guchar *message;
1066 guchar *encrypted;
1067 gsize encrypted_length;
1069 /* Create plaintext TLS record */
1070 compile_tls_record(state, msg, NULL);
1071 plaintext = state->common.out_buffer;
1072 plaintext_length = state->common.out_length;
1073 if (plaintext_length == 0) /* make Coverity happy */
1074 return;
1076 /* Prepare encryption buffer */
1077 encrypted_length = plaintext_length + state->mac_length;
1078 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT,
1079 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1080 message = g_malloc(encrypted_length);
1081 memcpy(message, plaintext, plaintext_length);
1082 lowlevel_integer_to_tls(message + TLS_RECORD_OFFSET_LENGTH, 2,
1083 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1086 * Calculate MAC
1088 * HMAC_hash(client_write_mac_secret,
1089 * sequence_number + type + version + length + fragment)
1090 * \--- == original TLS record ---/
1092 mac_length = sizeof(guint64) + plaintext_length;
1093 mac = g_malloc(mac_length);
1094 lowlevel_integer_to_tls(mac,
1095 sizeof(guint64),
1096 state->sequence_number++);
1097 memcpy(mac + sizeof(guint64), plaintext, plaintext_length);
1098 g_free(plaintext);
1099 state->mac_func(state->client_write_mac_secret,
1100 state->mac_length,
1101 mac,
1102 mac_length,
1103 message + plaintext_length);
1104 g_free(mac);
1106 /* Encrypt message + MAC */
1107 encrypted = g_malloc(encrypted_length);
1108 memcpy(encrypted, message, TLS_RECORD_HEADER_LENGTH);
1109 sipe_crypt_tls_stream(state->cipher_context,
1110 message + TLS_RECORD_HEADER_LENGTH,
1111 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1112 encrypted + TLS_RECORD_HEADER_LENGTH);
1113 g_free(message);
1115 /* swap buffers */
1116 state->common.out_buffer = encrypted;
1117 state->common.out_length = encrypted_length;
1120 static struct tls_compiled_message *compile_handshake_msg(struct tls_internal_state *state,
1121 const struct msg_descriptor *desc,
1122 gpointer data,
1123 gsize size)
1126 * Estimate the size of the compiled message
1128 * The data structures in the host format have zero or more padding
1129 * bytes added by the compiler to ensure correct element alignments.
1130 * So the sizeof() of the data structure is always equal or greater
1131 * than the space needed for the compiled data. By adding the space
1132 * required for the headers we arrive at a safe estimate
1134 * Therefore we don't need space checks in the compiler functions
1136 gsize total_size = sizeof(struct tls_compiled_message) +
1137 size + TLS_HANDSHAKE_HEADER_LENGTH;
1138 struct tls_compiled_message *msg = g_malloc(total_size);
1139 guchar *handshake = msg->data;
1140 const struct layout_descriptor *ldesc = desc->layouts;
1141 gsize length;
1143 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT,
1144 total_size);
1146 /* add TLS handshake header */
1147 handshake[TLS_HANDSHAKE_OFFSET_TYPE] = desc->type;
1148 state->msg_current = handshake + TLS_HANDSHAKE_HEADER_LENGTH;
1150 while (TLS_LAYOUT_IS_VALID(ldesc)) {
1152 * Avoid "cast increases required alignment" errors
1154 * (void *) tells the compiler that we know what we're
1155 * doing, i.e. we know that the calculated address
1156 * points to correctly aligned data.
1158 ldesc->compiler(state, ldesc,
1159 (void *) ((guchar *) data + ldesc->offset));
1160 ldesc++;
1163 length = state->msg_current - handshake - TLS_HANDSHAKE_HEADER_LENGTH;
1164 lowlevel_integer_to_tls(handshake + TLS_HANDSHAKE_OFFSET_LENGTH,
1165 3, length);
1166 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT,
1167 desc->type, desc->description, length);
1169 msg->size = length + TLS_HANDSHAKE_HEADER_LENGTH;
1171 /* update digest contexts */
1172 sipe_digest_md5_update(state->md5_context, handshake, msg->size);
1173 sipe_digest_sha1_update(state->sha1_context, handshake, msg->size);
1175 return(msg);
1179 * Specific TLS data verficiation & message compilers
1181 static struct tls_compiled_message *tls_client_certificate(struct tls_internal_state *state)
1183 struct Certificate_host *certificate;
1184 gsize certificate_length = sipe_cert_crypto_raw_length(state->certificate);
1185 struct tls_compiled_message *msg;
1187 /* setup our response */
1188 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1189 certificate = g_malloc0(sizeof(struct Certificate_host) + 3 +
1190 certificate_length);
1191 certificate->certificate.elements = certificate_length + 3;
1192 lowlevel_integer_to_tls((guchar *) certificate->certificate.placeholder, 3,
1193 certificate_length);
1194 memcpy((guchar *) certificate->certificate.placeholder + 3,
1195 sipe_cert_crypto_raw(state->certificate),
1196 certificate_length);
1198 msg = compile_handshake_msg(state, &Certificate_m, certificate,
1199 sizeof(struct Certificate_host) + certificate_length + 3);
1200 g_free(certificate);
1202 return(msg);
1205 static gboolean check_cipher_suite(struct tls_internal_state *state)
1207 struct tls_parsed_integer *cipher_suite = g_hash_table_lookup(state->data,
1208 "CipherSuite");
1209 const gchar *label_mac = NULL;
1210 const gchar *label_cipher = NULL;
1212 if (!cipher_suite) {
1213 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1214 return(FALSE);
1217 switch (cipher_suite->value) {
1218 case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
1219 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1220 state->key_length = 40 / 8;
1221 state->mac_func = sipe_digest_hmac_md5;
1222 label_mac = "MD5";
1223 label_cipher = "RC4";
1224 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1225 break;
1227 case TLS_RSA_WITH_RC4_128_MD5:
1228 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1229 state->key_length = 128 / 8;
1230 state->mac_func = sipe_digest_hmac_md5;
1231 label_mac = "MD5";
1232 label_cipher = "RC4";
1233 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1234 break;
1236 case TLS_RSA_WITH_RC4_128_SHA:
1237 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1238 state->key_length = 128 / 8;
1239 state->mac_func = sipe_digest_hmac_sha1;
1240 label_mac = "SHA-1";
1241 label_cipher = "RC4";
1242 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1243 break;
1245 case TLS_RSA_WITH_AES_128_CBC_SHA:
1246 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1247 state->key_length = 128 / 8;
1248 state->mac_func = sipe_digest_hmac_sha1;
1249 label_mac = "SHA-1";
1250 label_cipher = "AES-CBC";
1251 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1252 break;
1254 case TLS_RSA_WITH_AES_256_CBC_SHA:
1255 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1256 state->key_length = 256 / 8;
1257 state->mac_func = sipe_digest_hmac_sha1;
1258 label_mac = "SHA-1";
1259 label_cipher = "AES-CBC";
1260 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1261 break;
1263 default:
1264 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1265 cipher_suite->value);
1266 break;
1269 if (label_cipher && label_mac)
1270 SIPE_DEBUG_INFO("check_cipher_suite: KEY(stream cipher %s) %" G_GSIZE_FORMAT ", MAC(%s) %" G_GSIZE_FORMAT,
1271 label_cipher, state->key_length,
1272 label_mac, state->mac_length);
1274 return(label_cipher && label_mac);
1277 static void tls_calculate_secrets(struct tls_internal_state *state)
1279 gsize length = 2 * (state->mac_length + state->key_length);
1280 guchar *random;
1282 /* Generate pre-master secret */
1283 sipe_tls_fill_random(&state->pre_master_secret,
1284 TLS_ARRAY_MASTER_SECRET_LENGTH * 8); /* bits */
1285 lowlevel_integer_to_tls(state->pre_master_secret.buffer, 2,
1286 TLS_PROTOCOL_VERSION_1_0);
1287 debug_secrets(state, "tls_calculate_secrets: pre-master secret",
1288 state->pre_master_secret.buffer,
1289 state->pre_master_secret.length);
1292 * Calculate master secret
1294 * master_secret = PRF(pre_master_secret,
1295 * "master secret",
1296 * ClientHello.random + ServerHello.random)
1298 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1299 memcpy(random,
1300 state->client_random.buffer,
1301 TLS_ARRAY_RANDOM_LENGTH);
1302 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1303 state->server_random.buffer,
1304 TLS_ARRAY_RANDOM_LENGTH);
1305 state->master_secret = sipe_tls_prf(state,
1306 state->pre_master_secret.buffer,
1307 state->pre_master_secret.length,
1308 (guchar *) "master secret",
1310 random,
1311 TLS_ARRAY_RANDOM_LENGTH * 2,
1312 TLS_ARRAY_MASTER_SECRET_LENGTH);
1313 debug_secrets(state, "tls_calculate_secrets: master secret ",
1314 state->master_secret,
1315 TLS_ARRAY_MASTER_SECRET_LENGTH);
1318 * Calculate session key material
1320 * key_block = PRF(master_secret,
1321 * "key expansion",
1322 * ServerHello.random + ClientHello.random)
1324 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT,
1325 length);
1326 memcpy(random,
1327 state->server_random.buffer,
1328 TLS_ARRAY_RANDOM_LENGTH);
1329 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1330 state->client_random.buffer,
1331 TLS_ARRAY_RANDOM_LENGTH);
1332 state->key_block = sipe_tls_prf(state,
1333 state->master_secret,
1334 TLS_ARRAY_MASTER_SECRET_LENGTH,
1335 (guchar *) "key expansion",
1337 random,
1338 TLS_ARRAY_RANDOM_LENGTH * 2,
1339 length);
1340 g_free(random);
1341 debug_secrets(state, "tls_calculate_secrets: key block ",
1342 state->key_block, length);
1344 /* partition key block */
1345 state->client_write_mac_secret = state->key_block;
1346 state->server_write_mac_secret = state->key_block + state->mac_length;
1347 state->client_write_secret = state->key_block + 2 * state->mac_length;
1348 state->server_write_secret = state->key_block + 2 * state->mac_length + state->key_length;
1350 /* initialize cipher context */
1351 state->cipher_context = sipe_crypt_tls_start(state->client_write_secret,
1352 state->key_length);
1355 #if 0 /* NOT NEEDED? */
1356 /* signing */
1357 static guchar *tls_pkcs1_private_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1358 const guchar *data,
1359 gsize data_length,
1360 gsize buffer_length)
1362 gsize pad_length;
1363 guchar *pad_buffer;
1365 if (data_length + 3 > buffer_length) ||
1366 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */)
1367 return(NULL);
1369 pad_length = buffer_length - data_length - 3;
1370 pad_buffer = g_malloc(buffer_length);
1372 /* PKCS1 private key block padding */
1373 pad_buffer[0] = 0; /* +1 */
1374 pad_buffer[1] = 1; /* +2 */
1375 memset(pad_buffer + 2, 0xFF, pad_length);
1376 pad_buffer[2 + pad_length] = 0; /* +3 */
1377 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1379 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1380 debug_secrets(state, "tls_pkcs1_private_padding: ",
1381 pad_buffer, buffer_length);
1382 #endif
1384 return(pad_buffer);
1386 #endif
1388 /* encryption */
1389 static guchar *tls_pkcs1_public_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1390 const guchar *data,
1391 gsize data_length,
1392 gsize buffer_length)
1394 gsize pad_length, random_count;
1395 guchar *pad_buffer, *random;
1397 if ((data_length + 3 > buffer_length) ||
1398 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */
1399 return(NULL);
1401 pad_length = buffer_length - data_length - 3;
1402 pad_buffer = g_malloc(buffer_length);
1404 /* PKCS1 public key block padding */
1405 pad_buffer[0] = 0; /* +1 */
1406 pad_buffer[1] = 2; /* +2 */
1407 for (random = pad_buffer + 2, random_count = pad_length;
1408 random_count > 0;
1409 random_count--) {
1410 guchar byte;
1411 /* non-zero random byte */
1412 while ((byte = rand() & 0xFF) == 0);
1413 *random++ = byte;
1415 pad_buffer[2 + pad_length] = 0; /* +3 */
1416 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1418 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1419 debug_secrets(state, "tls_pkcs1_private_padding: ",
1420 pad_buffer, buffer_length);
1421 #endif
1423 return(pad_buffer);
1426 static struct tls_compiled_message *tls_client_key_exchange(struct tls_internal_state *state)
1428 struct tls_parsed_array *server_random;
1429 struct tls_parsed_array *server_certificate;
1430 struct ClientKeyExchange_host *exchange;
1431 gsize server_certificate_length;
1432 guchar *padded;
1433 struct tls_compiled_message *msg;
1435 /* check for required data fields */
1436 if (!check_cipher_suite(state))
1437 return(NULL);
1438 server_random = g_hash_table_lookup(state->data, "Random");
1439 if (!server_random) {
1440 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1441 return(NULL);
1443 server_certificate = g_hash_table_lookup(state->data, "Certificate");
1444 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1445 if (!server_certificate || (server_certificate->length < 3)) {
1446 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1447 return(FALSE);
1449 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT" bytes",
1450 server_certificate->length);
1451 /* first certificate is the server certificate */
1452 server_certificate_length = lowlevel_integer_to_host(server_certificate->data,
1454 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT" bytes",
1455 server_certificate_length);
1456 if ((server_certificate_length + 3) > server_certificate->length) {
1457 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1459 state->server_certificate = sipe_cert_crypto_import(server_certificate->data + 3,
1460 server_certificate_length);
1461 if (!state->server_certificate) {
1462 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1463 return(FALSE);
1465 /* server public key modulus length */
1466 server_certificate_length = sipe_cert_crypto_modulus_length(state->server_certificate);
1467 if (server_certificate_length < TLS_ARRAY_MASTER_SECRET_LENGTH) {
1468 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT ")",
1469 server_certificate_length);
1470 return(FALSE);
1472 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT,
1473 server_certificate_length);
1475 /* found all the required fields */
1476 state->server_random.length = server_random->length;
1477 state->server_random.buffer = g_memdup(server_random->data,
1478 server_random->length);
1479 tls_calculate_secrets(state);
1481 /* ClientKeyExchange */
1482 padded = tls_pkcs1_public_padding(state,
1483 state->pre_master_secret.buffer,
1484 state->pre_master_secret.length,
1485 server_certificate_length);
1486 if (!padded) {
1487 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: padding of pre-master secret failed");
1488 return(NULL);
1490 exchange = g_malloc0(sizeof(struct ClientKeyExchange_host) +
1491 server_certificate_length);
1492 exchange->secret.elements = server_certificate_length;
1493 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state->server_certificate),
1494 server_certificate_length,
1495 padded,
1496 (guchar *) exchange->secret.placeholder)) {
1497 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1498 g_free(exchange);
1499 g_free(padded);
1500 return(NULL);
1502 g_free(padded);
1504 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1505 debug_secrets(state, "tls_client_key_exchange: secret (encr) ",
1506 (guchar *) exchange->secret.placeholder,
1507 server_certificate_length);
1508 #endif
1510 msg = compile_handshake_msg(state, &ClientKeyExchange_m, exchange,
1511 sizeof(struct ClientKeyExchange_host) + server_certificate_length);
1512 g_free(exchange);
1514 return(msg);
1517 static struct tls_compiled_message *tls_certificate_verify(struct tls_internal_state *state)
1519 struct CertificateVerify_host *verify;
1520 struct tls_compiled_message *msg;
1521 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1522 guchar *signature;
1523 gsize length;
1525 /* calculate digests */
1526 sipe_digest_md5_end(state->md5_context, digests);
1527 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1529 /* sign digests */
1530 signature = sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state->certificate),
1531 digests,
1532 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1533 &length);
1534 g_free(digests);
1535 if (!signature) {
1536 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1537 return(NULL);
1540 /* CertificateVerify */
1541 verify = g_malloc0(sizeof(struct CertificateVerify_host) +
1542 length);
1543 verify->signature.elements = length;
1544 memcpy(verify->signature.placeholder, signature, length);
1545 g_free(signature);
1547 msg = compile_handshake_msg(state, &CertificateVerify_m, verify,
1548 sizeof(struct CertificateVerify_host) + length);
1549 g_free(verify);
1551 return(msg);
1554 static struct tls_compiled_message *tls_client_finished(struct tls_internal_state *state)
1556 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1557 guchar *verify;
1558 struct tls_compiled_message *cmsg;
1559 struct Finished_host msg;
1561 /* calculate digests */
1562 sipe_digest_md5_end(state->md5_context, digests);
1563 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1566 * verify_data = PRF(master_secret, "client finished",
1567 * MD5(handshake_messages) +
1568 * SHA-1(handshake_messages)) [0..11];
1570 verify = sipe_tls_prf(state,
1571 state->master_secret,
1572 TLS_ARRAY_MASTER_SECRET_LENGTH,
1573 (guchar *) "client finished",
1575 digests,
1576 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1577 TLS_ARRAY_VERIFY_LENGTH);
1578 g_free(digests);
1579 memcpy(msg.verify.verify, verify, TLS_ARRAY_VERIFY_LENGTH);
1580 g_free(verify);
1582 cmsg = compile_handshake_msg(state, &Finished_m, &msg, sizeof(msg));
1584 return(cmsg);
1588 * TLS state handling
1591 static gboolean tls_client_hello(struct tls_internal_state *state)
1593 guint32 now = time(NULL);
1594 guint32 now_N = GUINT32_TO_BE(now);
1595 struct ClientHello_host msg = {
1596 { TLS_PROTOCOL_VERSION_1_0 },
1597 { 0, { 0 } },
1598 { 0 /* empty SessionID */ },
1599 { 5,
1601 TLS_RSA_WITH_RC4_128_MD5,
1602 TLS_RSA_WITH_RC4_128_SHA,
1603 TLS_RSA_WITH_AES_128_CBC_SHA,
1604 TLS_RSA_WITH_AES_256_CBC_SHA,
1605 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1608 { 1,
1610 TLS_COMP_METHOD_NULL
1614 struct tls_compiled_message *cmsg;
1616 /* First 4 bytes of client_random is the current timestamp */
1617 sipe_tls_fill_random(&state->client_random,
1618 TLS_ARRAY_RANDOM_LENGTH * 8); /* -> bits */
1619 memcpy(state->client_random.buffer, &now_N, sizeof(now_N));
1620 memcpy(msg.random.random, state->client_random.buffer,
1621 TLS_ARRAY_RANDOM_LENGTH);
1623 cmsg = compile_handshake_msg(state, &ClientHello_m, &msg, sizeof(msg));
1624 compile_tls_record(state, cmsg, NULL);
1625 g_free(cmsg);
1627 if (sipe_backend_debug_enabled())
1628 state->debug = g_string_new("");
1630 state->state = TLS_HANDSHAKE_STATE_SERVER_HELLO;
1631 return(tls_record_parse(state, FALSE, 0));
1634 static gboolean tls_server_hello(struct tls_internal_state *state)
1636 struct tls_compiled_message *certificate = NULL;
1637 struct tls_compiled_message *exchange = NULL;
1638 struct tls_compiled_message *verify = NULL;
1639 struct tls_compiled_message *finished = NULL;
1640 gboolean success = FALSE;
1642 if (!tls_record_parse(state, TRUE, TLS_HANDSHAKE_TYPE_SERVER_HELLO))
1643 return(FALSE);
1645 if (((certificate = tls_client_certificate(state)) != NULL) &&
1646 ((exchange = tls_client_key_exchange(state)) != NULL) &&
1647 ((verify = tls_certificate_verify(state)) != NULL) &&
1648 ((finished = tls_client_finished(state)) != NULL)) {
1650 /* Part 1 */
1651 compile_tls_record(state, certificate, exchange, verify, NULL);
1653 success = tls_record_parse(state, FALSE, 0);
1654 if (success) {
1655 guchar *part1 = state->common.out_buffer;
1656 gsize part1_length = state->common.out_length;
1657 guchar *part3;
1658 gsize part3_length;
1659 guchar *merged;
1660 gsize length;
1661 /* ChangeCipherSpec is always the same */
1662 static const guchar part2[] = {
1663 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC,
1664 (TLS_PROTOCOL_VERSION_1_0 >> 8) & 0xFF,
1665 TLS_PROTOCOL_VERSION_1_0 & 0xFF,
1666 0x00, 0x01, /* length: 1 byte */
1667 0x01 /* change_cipher_spec(1) */
1670 state->common.out_buffer = NULL;
1672 /* Part 3 - this is the first encrypted record */
1673 compile_encrypted_tls_record(state, finished);
1674 part3 = state->common.out_buffer;
1675 part3_length = state->common.out_length;
1677 /* merge TLS records */
1678 length = part1_length + sizeof(part2) + part3_length;
1679 merged = g_malloc(length);
1681 memcpy(merged, part1, part1_length);
1682 memcpy(merged + part1_length, part2, sizeof(part2));
1683 memcpy(merged + part1_length + sizeof(part2), part3, part3_length);
1684 g_free(part3);
1685 g_free(part1);
1687 /* replace output buffer with merged message */
1688 state->common.out_buffer = merged;
1689 state->common.out_length = length;
1691 state->state = TLS_HANDSHAKE_STATE_FINISHED;
1695 g_free(finished);
1696 g_free(verify);
1697 g_free(exchange);
1698 g_free(certificate);
1699 free_parse_data(state);
1701 return(success);
1704 static gboolean tls_finished(struct tls_internal_state *state)
1706 guchar *random;
1708 if (!tls_record_parse(state, TRUE, TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC))
1709 return(FALSE);
1711 /* we don't need the data */
1712 free_parse_data(state);
1715 * Calculate session keys [MS-SIPAE section 3.2.5.1]
1717 * key_material = PRF (master_secret,
1718 * "client EAP encryption",
1719 * ClientHello.random + ServerHello.random)[128]
1720 * = 4 x 32 Bytes
1722 * client key = key_material[3rd 32 Bytes]
1723 * server key = key_material[4th 32 Bytes]
1725 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1726 memcpy(random,
1727 state->client_random.buffer,
1728 TLS_ARRAY_RANDOM_LENGTH);
1729 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1730 state->server_random.buffer,
1731 TLS_ARRAY_RANDOM_LENGTH);
1732 state->tls_dsk_key_block = sipe_tls_prf(state,
1733 state->master_secret,
1734 TLS_ARRAY_MASTER_SECRET_LENGTH,
1735 (guchar *) "client EAP encryption",
1737 random,
1738 TLS_ARRAY_RANDOM_LENGTH * 2,
1739 4 * 32);
1740 g_free(random);
1742 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1743 debug_secrets(state, "tls_finished: TLS-DSK key block ",
1744 state->tls_dsk_key_block, 4 * 32);
1745 #endif
1747 state->common.client_key = state->tls_dsk_key_block + 2 * 32;
1748 state->common.server_key = state->tls_dsk_key_block + 3 * 32;
1749 state->common.key_length = 32;
1751 debug_secrets(state, "tls_finished: TLS-DSK client key ",
1752 state->common.client_key,
1753 state->common.key_length);
1754 debug_secrets(state, "tls_finished: TLS-DSK server key ",
1755 state->common.server_key,
1756 state->common.key_length);
1758 state->common.out_buffer = NULL;
1759 state->common.out_length = 0;
1760 state->state = TLS_HANDSHAKE_STATE_COMPLETED;
1762 return(TRUE);
1766 * TLS public API
1769 struct sipe_tls_state *sipe_tls_start(gpointer certificate)
1771 struct tls_internal_state *state;
1773 if (!certificate)
1774 return(NULL);
1776 state = g_new0(struct tls_internal_state, 1);
1777 state->certificate = certificate;
1778 state->state = TLS_HANDSHAKE_STATE_START;
1779 state->md5_context = sipe_digest_md5_start();
1780 state->sha1_context = sipe_digest_sha1_start();
1781 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_NONE;
1783 return((struct sipe_tls_state *) state);
1786 gboolean sipe_tls_next(struct sipe_tls_state *state)
1788 /* Avoid "cast increases required alignment" errors */
1789 struct tls_internal_state *internal = (void *) state;
1790 gboolean success = FALSE;
1792 if (!state)
1793 return(FALSE);
1795 state->out_buffer = NULL;
1797 switch (internal->state) {
1798 case TLS_HANDSHAKE_STATE_START:
1799 success = tls_client_hello(internal);
1800 break;
1802 case TLS_HANDSHAKE_STATE_SERVER_HELLO:
1803 success = tls_server_hello(internal);
1804 break;
1806 case TLS_HANDSHAKE_STATE_FINISHED:
1807 success = tls_finished(internal);
1808 break;
1810 case TLS_HANDSHAKE_STATE_COMPLETED:
1811 case TLS_HANDSHAKE_STATE_FAILED:
1812 /* This should not happen */
1813 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1814 break;
1817 if (!success) {
1818 internal->state = TLS_HANDSHAKE_STATE_FAILED;
1821 return(success);
1824 guint sipe_tls_expires(struct sipe_tls_state *state)
1826 /* Avoid "cast increases required alignment" errors */
1827 struct tls_internal_state *internal = (void *) state;
1829 if (!state)
1830 return(0);
1832 return(sipe_cert_crypto_expires(internal->certificate));
1835 void sipe_tls_free(struct sipe_tls_state *state)
1837 if (state) {
1838 /* Avoid "cast increases required alignment" errors */
1839 struct tls_internal_state *internal = (void *) state;
1841 free_parse_data(internal);
1842 if (internal->debug)
1843 g_string_free(internal->debug, TRUE);
1844 g_free(internal->tls_dsk_key_block);
1845 g_free(internal->key_block);
1846 g_free(internal->master_secret);
1847 sipe_tls_free_random(&internal->pre_master_secret);
1848 sipe_tls_free_random(&internal->client_random);
1849 sipe_tls_free_random(&internal->server_random);
1850 if (internal->cipher_context)
1851 sipe_crypt_tls_destroy(internal->cipher_context);
1852 if (internal->md5_context)
1853 sipe_digest_md5_destroy(internal->md5_context);
1854 if (internal->sha1_context)
1855 sipe_digest_sha1_destroy(internal->sha1_context);
1856 sipe_cert_crypto_destroy(internal->server_certificate);
1857 g_free(state->out_buffer);
1858 g_free(state);
1862 #endif /* !_SIPE_COMPILING_ANALYZER */
1865 Local Variables:
1866 mode: c
1867 c-file-style: "bsd"
1868 indent-tabs-mode: t
1869 tab-width: 8
1870 End: