adium: clean up paths in xcconfigs
[siplcs.git] / src / core / sipe-tls.c
blobb0235d50e713ba41904a41aec54863c7e9549097
1 /**
2 * @file sipe-tls.c
4 * pidgin-sipe
6 * Copyright (C) 2011-2016 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
34 * - RFC5246: http://www.ietf.org/rfc/rfc5246.txt
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdarg.h>
41 #include <glib.h>
43 #include "sipe-common.h"
44 #include "sipe-backend.h"
45 #include "sipe-cert-crypto.h"
46 #include "sipe-crypt.h"
47 #include "sipe-digest.h"
48 #include "sipe-svc.h"
49 #include "sipe-tls.h"
52 * Private part of TLS state tracking
54 enum tls_handshake_state {
55 TLS_HANDSHAKE_STATE_START,
56 TLS_HANDSHAKE_STATE_SERVER_HELLO,
57 TLS_HANDSHAKE_STATE_FINISHED,
58 TLS_HANDSHAKE_STATE_COMPLETED,
59 TLS_HANDSHAKE_STATE_FAILED
62 struct tls_internal_state {
63 struct sipe_tls_state common;
64 gpointer certificate;
65 enum tls_handshake_state state;
66 guchar *msg_current;
67 gsize msg_remainder;
68 GHashTable *data;
69 GString *debug;
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 const guchar *client_write_iv;
86 const guchar *server_write_iv;
87 void (*mac_func)(const guchar *key, gsize key_length,
88 const guchar *data, gsize data_length,
89 guchar *digest);
90 gpointer cipher_context;
91 guint64 sequence_number;
92 gboolean stream_cipher;
93 gboolean encrypted;
94 gboolean expected;
98 * TLS messages & layout descriptors
101 /* constants */
102 #define TLS_VECTOR_MAX8 255 /* 2^8 - 1 */
103 #define TLS_VECTOR_MAX16 65535 /* 2^16 - 1 */
104 #define TLS_VECTOR_MAX24 16777215 /* 2^24 - 1 */
106 #define TLS_PROTOCOL_VERSION_1_0 0x0301
107 #define TLS_PROTOCOL_VERSION_1_1 0x0302
108 #define TLS_PROTOCOL_VERSION_1_2 0x0303
110 /* CipherSuites */
111 #define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
112 #define TLS_RSA_WITH_RC4_128_MD5 0x0004
113 #define TLS_RSA_WITH_RC4_128_SHA 0x0005
114 #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
115 #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035
117 #define TLS_AES_CBC_BLOCK_LENGTH 16 /* bytes */
119 /* CompressionMethods */
120 #define TLS_COMP_METHOD_NULL 0
122 /* various array lengths */
123 #define TLS_ARRAY_RANDOM_LENGTH 32
124 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
125 #define TLS_ARRAY_VERIFY_LENGTH 12
127 #define TLS_RECORD_HEADER_LENGTH 5
128 #define TLS_RECORD_OFFSET_TYPE 0
129 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
130 #define TLS_RECORD_TYPE_HANDSHAKE 22
131 #define TLS_RECORD_OFFSET_VERSION 1
132 #define TLS_RECORD_OFFSET_LENGTH 3
134 #define TLS_HANDSHAKE_HEADER_LENGTH 4
135 #define TLS_HANDSHAKE_OFFSET_TYPE 0
136 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
137 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
138 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
139 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
140 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
141 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
142 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
143 #define TLS_HANDSHAKE_TYPE_FINISHED 20
144 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
146 struct layout_descriptor;
147 typedef gboolean parse_func(struct tls_internal_state *state,
148 const struct layout_descriptor *desc);
150 /* Defines the strictest alignment requirement */
151 struct tls_compile_integer;
152 typedef void compile_func(struct tls_internal_state *state,
153 const struct layout_descriptor *desc,
154 const struct tls_compile_integer *data);
156 struct layout_descriptor {
157 const gchar *label;
158 parse_func *parser;
159 compile_func *compiler;
160 gsize min; /* 0 for fixed/array */
161 gsize max;
162 gsize offset;
165 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
166 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
168 struct msg_descriptor {
169 const struct msg_descriptor *next;
170 const gchar *description;
171 const struct layout_descriptor *layouts;
172 guint type;
175 /* parsed data */
176 struct tls_parsed_integer {
177 guint value;
180 struct tls_parsed_array {
181 gsize length; /* bytes */
182 const guchar data[0];
185 /* compile data */
186 struct tls_compile_integer {
187 gsize value;
190 struct tls_compile_array {
191 gsize elements; /* unused */
192 guchar placeholder[];
195 struct tls_compile_random {
196 gsize elements; /* unused */
197 guchar random[TLS_ARRAY_RANDOM_LENGTH];
200 struct tls_compile_verify {
201 gsize elements; /* unused */
202 guchar verify[TLS_ARRAY_VERIFY_LENGTH];
205 struct tls_compile_vector {
206 gsize elements; /* VECTOR */
207 guint placeholder[];
210 struct tls_compile_sessionid {
211 gsize elements; /* VECTOR */
214 struct tls_compile_cipher {
215 gsize elements; /* VECTOR */
216 guint suites[5];
219 struct tls_compile_compression {
220 gsize elements; /* VECTOR */
221 guint methods[1];
224 /* compiled message */
225 struct tls_compiled_message {
226 gsize size;
227 guchar data[];
231 * Random byte buffers
233 void sipe_tls_fill_random(struct sipe_tls_random *random,
234 guint bits)
236 guint bytes = ((bits + 15) / 16) * 2;
237 guint16 *p = g_malloc(bytes);
239 SIPE_DEBUG_INFO("sipe_tls_fill_random: %d bits -> %d bytes",
240 bits, bytes);
242 random->buffer = (guint8*) p;
243 random->length = bytes;
245 for (bytes /= 2; bytes; bytes--)
246 *p++ = rand() & 0xFFFF;
249 void sipe_tls_free_random(struct sipe_tls_random *random)
251 g_free(random->buffer);
255 * TLS message debugging
257 static void debug_hex(struct tls_internal_state *state,
258 gsize alternative_length)
260 GString *str = state->debug;
261 const guchar *bytes;
262 gsize length;
263 gint count;
265 if (!str) return;
267 bytes = state->msg_current;
268 length = alternative_length ? alternative_length : state->msg_remainder;
269 count = -1;
271 while (length-- > 0) {
272 if (++count == 0) {
273 /* do nothing */;
274 } else if ((count % 16) == 0) {
275 g_string_append(str, "\n");
276 } else if ((count % 8) == 0) {
277 g_string_append(str, " ");
279 g_string_append_printf(str, " %02X", *bytes++);
281 g_string_append(str, "\n");
284 #define debug_print(state, string) \
285 if (state->debug) g_string_append(state->debug, string)
286 #define debug_printf(state, format, ...) \
287 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
289 /* Analyzer only needs the debugging functions */
290 #ifndef _SIPE_COMPILING_ANALYZER
292 static void debug_secrets(struct tls_internal_state *state,
293 const gchar *label,
294 const guchar *secret,
295 gsize secret_length)
297 if (state->debug && secret) {
298 g_string_append_printf(state->debug, "%s (%3" G_GSIZE_FORMAT ") = ",
299 label, secret_length);
300 while (secret_length--)
301 g_string_append_printf(state->debug, "%02X", *secret++);
302 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
303 g_string_truncate(state->debug, 0);
308 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
310 static guchar *sipe_tls_p_md5(const guchar *secret,
311 gsize secret_length,
312 const guchar *seed,
313 gsize seed_length,
314 gsize output_length)
316 guchar *output = NULL;
319 * output_length == 0 -> illegal
320 * output_length == 1..16 -> iterations = 1
321 * output_length == 17..32 -> iterations = 2
323 if (secret && seed && (output_length > 0)) {
324 guint iterations = (output_length + SIPE_DIGEST_HMAC_MD5_LENGTH - 1) / SIPE_DIGEST_HMAC_MD5_LENGTH;
325 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length);
326 guchar A[SIPE_DIGEST_HMAC_MD5_LENGTH];
327 guchar *p;
329 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
330 secret_length, seed_length);
331 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
332 output_length, iterations);
334 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
335 sipe_digest_hmac_md5(secret, secret_length,
336 seed, seed_length,
339 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
340 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_MD5_LENGTH);
342 while (iterations-- > 0) {
343 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
344 guchar P[SIPE_DIGEST_HMAC_MD5_LENGTH];
345 memcpy(concat, A, SIPE_DIGEST_HMAC_MD5_LENGTH);
346 memcpy(concat + SIPE_DIGEST_HMAC_MD5_LENGTH, seed, seed_length);
347 sipe_digest_hmac_md5(secret, secret_length,
348 concat, SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length,
350 memcpy(p, P, SIPE_DIGEST_HMAC_MD5_LENGTH);
351 p += SIPE_DIGEST_HMAC_MD5_LENGTH;
353 /* A(i+1) = HMAC_MD5(secret, A(i)) */
354 sipe_digest_hmac_md5(secret, secret_length,
355 A, SIPE_DIGEST_HMAC_MD5_LENGTH,
358 g_free(concat);
361 return(output);
364 guchar *sipe_tls_p_sha1(const guchar *secret,
365 gsize secret_length,
366 const guchar *seed,
367 gsize seed_length,
368 gsize output_length)
370 guchar *output = NULL;
373 * output_length == 0 -> illegal
374 * output_length == 1..20 -> iterations = 1
375 * output_length == 21..40 -> iterations = 2
377 if (secret && seed && (output_length > 0)) {
378 guint iterations = (output_length + SIPE_DIGEST_HMAC_SHA1_LENGTH - 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH;
379 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length);
380 guchar A[SIPE_DIGEST_HMAC_SHA1_LENGTH];
381 guchar *p;
383 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
384 secret_length, seed_length);
385 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
386 output_length, iterations);
388 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
389 sipe_digest_hmac_sha1(secret, secret_length,
390 seed, seed_length,
393 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
394 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_SHA1_LENGTH);
396 while (iterations-- > 0) {
397 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
398 guchar P[SIPE_DIGEST_HMAC_SHA1_LENGTH];
399 memcpy(concat, A, SIPE_DIGEST_HMAC_SHA1_LENGTH);
400 memcpy(concat + SIPE_DIGEST_HMAC_SHA1_LENGTH, seed, seed_length);
401 sipe_digest_hmac_sha1(secret, secret_length,
402 concat, SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length,
404 memcpy(p, P, SIPE_DIGEST_HMAC_SHA1_LENGTH);
405 p += SIPE_DIGEST_HMAC_SHA1_LENGTH;
407 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
408 sipe_digest_hmac_sha1(secret, secret_length,
409 A, SIPE_DIGEST_HMAC_SHA1_LENGTH,
412 g_free(concat);
415 return(output);
418 static guchar *sipe_tls_prf(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
419 const guchar *secret,
420 gsize secret_length,
421 const guchar *label,
422 gsize label_length,
423 const guchar *seed,
424 gsize seed_length,
425 gsize output_length)
427 gsize half = (secret_length + 1) / 2;
428 gsize newseed_length = label_length + seed_length;
429 /* secret: used as S1; secret2: last half of original secret (S2) */
430 guchar *secret2 = g_memdup(secret + secret_length - half, half);
431 guchar *newseed = g_malloc(newseed_length);
432 guchar *md5, *dest;
433 guchar *sha1, *src;
434 gsize count;
436 /* make Coverity happy - lengths could be 0 */
437 if (!secret2 || !newseed) {
438 g_free(secret2);
439 g_free(newseed);
440 return(NULL);
444 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
445 * P_SHA-1(S2, label + seed);
447 memcpy(newseed, label, label_length);
448 memcpy(newseed + label_length, seed, seed_length);
449 #undef __SIPE_TLS_CRYPTO_DEBUG
450 #ifdef __SIPE_TLS_CRYPTO_DEBUG
451 debug_secrets(state, "sipe_tls_prf: secret ",
452 secret, secret_length);
453 debug_secrets(state, "sipe_tls_prf: combined seed ",
454 newseed, newseed_length);
455 SIPE_DEBUG_INFO("total seed length %" G_GSIZE_FORMAT,
456 newseed_length);
457 debug_secrets(state, "sipe_tls_prf: S1 ",
458 secret, half);
459 debug_secrets(state, "sipe_tls_prf: S2 ",
460 secret2, half);
461 #endif
462 md5 = sipe_tls_p_md5(secret, half, newseed, newseed_length, output_length);
463 sha1 = sipe_tls_p_sha1(secret2, half, newseed, newseed_length, output_length);
464 #ifdef __SIPE_TLS_CRYPTO_DEBUG
465 debug_secrets(state, "sipe_tls_prf: P_md5() ",
466 md5, output_length);
467 debug_secrets(state, "sipe_tls_prf: P_sha1() ",
468 sha1, output_length);
469 #endif
470 for (dest = md5, src = sha1, count = output_length;
471 count > 0;
472 count--)
473 *dest++ ^= *src++;
475 g_free(sha1);
476 g_free(newseed);
477 g_free(secret2);
479 #ifdef __SIPE_TLS_CRYPTO_DEBUG
480 debug_secrets(state, "sipe_tls_prf: PRF() ",
481 md5, output_length);
482 #endif
484 return(md5);
487 #endif /* !_SIPE_COMPILING_ANALYZER */
490 * TLS data parsers
492 * Low-level data conversion routines
494 * - host alignment agnostic, i.e. can fetch a word from uneven address
495 * - TLS -> host endianess conversion
496 * - no length check, caller has to do it
497 * - don't modify state
499 static guint lowlevel_integer_to_host(const guchar *bytes,
500 gsize length)
502 guint sum = 0;
503 while (length--) sum = (sum << 8) + *bytes++;
504 return(sum);
508 * Generic data type parser routines
510 static gboolean msg_remainder_check(struct tls_internal_state *state,
511 const gchar *label,
512 gsize length)
514 if (length > state->msg_remainder) {
515 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT,
516 label, length, state->msg_remainder);
517 return(FALSE);
519 return(TRUE);
522 static gboolean parse_integer_quiet(struct tls_internal_state *state,
523 const gchar *label,
524 gsize length,
525 guint *result)
527 if (!msg_remainder_check(state, label, length)) return(FALSE);
528 *result = lowlevel_integer_to_host(state->msg_current, length);
529 state->msg_current += length;
530 state->msg_remainder -= length;
531 return(TRUE);
534 static gboolean parse_integer(struct tls_internal_state *state,
535 const struct layout_descriptor *desc)
537 guint value;
538 if (!parse_integer_quiet(state, desc->label, desc->max, &value))
539 return(FALSE);
540 debug_printf(state, "%s/INTEGER%" G_GSIZE_FORMAT " = %d\n",
541 desc->label, desc->max, value);
542 if (state->data) {
543 struct tls_parsed_integer *save = g_new0(struct tls_parsed_integer, 1);
544 save->value = value;
545 g_hash_table_insert(state->data, (gpointer) desc->label, save);
547 return(TRUE);
550 static gboolean parse_array(struct tls_internal_state *state,
551 const struct layout_descriptor *desc)
553 if (!msg_remainder_check(state, desc->label, desc->max))
554 return(FALSE);
555 debug_printf(state, "%s/ARRAY[%" G_GSIZE_FORMAT "]\n",
556 desc->label, desc->max);
557 #ifdef _SIPE_COMPILING_ANALYZER
558 if (desc->max)
559 debug_hex(state, desc->max);
560 #endif
561 if (state->data) {
562 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
563 desc->max);
564 save->length = desc->max;
565 memcpy((guchar *)save->data, state->msg_current, desc->max);
566 g_hash_table_insert(state->data, (gpointer) desc->label, save);
569 state->msg_current += desc->max;
570 state->msg_remainder -= desc->max;
571 return(TRUE);
574 static gboolean parse_vector(struct tls_internal_state *state,
575 const struct layout_descriptor *desc)
577 guint length;
578 if (!parse_integer_quiet(state, desc->label,
579 (desc->max > TLS_VECTOR_MAX16) ? 3 :
580 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1,
581 &length))
582 return(FALSE);
583 if (length < desc->min) {
584 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT,
585 desc->label, length, desc->min);
586 return(FALSE);
588 debug_printf(state, "%s/VECTOR<%d>\n", desc->label, length);
589 #ifdef _SIPE_COMPILING_ANALYZER
590 if (length)
591 debug_hex(state, length);
592 #endif
593 if (state->data) {
594 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
595 length);
596 save->length = length;
597 memcpy((guchar *)save->data, state->msg_current, length);
598 g_hash_table_insert(state->data, (gpointer) desc->label, save);
600 state->msg_current += length;
601 state->msg_remainder -= length;
602 return(TRUE);
606 * Specific data type parser routines
609 /* TBD... */
612 * TLS data compilers
614 * Low-level data conversion routines
616 * - host alignment agnostic, i.e. can fetch a word from uneven address
617 * - host -> TLS host endianess conversion
618 * - don't modify state
620 static void lowlevel_integer_to_tls(guchar *bytes,
621 gsize length,
622 guint value)
624 while (length--) {
625 bytes[length] = value & 0xFF;
626 value >>= 8;
631 * Generic data type compiler routines
633 static void compile_integer(struct tls_internal_state *state,
634 const struct layout_descriptor *desc,
635 const struct tls_compile_integer *data)
637 lowlevel_integer_to_tls(state->msg_current, desc->max, data->value);
638 state->msg_current += desc->max;
641 static void compile_array(struct tls_internal_state *state,
642 const struct layout_descriptor *desc,
643 const struct tls_compile_integer *data)
645 const struct tls_compile_array *array = (struct tls_compile_array *) data;
646 memcpy(state->msg_current, array->placeholder, desc->max);
647 state->msg_current += desc->max;
650 static void compile_vector(struct tls_internal_state *state,
651 const struct layout_descriptor *desc,
652 const struct tls_compile_integer *data)
654 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
655 gsize length = vector->elements;
656 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
657 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
659 lowlevel_integer_to_tls(state->msg_current, length_field, length);
660 state->msg_current += length_field;
661 memcpy(state->msg_current, vector->placeholder, length);
662 state->msg_current += length;
665 static void compile_vector_int2(struct tls_internal_state *state,
666 const struct layout_descriptor *desc,
667 const struct tls_compile_integer *data)
669 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
670 gsize elements = vector->elements;
671 gsize length = elements * sizeof(guint16);
672 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
673 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
674 const guint *p = vector->placeholder;
676 lowlevel_integer_to_tls(state->msg_current, length_field, length);
677 state->msg_current += length_field;
678 while (elements--) {
679 lowlevel_integer_to_tls(state->msg_current, sizeof(guint16), *p++);
680 state->msg_current += sizeof(guint16);
685 * Specific data type compiler routines
688 /* TBD... */
691 * TLS handshake message layout descriptors
693 struct ClientHello_host {
694 struct tls_compile_integer protocol_version;
695 struct tls_compile_random random;
696 struct tls_compile_sessionid sessionid;
697 struct tls_compile_cipher cipher;
698 struct tls_compile_compression compression;
700 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
702 static const struct layout_descriptor ClientHello_l[] = {
703 { "Client Protocol Version", parse_integer, compile_integer, 0, 2, CLIENTHELLO_OFFSET(protocol_version) },
704 { "Random", parse_array, compile_array, 0, TLS_ARRAY_RANDOM_LENGTH, CLIENTHELLO_OFFSET(random) },
705 { "SessionID", parse_vector, compile_vector, 0, 32, CLIENTHELLO_OFFSET(sessionid) },
706 { "CipherSuite", parse_vector, compile_vector_int2, 2, TLS_VECTOR_MAX16, CLIENTHELLO_OFFSET(cipher)},
707 { "CompressionMethod", parse_vector, compile_vector, 1, TLS_VECTOR_MAX8, CLIENTHELLO_OFFSET(compression) },
708 TLS_LAYOUT_DESCRIPTOR_END
710 static const struct msg_descriptor ClientHello_m = {
711 NULL, "Client Hello", ClientHello_l, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
714 static const struct layout_descriptor ServerHello_l[] = {
715 { "Server Protocol Version", parse_integer, NULL, 0, 2, 0 },
716 { "Random", parse_array, NULL, 0, TLS_ARRAY_RANDOM_LENGTH, 0 },
717 { "SessionID", parse_vector, NULL, 0, 32, 0 },
718 { "CipherSuite", parse_integer, NULL, 0, 2, 0 },
719 { "CompressionMethod", parse_integer, NULL, 0, 1, 0 },
720 TLS_LAYOUT_DESCRIPTOR_END
722 static const struct msg_descriptor ServerHello_m = {
723 &ClientHello_m, "Server Hello", ServerHello_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO
726 struct Certificate_host {
727 struct tls_compile_vector certificate;
729 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
731 static const struct layout_descriptor Certificate_l[] = {
732 { "Certificate", parse_vector, compile_vector, 0, TLS_VECTOR_MAX24, CERTIFICATE_OFFSET(certificate) },
733 TLS_LAYOUT_DESCRIPTOR_END
735 static const struct msg_descriptor Certificate_m = {
736 &ServerHello_m, "Certificate", Certificate_l, TLS_HANDSHAKE_TYPE_CERTIFICATE
739 static const struct layout_descriptor CertificateRequest_l[] = {
740 { "CertificateType", parse_vector, NULL, 1, TLS_VECTOR_MAX8, 0 },
741 { "DistinguishedName", parse_vector, NULL, 0, TLS_VECTOR_MAX16, 0 },
742 TLS_LAYOUT_DESCRIPTOR_END
744 static const struct msg_descriptor CertificateRequest_m = {
745 &Certificate_m, "Certificate Request", CertificateRequest_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
748 static const struct layout_descriptor ServerHelloDone_l[] = {
749 TLS_LAYOUT_DESCRIPTOR_END
751 static const struct msg_descriptor ServerHelloDone_m = {
752 &CertificateRequest_m, "Server Hello Done", ServerHelloDone_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
755 struct ClientKeyExchange_host {
756 struct tls_compile_vector secret;
758 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
760 static const struct layout_descriptor ClientKeyExchange_l[] = {
761 { "Exchange Keys", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CLIENTKEYEXCHANGE_OFFSET(secret) },
762 TLS_LAYOUT_DESCRIPTOR_END
764 static const struct msg_descriptor ClientKeyExchange_m = {
765 &ServerHelloDone_m, "Client Key Exchange", ClientKeyExchange_l, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
768 struct CertificateVerify_host {
769 struct tls_compile_vector signature;
771 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
773 static const struct layout_descriptor CertificateVerify_l[] = {
774 { "Signature", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CERTIFICATEVERIFY_OFFSET(signature) },
775 TLS_LAYOUT_DESCRIPTOR_END
777 static const struct msg_descriptor CertificateVerify_m = {
778 &ClientKeyExchange_m, "Certificate Verify", CertificateVerify_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
781 struct Finished_host {
782 struct tls_compile_verify verify;
784 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
786 static const struct layout_descriptor Finished_l[] = {
787 { "Verify Data", parse_array, compile_array, 0, TLS_ARRAY_VERIFY_LENGTH, FINISHED_OFFSET(verify) },
788 TLS_LAYOUT_DESCRIPTOR_END
790 static const struct msg_descriptor Finished_m = {
791 &CertificateVerify_m, "Finished", Finished_l, TLS_HANDSHAKE_TYPE_FINISHED
794 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
797 * TLS message parsers
799 static gboolean handshake_parse(struct tls_internal_state *state,
800 guint expected_type)
802 const guchar *bytes = state->msg_current;
803 gsize length = state->msg_remainder;
804 gboolean success = FALSE;
806 while (length > 0) {
807 const struct msg_descriptor *desc;
808 gsize msg_length;
809 guint msg_type;
811 /* header check */
812 if (length < TLS_HANDSHAKE_HEADER_LENGTH) {
813 debug_print(state, "CORRUPTED HANDSHAKE HEADER");
814 break;
817 /* msg length check */
818 msg_length = lowlevel_integer_to_host(bytes + TLS_HANDSHAKE_OFFSET_LENGTH,
820 if (msg_length > length) {
821 debug_print(state, "HANDSHAKE MESSAGE TOO LONG");
822 break;
825 /* msg type */
826 msg_type = bytes[TLS_HANDSHAKE_OFFSET_TYPE];
827 for (desc = HANDSHAKE_MSG_DESCRIPTORS;
828 desc;
829 desc = desc->next)
830 if (msg_type == desc->type)
831 break;
833 debug_printf(state, "TLS handshake (%" G_GSIZE_FORMAT " bytes) (%d)",
834 msg_length, msg_type);
836 if (msg_type == expected_type)
837 state->expected = TRUE;
839 state->msg_current = (guchar *) bytes + TLS_HANDSHAKE_HEADER_LENGTH;
840 state->msg_remainder = msg_length;
842 if (desc && desc->layouts) {
843 const struct layout_descriptor *ldesc = desc->layouts;
845 debug_printf(state, "%s\n", desc->description);
847 while (TLS_LAYOUT_IS_VALID(ldesc)) {
848 success = ldesc->parser(state, ldesc);
849 if (!success)
850 break;
851 ldesc++;
853 if (!success)
854 break;
855 } else {
856 debug_print(state, "ignored\n");
857 debug_hex(state, 0);
860 /* next message */
861 bytes += TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
862 length -= TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
863 if (length > 0) {
864 debug_print(state, "------\n");
865 } else {
866 success = TRUE;
870 return(success);
873 static void free_parse_data(struct tls_internal_state *state)
875 if (state->data) {
876 g_hash_table_destroy(state->data);
877 state->data = NULL;
881 static gboolean tls_record_parse(struct tls_internal_state *state,
882 gboolean incoming,
883 guint expected)
885 const guchar *bytes = incoming ? state->common.in_buffer : state->common.out_buffer;
886 gsize length = incoming ? state->common.in_length : state->common.out_length;
887 guint version;
888 const gchar *version_str;
889 gsize record_length;
890 gboolean success = TRUE;
892 /* reject empty incoming messages */
893 if (incoming && (length == 0)) {
894 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: empty TLS message received");
895 return(FALSE);
898 #ifndef _SIPE_COMPILING_ANALYZER
899 debug_printf(state, "TLS MESSAGE %s\n", incoming ? "INCOMING" : "OUTGOING");
900 #endif
902 /* Collect parser data for incoming messages */
903 if (incoming)
904 state->data = g_hash_table_new_full(g_str_hash, g_str_equal,
905 NULL, g_free);
907 state->expected = FALSE;
908 while (success && (length > 0)) {
910 /* truncated header check */
911 if (length < TLS_RECORD_HEADER_LENGTH) {
912 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT " bytes)",
913 length);
914 success = FALSE;
915 break;
918 /* protocol version check */
919 version = lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_VERSION, 2);
920 if (version < TLS_PROTOCOL_VERSION_1_0) {
921 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
922 success = FALSE;
923 break;
925 switch (version) {
926 case TLS_PROTOCOL_VERSION_1_0:
927 version_str = "1.0 (RFC2246)";
928 break;
929 case TLS_PROTOCOL_VERSION_1_1:
930 version_str = "1.1 (RFC4346)";
931 break;
932 case TLS_PROTOCOL_VERSION_1_2:
933 version_str = "1.2 (RFC5246)";
934 break;
935 default:
936 version_str = "<future protocol version>";
937 break;
940 /* record length check */
941 record_length = TLS_RECORD_HEADER_LENGTH +
942 lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_LENGTH, 2);
943 if (record_length > length) {
944 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
945 success = FALSE;
946 break;
949 /* TLS record header OK */
950 debug_printf(state, "TLS %s record (%" G_GSIZE_FORMAT " bytes)\n",
951 version_str, record_length);
952 state->msg_current = (guchar *) bytes + TLS_RECORD_HEADER_LENGTH;
953 state->msg_remainder = record_length - TLS_RECORD_HEADER_LENGTH;
955 /* Analyzer only needs the debugging functions */
956 #ifndef _SIPE_COMPILING_ANALYZER
957 /* Add incoming message contents to digest contexts */
958 if (incoming) {
959 sipe_digest_md5_update(state->md5_context,
960 state->msg_current,
961 state->msg_remainder);
962 sipe_digest_sha1_update(state->sha1_context,
963 state->msg_current,
964 state->msg_remainder);
966 #endif /* !_SIPE_COMPILING_ANALYZER */
968 switch (bytes[TLS_RECORD_OFFSET_TYPE]) {
969 case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:
970 debug_print(state, "Change Cipher Spec\n");
971 if (incoming)
972 state->encrypted = TRUE;
973 if (expected == TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC)
974 state->expected = TRUE;
975 break;
977 case TLS_RECORD_TYPE_HANDSHAKE:
978 if (incoming && state->encrypted) {
979 debug_print(state, "Encrypted handshake message\n");
980 debug_hex(state, 0);
981 } else {
982 success = handshake_parse(state, expected);
984 break;
986 default:
987 debug_print(state, "Unsupported TLS message\n");
988 debug_hex(state, 0);
989 break;
992 /* next fragment */
993 bytes += record_length;
994 length -= record_length;
997 #ifndef _SIPE_COMPILING_ANALYZER
998 if (incoming && !state->expected) {
999 SIPE_DEBUG_ERROR("tls_record_parse: did not find expected msg type %d",
1000 expected);
1001 success = FALSE;
1003 #endif
1005 if (!success)
1006 free_parse_data(state);
1008 if (state->debug) {
1009 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
1010 g_string_truncate(state->debug, 0);
1013 return(success);
1016 /* Analyzer only needs the debugging functions */
1017 #ifndef _SIPE_COMPILING_ANALYZER
1020 * TLS message compiler
1022 static void compile_tls_record(struct tls_internal_state *state,
1023 ...)
1025 gsize total_size = 0;
1026 guchar *current;
1027 va_list ap;
1029 /* calculate message size */
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;
1034 total_size += msg->size;
1036 va_end(ap);
1038 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT,
1039 total_size);
1041 state->common.out_buffer = current = g_malloc(total_size + TLS_RECORD_HEADER_LENGTH);
1042 state->common.out_length = total_size + TLS_RECORD_HEADER_LENGTH;
1044 /* add TLS record header */
1045 current[TLS_RECORD_OFFSET_TYPE] = TLS_RECORD_TYPE_HANDSHAKE;
1046 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_VERSION, 2,
1047 TLS_PROTOCOL_VERSION_1_0);
1048 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_LENGTH, 2,
1049 total_size);
1050 current += TLS_RECORD_HEADER_LENGTH;
1052 /* copy messages */
1053 va_start(ap, state);
1054 while (1) {
1055 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
1056 if (!msg) break;
1058 memcpy(current, msg->data, msg->size);
1059 current += msg->size;
1061 va_end(ap);
1064 static void compile_encrypted_tls_record(struct tls_internal_state *state,
1065 const struct tls_compiled_message *msg)
1067 guchar *plaintext;
1068 gsize plaintext_length; /* header + content */
1069 guchar *mac;
1070 gsize mac_length;
1071 guchar *message;
1072 guchar *encrypted;
1073 gsize message_length; /* header + content + MAC */
1074 gsize padding_length; /* for block cipher */
1075 gsize encrypted_length; /* header + encrypted data */
1077 /* Create plaintext TLS record */
1078 compile_tls_record(state, msg, NULL);
1079 plaintext = state->common.out_buffer;
1080 plaintext_length = state->common.out_length;
1081 if (plaintext_length == 0) /* make Coverity happy */
1082 return;
1084 /* Prepare encryption buffer */
1085 message_length = plaintext_length + state->mac_length;
1086 if (state->stream_cipher) {
1087 padding_length = 0;
1088 encrypted_length = message_length;
1089 } else {
1090 if (message_length < TLS_RECORD_HEADER_LENGTH) /* make Coverity happy */
1091 return;
1092 padding_length = TLS_AES_CBC_BLOCK_LENGTH - (message_length - TLS_RECORD_HEADER_LENGTH + 1) % TLS_AES_CBC_BLOCK_LENGTH;
1093 encrypted_length = message_length + padding_length + 1;
1095 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT,
1096 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1097 message = g_malloc(message_length);
1098 memcpy(message, plaintext, plaintext_length);
1099 lowlevel_integer_to_tls(message + TLS_RECORD_OFFSET_LENGTH, 2,
1100 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1103 * Calculate MAC and append to message
1105 * HMAC_hash(client_write_mac_secret,
1106 * sequence_number + type + version + length + fragment)
1107 * \--- == original TLS record ---/
1109 mac_length = sizeof(guint64) + plaintext_length;
1110 mac = g_malloc(mac_length);
1111 lowlevel_integer_to_tls(mac,
1112 sizeof(guint64),
1113 state->sequence_number++);
1114 memcpy(mac + sizeof(guint64), plaintext, plaintext_length);
1115 g_free(plaintext);
1116 state->mac_func(state->client_write_mac_secret,
1117 state->mac_length,
1118 mac,
1119 mac_length,
1120 message + plaintext_length);
1121 g_free(mac);
1123 encrypted = g_malloc(encrypted_length);
1124 /* header (unencrypted) */
1125 memcpy(encrypted, message, TLS_RECORD_HEADER_LENGTH);
1126 if (state->stream_cipher) {
1127 /* ENCRYPT(content + MAC) */
1128 sipe_crypt_tls_stream(state->cipher_context,
1129 message + TLS_RECORD_HEADER_LENGTH,
1130 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1131 encrypted + TLS_RECORD_HEADER_LENGTH);
1132 } else {
1133 /* TLS 1.0 GenericBlockCipher */
1134 /* content + MAC */
1135 memcpy(encrypted + TLS_RECORD_HEADER_LENGTH,
1136 message + TLS_RECORD_HEADER_LENGTH,
1137 message_length - TLS_RECORD_HEADER_LENGTH);
1139 /* padding + padding_length */
1140 memset(encrypted + message_length,
1141 padding_length,
1142 padding_length + 1);
1144 /* ENCRYPT(content + MAC + padding + padding_length) */
1145 sipe_crypt_tls_block(state->client_write_secret,
1146 state->key_length,
1147 state->client_write_iv,
1148 TLS_AES_CBC_BLOCK_LENGTH,
1149 encrypted + TLS_RECORD_HEADER_LENGTH,
1150 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1151 encrypted + TLS_RECORD_HEADER_LENGTH);
1153 g_free(message);
1155 /* swap buffers */
1156 state->common.out_buffer = encrypted;
1157 state->common.out_length = encrypted_length;
1160 static struct tls_compiled_message *compile_handshake_msg(struct tls_internal_state *state,
1161 const struct msg_descriptor *desc,
1162 gpointer data,
1163 gsize size)
1166 * Estimate the size of the compiled message
1168 * The data structures in the host format have zero or more padding
1169 * bytes added by the compiler to ensure correct element alignments.
1170 * So the sizeof() of the data structure is always equal or greater
1171 * than the space needed for the compiled data. By adding the space
1172 * required for the headers we arrive at a safe estimate
1174 * Therefore we don't need space checks in the compiler functions
1176 gsize total_size = sizeof(struct tls_compiled_message) +
1177 size + TLS_HANDSHAKE_HEADER_LENGTH;
1178 struct tls_compiled_message *msg = g_malloc(total_size);
1179 guchar *handshake = msg->data;
1180 const struct layout_descriptor *ldesc = desc->layouts;
1181 gsize length;
1183 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT,
1184 total_size);
1186 /* add TLS handshake header */
1187 handshake[TLS_HANDSHAKE_OFFSET_TYPE] = desc->type;
1188 state->msg_current = handshake + TLS_HANDSHAKE_HEADER_LENGTH;
1190 while (TLS_LAYOUT_IS_VALID(ldesc)) {
1192 * Avoid "cast increases required alignment" errors
1194 * (void *) tells the compiler that we know what we're
1195 * doing, i.e. we know that the calculated address
1196 * points to correctly aligned data.
1198 ldesc->compiler(state, ldesc,
1199 (void *) ((guchar *) data + ldesc->offset));
1200 ldesc++;
1203 length = state->msg_current - handshake - TLS_HANDSHAKE_HEADER_LENGTH;
1204 lowlevel_integer_to_tls(handshake + TLS_HANDSHAKE_OFFSET_LENGTH,
1205 3, length);
1206 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT,
1207 desc->type, desc->description, length);
1209 msg->size = length + TLS_HANDSHAKE_HEADER_LENGTH;
1211 /* update digest contexts */
1212 sipe_digest_md5_update(state->md5_context, handshake, msg->size);
1213 sipe_digest_sha1_update(state->sha1_context, handshake, msg->size);
1215 return(msg);
1219 * Specific TLS data verficiation & message compilers
1221 static struct tls_compiled_message *tls_client_certificate(struct tls_internal_state *state)
1223 struct Certificate_host *certificate;
1224 gsize certificate_length = sipe_cert_crypto_raw_length(state->certificate);
1225 struct tls_compiled_message *msg;
1227 /* setup our response */
1228 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1229 certificate = g_malloc0(sizeof(struct Certificate_host) + 3 +
1230 certificate_length);
1231 certificate->certificate.elements = certificate_length + 3;
1232 lowlevel_integer_to_tls((guchar *) certificate->certificate.placeholder, 3,
1233 certificate_length);
1234 memcpy((guchar *) certificate->certificate.placeholder + 3,
1235 sipe_cert_crypto_raw(state->certificate),
1236 certificate_length);
1238 msg = compile_handshake_msg(state, &Certificate_m, certificate,
1239 sizeof(struct Certificate_host) + certificate_length + 3);
1240 g_free(certificate);
1242 return(msg);
1245 static gboolean check_cipher_suite(struct tls_internal_state *state)
1247 struct tls_parsed_integer *cipher_suite = g_hash_table_lookup(state->data,
1248 "CipherSuite");
1249 const gchar *label_mac = NULL;
1250 const gchar *label_cipher = NULL;
1252 if (!cipher_suite) {
1253 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1254 return(FALSE);
1257 switch (cipher_suite->value) {
1258 case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
1259 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1260 state->key_length = 40 / 8;
1261 state->mac_func = sipe_digest_hmac_md5;
1262 state->stream_cipher = TRUE;
1263 label_mac = "MD5";
1264 label_cipher = "RC4 stream";
1265 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1266 break;
1268 case TLS_RSA_WITH_RC4_128_MD5:
1269 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1270 state->key_length = 128 / 8;
1271 state->mac_func = sipe_digest_hmac_md5;
1272 state->stream_cipher = TRUE;
1273 label_mac = "MD5";
1274 label_cipher = "RC4 stream";
1275 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1276 break;
1278 case TLS_RSA_WITH_RC4_128_SHA:
1279 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1280 state->key_length = 128 / 8;
1281 state->mac_func = sipe_digest_hmac_sha1;
1282 state->stream_cipher = TRUE;
1283 label_mac = "SHA-1";
1284 label_cipher = "RC4 stream";
1285 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1286 break;
1288 case TLS_RSA_WITH_AES_128_CBC_SHA:
1289 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1290 state->key_length = 128 / 8;
1291 state->mac_func = sipe_digest_hmac_sha1;
1292 state->stream_cipher = FALSE;
1293 label_mac = "SHA-1";
1294 label_cipher = "AES-CBC block";
1295 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1296 break;
1298 case TLS_RSA_WITH_AES_256_CBC_SHA:
1299 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1300 state->key_length = 256 / 8;
1301 state->mac_func = sipe_digest_hmac_sha1;
1302 state->stream_cipher = FALSE;
1303 label_mac = "SHA-1";
1304 label_cipher = "AES-CBC block";
1305 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1306 break;
1308 default:
1309 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1310 cipher_suite->value);
1311 break;
1314 if (label_cipher && label_mac)
1315 SIPE_DEBUG_INFO("check_cipher_suite: KEY(%s cipher) %" G_GSIZE_FORMAT ", MAC(%s) %" G_GSIZE_FORMAT,
1316 label_cipher, state->key_length,
1317 label_mac, state->mac_length);
1319 return(label_cipher && label_mac);
1322 static void tls_calculate_secrets(struct tls_internal_state *state)
1324 gsize length = 2 * (state->mac_length + state->key_length +
1325 (state->stream_cipher ? 0 : TLS_AES_CBC_BLOCK_LENGTH));
1326 guchar *random;
1328 /* Generate pre-master secret */
1329 sipe_tls_fill_random(&state->pre_master_secret,
1330 TLS_ARRAY_MASTER_SECRET_LENGTH * 8); /* bits */
1331 lowlevel_integer_to_tls(state->pre_master_secret.buffer, 2,
1332 TLS_PROTOCOL_VERSION_1_0);
1333 debug_secrets(state, "tls_calculate_secrets: pre-master secret",
1334 state->pre_master_secret.buffer,
1335 state->pre_master_secret.length);
1338 * Calculate master secret
1340 * master_secret = PRF(pre_master_secret,
1341 * "master secret",
1342 * ClientHello.random + ServerHello.random)
1344 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1345 memcpy(random,
1346 state->client_random.buffer,
1347 TLS_ARRAY_RANDOM_LENGTH);
1348 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1349 state->server_random.buffer,
1350 TLS_ARRAY_RANDOM_LENGTH);
1351 state->master_secret = sipe_tls_prf(state,
1352 state->pre_master_secret.buffer,
1353 state->pre_master_secret.length,
1354 (guchar *) "master secret",
1356 random,
1357 TLS_ARRAY_RANDOM_LENGTH * 2,
1358 TLS_ARRAY_MASTER_SECRET_LENGTH);
1359 debug_secrets(state, "tls_calculate_secrets: master secret ",
1360 state->master_secret,
1361 TLS_ARRAY_MASTER_SECRET_LENGTH);
1364 * Calculate session key material
1366 * key_block = PRF(master_secret,
1367 * "key expansion",
1368 * ServerHello.random + ClientHello.random)
1370 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT,
1371 length);
1372 memcpy(random,
1373 state->server_random.buffer,
1374 TLS_ARRAY_RANDOM_LENGTH);
1375 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1376 state->client_random.buffer,
1377 TLS_ARRAY_RANDOM_LENGTH);
1378 state->key_block = sipe_tls_prf(state,
1379 state->master_secret,
1380 TLS_ARRAY_MASTER_SECRET_LENGTH,
1381 (guchar *) "key expansion",
1383 random,
1384 TLS_ARRAY_RANDOM_LENGTH * 2,
1385 length);
1386 g_free(random);
1387 debug_secrets(state, "tls_calculate_secrets: key block ",
1388 state->key_block, length);
1390 /* partition key block */
1391 state->client_write_mac_secret = state->key_block;
1392 state->server_write_mac_secret = state->key_block + state->mac_length;
1393 state->client_write_secret = state->key_block + 2 * state->mac_length;
1394 state->server_write_secret = state->key_block + 2 * state->mac_length + state->key_length;
1396 /* initialize stream cipher context */
1397 if (state->stream_cipher) {
1398 state->cipher_context = sipe_crypt_tls_start(state->client_write_secret,
1399 state->key_length);
1400 } else {
1401 state->client_write_iv = state->key_block + 2 * (state->mac_length + state->key_length);
1402 state->server_write_iv = state->key_block + 2 * (state->mac_length + state->key_length) + TLS_AES_CBC_BLOCK_LENGTH;
1406 #if 0 /* NOT NEEDED? */
1407 /* signing */
1408 static guchar *tls_pkcs1_private_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1409 const guchar *data,
1410 gsize data_length,
1411 gsize buffer_length)
1413 gsize pad_length;
1414 guchar *pad_buffer;
1416 if (data_length + 3 > buffer_length) ||
1417 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */)
1418 return(NULL);
1420 pad_length = buffer_length - data_length - 3;
1421 pad_buffer = g_malloc(buffer_length);
1423 /* PKCS1 private key block padding */
1424 pad_buffer[0] = 0; /* +1 */
1425 pad_buffer[1] = 1; /* +2 */
1426 memset(pad_buffer + 2, 0xFF, pad_length);
1427 pad_buffer[2 + pad_length] = 0; /* +3 */
1428 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1430 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1431 debug_secrets(state, "tls_pkcs1_private_padding: ",
1432 pad_buffer, buffer_length);
1433 #endif
1435 return(pad_buffer);
1437 #endif
1439 /* encryption */
1440 static guchar *tls_pkcs1_public_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1441 const guchar *data,
1442 gsize data_length,
1443 gsize buffer_length)
1445 gsize pad_length, random_count;
1446 guchar *pad_buffer, *random;
1448 if ((data_length + 3 > buffer_length) ||
1449 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */
1450 return(NULL);
1452 pad_length = buffer_length - data_length - 3;
1453 pad_buffer = g_malloc(buffer_length);
1455 /* PKCS1 public key block padding */
1456 pad_buffer[0] = 0; /* +1 */
1457 pad_buffer[1] = 2; /* +2 */
1458 for (random = pad_buffer + 2, random_count = pad_length;
1459 random_count > 0;
1460 random_count--) {
1461 guchar byte;
1462 /* non-zero random byte */
1463 while ((byte = rand() & 0xFF) == 0);
1464 *random++ = byte;
1466 pad_buffer[2 + pad_length] = 0; /* +3 */
1467 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1469 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1470 debug_secrets(state, "tls_pkcs1_private_padding: ",
1471 pad_buffer, buffer_length);
1472 #endif
1474 return(pad_buffer);
1477 static struct tls_compiled_message *tls_client_key_exchange(struct tls_internal_state *state)
1479 struct tls_parsed_array *server_random;
1480 struct tls_parsed_array *server_certificate;
1481 struct ClientKeyExchange_host *exchange;
1482 gsize server_certificate_length;
1483 guchar *padded;
1484 struct tls_compiled_message *msg;
1486 /* check for required data fields */
1487 if (!check_cipher_suite(state))
1488 return(NULL);
1489 server_random = g_hash_table_lookup(state->data, "Random");
1490 if (!server_random) {
1491 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1492 return(NULL);
1494 server_certificate = g_hash_table_lookup(state->data, "Certificate");
1495 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1496 if (!server_certificate || (server_certificate->length < 3)) {
1497 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1498 return(FALSE);
1500 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT" bytes",
1501 server_certificate->length);
1502 /* first certificate is the server certificate */
1503 server_certificate_length = lowlevel_integer_to_host(server_certificate->data,
1505 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT" bytes",
1506 server_certificate_length);
1507 if ((server_certificate_length + 3) > server_certificate->length) {
1508 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1510 state->server_certificate = sipe_cert_crypto_import(server_certificate->data + 3,
1511 server_certificate_length);
1512 if (!state->server_certificate) {
1513 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1514 return(FALSE);
1516 /* server public key modulus length */
1517 server_certificate_length = sipe_cert_crypto_modulus_length(state->server_certificate);
1518 if (server_certificate_length < TLS_ARRAY_MASTER_SECRET_LENGTH) {
1519 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT ")",
1520 server_certificate_length);
1521 return(FALSE);
1523 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT,
1524 server_certificate_length);
1526 /* found all the required fields */
1527 state->server_random.length = server_random->length;
1528 state->server_random.buffer = g_memdup(server_random->data,
1529 server_random->length);
1530 tls_calculate_secrets(state);
1532 /* ClientKeyExchange */
1533 padded = tls_pkcs1_public_padding(state,
1534 state->pre_master_secret.buffer,
1535 state->pre_master_secret.length,
1536 server_certificate_length);
1537 if (!padded) {
1538 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: padding of pre-master secret failed");
1539 return(NULL);
1541 exchange = g_malloc0(sizeof(struct ClientKeyExchange_host) +
1542 server_certificate_length);
1543 exchange->secret.elements = server_certificate_length;
1544 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state->server_certificate),
1545 server_certificate_length,
1546 padded,
1547 (guchar *) exchange->secret.placeholder)) {
1548 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1549 g_free(exchange);
1550 g_free(padded);
1551 return(NULL);
1553 g_free(padded);
1555 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1556 debug_secrets(state, "tls_client_key_exchange: secret (encr) ",
1557 (guchar *) exchange->secret.placeholder,
1558 server_certificate_length);
1559 #endif
1561 msg = compile_handshake_msg(state, &ClientKeyExchange_m, exchange,
1562 sizeof(struct ClientKeyExchange_host) + server_certificate_length);
1563 g_free(exchange);
1565 return(msg);
1568 static struct tls_compiled_message *tls_certificate_verify(struct tls_internal_state *state)
1570 struct CertificateVerify_host *verify;
1571 struct tls_compiled_message *msg;
1572 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1573 guchar *signature;
1574 gsize length;
1576 /* calculate digests */
1577 sipe_digest_md5_end(state->md5_context, digests);
1578 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1580 /* sign digests */
1581 signature = sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state->certificate),
1582 digests,
1583 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1584 &length);
1585 g_free(digests);
1586 if (!signature) {
1587 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1588 return(NULL);
1591 /* CertificateVerify */
1592 verify = g_malloc0(sizeof(struct CertificateVerify_host) +
1593 length);
1594 verify->signature.elements = length;
1595 memcpy(verify->signature.placeholder, signature, length);
1596 g_free(signature);
1598 msg = compile_handshake_msg(state, &CertificateVerify_m, verify,
1599 sizeof(struct CertificateVerify_host) + length);
1600 g_free(verify);
1602 return(msg);
1605 static struct tls_compiled_message *tls_client_finished(struct tls_internal_state *state)
1607 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1608 guchar *verify;
1609 struct tls_compiled_message *cmsg;
1610 struct Finished_host msg;
1612 /* calculate digests */
1613 sipe_digest_md5_end(state->md5_context, digests);
1614 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1617 * verify_data = PRF(master_secret, "client finished",
1618 * MD5(handshake_messages) +
1619 * SHA-1(handshake_messages)) [0..11];
1621 verify = sipe_tls_prf(state,
1622 state->master_secret,
1623 TLS_ARRAY_MASTER_SECRET_LENGTH,
1624 (guchar *) "client finished",
1626 digests,
1627 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1628 TLS_ARRAY_VERIFY_LENGTH);
1629 g_free(digests);
1630 memcpy(msg.verify.verify, verify, TLS_ARRAY_VERIFY_LENGTH);
1631 g_free(verify);
1633 cmsg = compile_handshake_msg(state, &Finished_m, &msg, sizeof(msg));
1635 return(cmsg);
1639 * TLS state handling
1642 static gboolean tls_client_hello(struct tls_internal_state *state)
1644 guint32 now = time(NULL);
1645 guint32 now_N = GUINT32_TO_BE(now);
1646 struct ClientHello_host msg = {
1647 { TLS_PROTOCOL_VERSION_1_0 },
1648 { 0, { 0 } },
1649 { 0 /* empty SessionID */ },
1650 { 5,
1652 TLS_RSA_WITH_RC4_128_MD5,
1653 TLS_RSA_WITH_RC4_128_SHA,
1654 TLS_RSA_WITH_AES_128_CBC_SHA,
1655 TLS_RSA_WITH_AES_256_CBC_SHA,
1656 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1659 { 1,
1661 TLS_COMP_METHOD_NULL
1665 struct tls_compiled_message *cmsg;
1667 /* First 4 bytes of client_random is the current timestamp */
1668 sipe_tls_fill_random(&state->client_random,
1669 TLS_ARRAY_RANDOM_LENGTH * 8); /* -> bits */
1670 memcpy(state->client_random.buffer, &now_N, sizeof(now_N));
1671 memcpy(msg.random.random, state->client_random.buffer,
1672 TLS_ARRAY_RANDOM_LENGTH);
1674 cmsg = compile_handshake_msg(state, &ClientHello_m, &msg, sizeof(msg));
1675 compile_tls_record(state, cmsg, NULL);
1676 g_free(cmsg);
1678 if (sipe_backend_debug_enabled())
1679 state->debug = g_string_new("");
1681 state->state = TLS_HANDSHAKE_STATE_SERVER_HELLO;
1682 return(tls_record_parse(state, FALSE, 0));
1685 static gboolean tls_server_hello(struct tls_internal_state *state)
1687 struct tls_compiled_message *certificate = NULL;
1688 struct tls_compiled_message *exchange = NULL;
1689 struct tls_compiled_message *verify = NULL;
1690 struct tls_compiled_message *finished = NULL;
1691 gboolean success = FALSE;
1693 if (!tls_record_parse(state, TRUE, TLS_HANDSHAKE_TYPE_SERVER_HELLO))
1694 return(FALSE);
1696 if (((certificate = tls_client_certificate(state)) != NULL) &&
1697 ((exchange = tls_client_key_exchange(state)) != NULL) &&
1698 ((verify = tls_certificate_verify(state)) != NULL) &&
1699 ((finished = tls_client_finished(state)) != NULL)) {
1701 /* Part 1 */
1702 compile_tls_record(state, certificate, exchange, verify, NULL);
1704 success = tls_record_parse(state, FALSE, 0);
1705 if (success) {
1706 guchar *part1 = state->common.out_buffer;
1707 gsize part1_length = state->common.out_length;
1708 guchar *part3;
1709 gsize part3_length;
1710 guchar *merged;
1711 gsize length;
1712 /* ChangeCipherSpec is always the same */
1713 static const guchar part2[] = {
1714 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC,
1715 (TLS_PROTOCOL_VERSION_1_0 >> 8) & 0xFF,
1716 TLS_PROTOCOL_VERSION_1_0 & 0xFF,
1717 0x00, 0x01, /* length: 1 byte */
1718 0x01 /* change_cipher_spec(1) */
1721 state->common.out_buffer = NULL;
1723 /* Part 3 - this is the first encrypted record */
1724 compile_encrypted_tls_record(state, finished);
1725 part3 = state->common.out_buffer;
1726 part3_length = state->common.out_length;
1728 /* merge TLS records */
1729 length = part1_length + sizeof(part2) + part3_length;
1730 merged = g_malloc(length);
1732 memcpy(merged, part1, part1_length);
1733 memcpy(merged + part1_length, part2, sizeof(part2));
1734 memcpy(merged + part1_length + sizeof(part2), part3, part3_length);
1735 g_free(part3);
1736 g_free(part1);
1738 /* replace output buffer with merged message */
1739 state->common.out_buffer = merged;
1740 state->common.out_length = length;
1742 state->state = TLS_HANDSHAKE_STATE_FINISHED;
1746 g_free(finished);
1747 g_free(verify);
1748 g_free(exchange);
1749 g_free(certificate);
1750 free_parse_data(state);
1752 return(success);
1755 static gboolean tls_finished(struct tls_internal_state *state)
1757 guchar *random;
1759 if (!tls_record_parse(state, TRUE, TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC))
1760 return(FALSE);
1762 /* we don't need the data */
1763 free_parse_data(state);
1766 * Calculate session keys [MS-SIPAE section 3.2.5.1]
1768 * key_material = PRF (master_secret,
1769 * "client EAP encryption",
1770 * ClientHello.random + ServerHello.random)[128]
1771 * = 4 x 32 Bytes
1773 * client key = key_material[3rd 32 Bytes]
1774 * server key = key_material[4th 32 Bytes]
1776 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1777 memcpy(random,
1778 state->client_random.buffer,
1779 TLS_ARRAY_RANDOM_LENGTH);
1780 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1781 state->server_random.buffer,
1782 TLS_ARRAY_RANDOM_LENGTH);
1783 state->tls_dsk_key_block = sipe_tls_prf(state,
1784 state->master_secret,
1785 TLS_ARRAY_MASTER_SECRET_LENGTH,
1786 (guchar *) "client EAP encryption",
1788 random,
1789 TLS_ARRAY_RANDOM_LENGTH * 2,
1790 4 * 32);
1791 g_free(random);
1793 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1794 debug_secrets(state, "tls_finished: TLS-DSK key block ",
1795 state->tls_dsk_key_block, 4 * 32);
1796 #endif
1798 state->common.client_key = state->tls_dsk_key_block + 2 * 32;
1799 state->common.server_key = state->tls_dsk_key_block + 3 * 32;
1800 state->common.key_length = 32;
1802 debug_secrets(state, "tls_finished: TLS-DSK client key ",
1803 state->common.client_key,
1804 state->common.key_length);
1805 debug_secrets(state, "tls_finished: TLS-DSK server key ",
1806 state->common.server_key,
1807 state->common.key_length);
1809 state->common.out_buffer = NULL;
1810 state->common.out_length = 0;
1811 state->state = TLS_HANDSHAKE_STATE_COMPLETED;
1813 return(TRUE);
1817 * TLS public API
1820 struct sipe_tls_state *sipe_tls_start(gpointer certificate)
1822 struct tls_internal_state *state;
1824 if (!certificate)
1825 return(NULL);
1827 state = g_new0(struct tls_internal_state, 1);
1828 state->certificate = certificate;
1829 state->state = TLS_HANDSHAKE_STATE_START;
1830 state->md5_context = sipe_digest_md5_start();
1831 state->sha1_context = sipe_digest_sha1_start();
1832 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_NONE;
1834 return((struct sipe_tls_state *) state);
1837 gboolean sipe_tls_next(struct sipe_tls_state *state)
1839 /* Avoid "cast increases required alignment" errors */
1840 struct tls_internal_state *internal = (void *) state;
1841 gboolean success = FALSE;
1843 if (!state)
1844 return(FALSE);
1846 state->out_buffer = NULL;
1848 switch (internal->state) {
1849 case TLS_HANDSHAKE_STATE_START:
1850 success = tls_client_hello(internal);
1851 break;
1853 case TLS_HANDSHAKE_STATE_SERVER_HELLO:
1854 success = tls_server_hello(internal);
1855 break;
1857 case TLS_HANDSHAKE_STATE_FINISHED:
1858 success = tls_finished(internal);
1859 break;
1861 case TLS_HANDSHAKE_STATE_COMPLETED:
1862 case TLS_HANDSHAKE_STATE_FAILED:
1863 /* This should not happen */
1864 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1865 break;
1868 if (!success) {
1869 internal->state = TLS_HANDSHAKE_STATE_FAILED;
1872 return(success);
1875 guint sipe_tls_expires(struct sipe_tls_state *state)
1877 /* Avoid "cast increases required alignment" errors */
1878 struct tls_internal_state *internal = (void *) state;
1880 if (!state)
1881 return(0);
1883 return(sipe_cert_crypto_expires(internal->certificate));
1886 void sipe_tls_free(struct sipe_tls_state *state)
1888 if (state) {
1889 /* Avoid "cast increases required alignment" errors */
1890 struct tls_internal_state *internal = (void *) state;
1892 free_parse_data(internal);
1893 if (internal->debug)
1894 g_string_free(internal->debug, TRUE);
1895 g_free(internal->tls_dsk_key_block);
1896 g_free(internal->key_block);
1897 g_free(internal->master_secret);
1898 sipe_tls_free_random(&internal->pre_master_secret);
1899 sipe_tls_free_random(&internal->client_random);
1900 sipe_tls_free_random(&internal->server_random);
1901 if (internal->cipher_context)
1902 sipe_crypt_tls_destroy(internal->cipher_context);
1903 if (internal->md5_context)
1904 sipe_digest_md5_destroy(internal->md5_context);
1905 if (internal->sha1_context)
1906 sipe_digest_sha1_destroy(internal->sha1_context);
1907 sipe_cert_crypto_destroy(internal->server_certificate);
1908 g_free(state->out_buffer);
1909 g_free(state);
1913 #endif /* !_SIPE_COMPILING_ANALYZER */
1916 Local Variables:
1917 mode: c
1918 c-file-style: "bsd"
1919 indent-tabs-mode: t
1920 tab-width: 8
1921 End: