purple: take renamed API 3.x.x headers in use
[siplcs.git] / src / core / sipe-tls.c
blob641d2218a48573f387449ac8a3c0dbd2486805f9
1 /**
2 * @file sipe-tls.c
4 * pidgin-sipe
6 * Copyright (C) 2011-12 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 - 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;
93 * TLS messages & layout descriptors
96 /* constants */
97 #define TLS_VECTOR_MAX8 255 /* 2^8 - 1 */
98 #define TLS_VECTOR_MAX16 65535 /* 2^16 - 1 */
99 #define TLS_VECTOR_MAX24 16777215 /* 2^24 - 1 */
101 #define TLS_PROTOCOL_VERSION_1_0 0x0301
102 #define TLS_PROTOCOL_VERSION_1_1 0x0302
104 /* CipherSuites */
105 #define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
106 #define TLS_RSA_WITH_RC4_128_MD5 0x0004
107 #define TLS_RSA_WITH_RC4_128_SHA 0x0005
109 /* CompressionMethods */
110 #define TLS_COMP_METHOD_NULL 0
112 /* various array lengths */
113 #define TLS_ARRAY_RANDOM_LENGTH 32
114 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
115 #define TLS_ARRAY_VERIFY_LENGTH 12
117 #define TLS_RECORD_HEADER_LENGTH 5
118 #define TLS_RECORD_OFFSET_TYPE 0
119 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
120 #define TLS_RECORD_TYPE_HANDSHAKE 22
121 #define TLS_RECORD_OFFSET_VERSION 1
122 #define TLS_RECORD_OFFSET_LENGTH 3
124 #define TLS_HANDSHAKE_HEADER_LENGTH 4
125 #define TLS_HANDSHAKE_OFFSET_TYPE 0
126 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
127 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
128 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
129 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
130 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
131 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
132 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
133 #define TLS_HANDSHAKE_TYPE_FINISHED 20
134 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
136 struct layout_descriptor;
137 typedef gboolean parse_func(struct tls_internal_state *state,
138 const struct layout_descriptor *desc);
140 /* Defines the strictest alignment requirement */
141 struct tls_compile_integer;
142 typedef void compile_func(struct tls_internal_state *state,
143 const struct layout_descriptor *desc,
144 const struct tls_compile_integer *data);
146 struct layout_descriptor {
147 const gchar *label;
148 parse_func *parser;
149 compile_func *compiler;
150 gsize min; /* 0 for fixed/array */
151 gsize max;
152 gsize offset;
155 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
156 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
158 struct msg_descriptor {
159 const struct msg_descriptor *next;
160 const gchar *description;
161 const struct layout_descriptor *layouts;
162 guint type;
165 /* parsed data */
166 struct tls_parsed_integer {
167 guint value;
170 struct tls_parsed_array {
171 gsize length; /* bytes */
172 const guchar data[0];
175 /* compile data */
176 struct tls_compile_integer {
177 gsize value;
180 struct tls_compile_array {
181 gsize elements; /* unused */
182 guchar placeholder[];
185 struct tls_compile_random {
186 gsize elements; /* unused */
187 guchar random[TLS_ARRAY_RANDOM_LENGTH];
190 struct tls_compile_verify {
191 gsize elements; /* unused */
192 guchar verify[TLS_ARRAY_VERIFY_LENGTH];
195 struct tls_compile_vector {
196 gsize elements; /* VECTOR */
197 guint placeholder[];
200 struct tls_compile_sessionid {
201 gsize elements; /* VECTOR */
204 struct tls_compile_cipher {
205 gsize elements; /* VECTOR */
206 guint suites[3];
209 struct tls_compile_compression {
210 gsize elements; /* VECTOR */
211 guint methods[1];
214 /* compiled message */
215 struct tls_compiled_message {
216 gsize size;
217 guchar data[];
221 * Random byte buffers
223 void sipe_tls_fill_random(struct sipe_tls_random *random,
224 guint bits)
226 guint bytes = ((bits + 15) / 16) * 2;
227 guint16 *p = g_malloc(bytes);
229 SIPE_DEBUG_INFO("sipe_tls_fill_random: %d bits -> %d bytes",
230 bits, bytes);
232 random->buffer = (guint8*) p;
233 random->length = bytes;
235 for (bytes /= 2; bytes; bytes--)
236 *p++ = rand() & 0xFFFF;
239 void sipe_tls_free_random(struct sipe_tls_random *random)
241 g_free(random->buffer);
245 * TLS message debugging
247 static void debug_hex(struct tls_internal_state *state,
248 gsize alternative_length)
250 GString *str = state->debug;
251 const guchar *bytes;
252 gsize length;
253 gint count;
255 if (!str) return;
257 bytes = state->msg_current;
258 length = alternative_length ? alternative_length : state->msg_remainder;
259 count = -1;
261 while (length-- > 0) {
262 if (++count == 0) {
263 /* do nothing */;
264 } else if ((count % 16) == 0) {
265 g_string_append(str, "\n");
266 } else if ((count % 8) == 0) {
267 g_string_append(str, " ");
269 g_string_append_printf(str, " %02X", *bytes++);
271 g_string_append(str, "\n");
274 #define debug_print(state, string) \
275 if (state->debug) g_string_append(state->debug, string)
276 #define debug_printf(state, format, ...) \
277 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
279 static void debug_secrets(struct tls_internal_state *state,
280 const gchar *label,
281 const guchar *secret,
282 gsize secret_length)
284 if (state->debug && secret) {
285 g_string_append_printf(state->debug, "%s (%3" G_GSIZE_FORMAT ") = ",
286 label, secret_length);
287 while (secret_length--)
288 g_string_append_printf(state->debug, "%02X", *secret++);
289 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
290 g_string_truncate(state->debug, 0);
295 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
297 static guchar *sipe_tls_p_md5(const guchar *secret,
298 gsize secret_length,
299 const guchar *seed,
300 gsize seed_length,
301 gsize output_length)
303 guchar *output = NULL;
306 * output_length == 0 -> illegal
307 * output_length == 1..16 -> iterations = 1
308 * output_length == 17..32 -> iterations = 2
310 if (secret && seed && (output_length > 0)) {
311 guint iterations = (output_length + SIPE_DIGEST_HMAC_MD5_LENGTH - 1) / SIPE_DIGEST_HMAC_MD5_LENGTH;
312 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length);
313 guchar A[SIPE_DIGEST_HMAC_MD5_LENGTH];
314 guchar *p;
316 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
317 secret_length, seed_length);
318 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
319 output_length, iterations);
321 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
322 sipe_digest_hmac_md5(secret, secret_length,
323 seed, seed_length,
326 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
327 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_MD5_LENGTH);
329 while (iterations-- > 0) {
330 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
331 guchar P[SIPE_DIGEST_HMAC_MD5_LENGTH];
332 memcpy(concat, A, SIPE_DIGEST_HMAC_MD5_LENGTH);
333 memcpy(concat + SIPE_DIGEST_HMAC_MD5_LENGTH, seed, seed_length);
334 sipe_digest_hmac_md5(secret, secret_length,
335 concat, SIPE_DIGEST_HMAC_MD5_LENGTH + seed_length,
337 memcpy(p, P, SIPE_DIGEST_HMAC_MD5_LENGTH);
338 p += SIPE_DIGEST_HMAC_MD5_LENGTH;
340 /* A(i+1) = HMAC_MD5(secret, A(i)) */
341 sipe_digest_hmac_md5(secret, secret_length,
342 A, SIPE_DIGEST_HMAC_MD5_LENGTH,
345 g_free(concat);
348 return(output);
351 guchar *sipe_tls_p_sha1(const guchar *secret,
352 gsize secret_length,
353 const guchar *seed,
354 gsize seed_length,
355 gsize output_length)
357 guchar *output = NULL;
360 * output_length == 0 -> illegal
361 * output_length == 1..20 -> iterations = 1
362 * output_length == 21..40 -> iterations = 2
364 if (secret && seed && (output_length > 0)) {
365 guint iterations = (output_length + SIPE_DIGEST_HMAC_SHA1_LENGTH - 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH;
366 guchar *concat = g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length);
367 guchar A[SIPE_DIGEST_HMAC_SHA1_LENGTH];
368 guchar *p;
370 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT " bytes, seed %" G_GSIZE_FORMAT " bytes",
371 secret_length, seed_length);
372 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT " bytes -> %d iterations",
373 output_length, iterations);
375 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
376 sipe_digest_hmac_sha1(secret, secret_length,
377 seed, seed_length,
380 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
381 p = output = g_malloc(iterations * SIPE_DIGEST_HMAC_SHA1_LENGTH);
383 while (iterations-- > 0) {
384 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
385 guchar P[SIPE_DIGEST_HMAC_SHA1_LENGTH];
386 memcpy(concat, A, SIPE_DIGEST_HMAC_SHA1_LENGTH);
387 memcpy(concat + SIPE_DIGEST_HMAC_SHA1_LENGTH, seed, seed_length);
388 sipe_digest_hmac_sha1(secret, secret_length,
389 concat, SIPE_DIGEST_HMAC_SHA1_LENGTH + seed_length,
391 memcpy(p, P, SIPE_DIGEST_HMAC_SHA1_LENGTH);
392 p += SIPE_DIGEST_HMAC_SHA1_LENGTH;
394 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
395 sipe_digest_hmac_sha1(secret, secret_length,
396 A, SIPE_DIGEST_HMAC_SHA1_LENGTH,
399 g_free(concat);
402 return(output);
405 static guchar *sipe_tls_prf(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
406 const guchar *secret,
407 gsize secret_length,
408 const guchar *label,
409 gsize label_length,
410 const guchar *seed,
411 gsize seed_length,
412 gsize output_length)
414 gsize half = (secret_length + 1) / 2;
415 gsize newseed_length = label_length + seed_length;
416 /* secret: used as S1; secret2: last half of original secret (S2) */
417 guchar *secret2 = g_memdup(secret + secret_length - half, half);
418 guchar *newseed = g_malloc(newseed_length);
419 guchar *md5, *dest;
420 guchar *sha1, *src;
421 gsize count;
423 /* make Coverity happy - lengths could be 0 */
424 if (!secret2 || !newseed) {
425 g_free(secret2);
426 g_free(newseed);
427 return(NULL);
431 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
432 * P_SHA-1(S2, label + seed);
434 memcpy(newseed, label, label_length);
435 memcpy(newseed + label_length, seed, seed_length);
436 #undef __SIPE_TLS_CRYPTO_DEBUG
437 #ifdef __SIPE_TLS_CRYPTO_DEBUG
438 debug_secrets(state, "sipe_tls_prf: secret ",
439 secret, secret_length);
440 debug_secrets(state, "sipe_tls_prf: combined seed ",
441 newseed, newseed_length);
442 SIPE_DEBUG_INFO("total seed length %" G_GSIZE_FORMAT,
443 newseed_length);
444 debug_secrets(state, "sipe_tls_prf: S1 ",
445 secret, half);
446 debug_secrets(state, "sipe_tls_prf: S2 ",
447 secret2, half);
448 #endif
449 md5 = sipe_tls_p_md5(secret, half, newseed, newseed_length, output_length);
450 sha1 = sipe_tls_p_sha1(secret2, half, newseed, newseed_length, output_length);
451 #ifdef __SIPE_TLS_CRYPTO_DEBUG
452 debug_secrets(state, "sipe_tls_prf: P_md5() ",
453 md5, output_length);
454 debug_secrets(state, "sipe_tls_prf: P_sha1() ",
455 sha1, output_length);
456 #endif
457 for (dest = md5, src = sha1, count = output_length;
458 count > 0;
459 count--)
460 *dest++ ^= *src++;
462 g_free(sha1);
463 g_free(newseed);
464 g_free(secret2);
466 #ifdef __SIPE_TLS_CRYPTO_DEBUG
467 debug_secrets(state, "sipe_tls_prf: PRF() ",
468 md5, output_length);
469 #endif
471 return(md5);
475 * TLS data parsers
477 * Low-level data conversion routines
479 * - host alignment agnostic, i.e. can fetch a word from uneven address
480 * - TLS -> host endianess conversion
481 * - no length check, caller has to do it
482 * - don't modify state
484 static guint lowlevel_integer_to_host(const guchar *bytes,
485 gsize length)
487 guint sum = 0;
488 while (length--) sum = (sum << 8) + *bytes++;
489 return(sum);
493 * Generic data type parser routines
495 static gboolean msg_remainder_check(struct tls_internal_state *state,
496 const gchar *label,
497 gsize length)
499 if (length > state->msg_remainder) {
500 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT " bytes, remaining %" G_GSIZE_FORMAT,
501 label, length, state->msg_remainder);
502 return(FALSE);
504 return(TRUE);
507 static gboolean parse_integer_quiet(struct tls_internal_state *state,
508 const gchar *label,
509 gsize length,
510 guint *result)
512 if (!msg_remainder_check(state, label, length)) return(FALSE);
513 *result = lowlevel_integer_to_host(state->msg_current, length);
514 state->msg_current += length;
515 state->msg_remainder -= length;
516 return(TRUE);
519 static gboolean parse_integer(struct tls_internal_state *state,
520 const struct layout_descriptor *desc)
522 guint value;
523 if (!parse_integer_quiet(state, desc->label, desc->max, &value))
524 return(FALSE);
525 debug_printf(state, "%s/INTEGER%" G_GSIZE_FORMAT " = %d\n",
526 desc->label, desc->max, value);
527 if (state->data) {
528 struct tls_parsed_integer *save = g_new0(struct tls_parsed_integer, 1);
529 save->value = value;
530 g_hash_table_insert(state->data, (gpointer) desc->label, save);
532 return(TRUE);
535 static gboolean parse_array(struct tls_internal_state *state,
536 const struct layout_descriptor *desc)
538 if (!msg_remainder_check(state, desc->label, desc->max))
539 return(FALSE);
540 debug_printf(state, "%s/ARRAY[%" G_GSIZE_FORMAT "]\n",
541 desc->label, desc->max);
542 if (state->data) {
543 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
544 desc->max);
545 save->length = desc->max;
546 memcpy((guchar *)save->data, state->msg_current, desc->max);
547 g_hash_table_insert(state->data, (gpointer) desc->label, save);
550 state->msg_current += desc->max;
551 state->msg_remainder -= desc->max;
552 return(TRUE);
555 static gboolean parse_vector(struct tls_internal_state *state,
556 const struct layout_descriptor *desc)
558 guint length;
559 if (!parse_integer_quiet(state, desc->label,
560 (desc->max > TLS_VECTOR_MAX16) ? 3 :
561 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1,
562 &length))
563 return(FALSE);
564 if (length < desc->min) {
565 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT,
566 desc->label, length, desc->min);
567 return(FALSE);
569 debug_printf(state, "%s/VECTOR<%d>\n", desc->label, length);
570 if (state->data) {
571 struct tls_parsed_array *save = g_malloc0(sizeof(struct tls_parsed_array) +
572 length);
573 save->length = length;
574 memcpy((guchar *)save->data, state->msg_current, length);
575 g_hash_table_insert(state->data, (gpointer) desc->label, save);
577 state->msg_current += length;
578 state->msg_remainder -= length;
579 return(TRUE);
583 * Specific data type parser routines
586 /* TBD... */
589 * TLS data compilers
591 * Low-level data conversion routines
593 * - host alignment agnostic, i.e. can fetch a word from uneven address
594 * - host -> TLS host endianess conversion
595 * - don't modify state
597 static void lowlevel_integer_to_tls(guchar *bytes,
598 gsize length,
599 guint value)
601 while (length--) {
602 bytes[length] = value & 0xFF;
603 value >>= 8;
608 * Generic data type compiler routines
610 static void compile_integer(struct tls_internal_state *state,
611 const struct layout_descriptor *desc,
612 const struct tls_compile_integer *data)
614 lowlevel_integer_to_tls(state->msg_current, desc->max, data->value);
615 state->msg_current += desc->max;
618 static void compile_array(struct tls_internal_state *state,
619 const struct layout_descriptor *desc,
620 const struct tls_compile_integer *data)
622 const struct tls_compile_array *array = (struct tls_compile_array *) data;
623 memcpy(state->msg_current, array->placeholder, desc->max);
624 state->msg_current += desc->max;
627 static void compile_vector(struct tls_internal_state *state,
628 const struct layout_descriptor *desc,
629 const struct tls_compile_integer *data)
631 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
632 gsize length = vector->elements;
633 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
634 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
636 lowlevel_integer_to_tls(state->msg_current, length_field, length);
637 state->msg_current += length_field;
638 memcpy(state->msg_current, vector->placeholder, length);
639 state->msg_current += length;
642 static void compile_vector_int2(struct tls_internal_state *state,
643 const struct layout_descriptor *desc,
644 const struct tls_compile_integer *data)
646 const struct tls_compile_vector *vector = (struct tls_compile_vector *) data;
647 gsize elements = vector->elements;
648 gsize length = elements * sizeof(guint16);
649 gsize length_field = (desc->max > TLS_VECTOR_MAX16) ? 3 :
650 (desc->max > TLS_VECTOR_MAX8) ? 2 : 1;
651 const guint *p = vector->placeholder;
653 lowlevel_integer_to_tls(state->msg_current, length_field, length);
654 state->msg_current += length_field;
655 while (elements--) {
656 lowlevel_integer_to_tls(state->msg_current, sizeof(guint16), *p++);
657 state->msg_current += sizeof(guint16);
662 * Specific data type compiler routines
665 /* TBD... */
668 * TLS handshake message layout descriptors
670 struct ClientHello_host {
671 struct tls_compile_integer protocol_version;
672 struct tls_compile_random random;
673 struct tls_compile_sessionid sessionid;
674 struct tls_compile_cipher cipher;
675 struct tls_compile_compression compression;
677 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
679 static const struct layout_descriptor ClientHello_l[] = {
680 { "Client Protocol Version", parse_integer, compile_integer, 0, 2, CLIENTHELLO_OFFSET(protocol_version) },
681 { "Random", parse_array, compile_array, 0, TLS_ARRAY_RANDOM_LENGTH, CLIENTHELLO_OFFSET(random) },
682 { "SessionID", parse_vector, compile_vector, 0, 32, CLIENTHELLO_OFFSET(sessionid) },
683 { "CipherSuite", parse_vector, compile_vector_int2, 2, TLS_VECTOR_MAX16, CLIENTHELLO_OFFSET(cipher)},
684 { "CompressionMethod", parse_vector, compile_vector, 1, TLS_VECTOR_MAX8, CLIENTHELLO_OFFSET(compression) },
685 TLS_LAYOUT_DESCRIPTOR_END
687 static const struct msg_descriptor ClientHello_m = {
688 NULL, "Client Hello", ClientHello_l, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
691 static const struct layout_descriptor ServerHello_l[] = {
692 { "Server Protocol Version", parse_integer, NULL, 0, 2, 0 },
693 { "Random", parse_array, NULL, 0, TLS_ARRAY_RANDOM_LENGTH, 0 },
694 { "SessionID", parse_vector, NULL, 0, 32, 0 },
695 { "CipherSuite", parse_integer, NULL, 0, 2, 0 },
696 { "CompressionMethod", parse_integer, NULL, 0, 1, 0 },
697 TLS_LAYOUT_DESCRIPTOR_END
699 static const struct msg_descriptor ServerHello_m = {
700 &ClientHello_m, "Server Hello", ServerHello_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO
703 struct Certificate_host {
704 struct tls_compile_vector certificate;
706 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
708 static const struct layout_descriptor Certificate_l[] = {
709 { "Certificate", parse_vector, compile_vector, 0, TLS_VECTOR_MAX24, CERTIFICATE_OFFSET(certificate) },
710 TLS_LAYOUT_DESCRIPTOR_END
712 static const struct msg_descriptor Certificate_m = {
713 &ServerHello_m, "Certificate", Certificate_l, TLS_HANDSHAKE_TYPE_CERTIFICATE
716 static const struct layout_descriptor CertificateRequest_l[] = {
717 { "CertificateType", parse_vector, NULL, 1, TLS_VECTOR_MAX8, 0 },
718 { "DistinguishedName", parse_vector, NULL, 0, TLS_VECTOR_MAX16, 0 },
719 TLS_LAYOUT_DESCRIPTOR_END
721 static const struct msg_descriptor CertificateRequest_m = {
722 &Certificate_m, "Certificate Request", CertificateRequest_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
725 static const struct layout_descriptor ServerHelloDone_l[] = {
726 TLS_LAYOUT_DESCRIPTOR_END
728 static const struct msg_descriptor ServerHelloDone_m = {
729 &CertificateRequest_m, "Server Hello Done", ServerHelloDone_l, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
732 struct ClientKeyExchange_host {
733 struct tls_compile_vector secret;
735 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
737 static const struct layout_descriptor ClientKeyExchange_l[] = {
738 { "Exchange Keys", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CLIENTKEYEXCHANGE_OFFSET(secret) },
739 TLS_LAYOUT_DESCRIPTOR_END
741 static const struct msg_descriptor ClientKeyExchange_m = {
742 &ServerHelloDone_m, "Client Key Exchange", ClientKeyExchange_l, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
745 struct CertificateVerify_host {
746 struct tls_compile_vector signature;
748 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
750 static const struct layout_descriptor CertificateVerify_l[] = {
751 { "Signature", parse_vector, compile_vector, 0, TLS_VECTOR_MAX16, CERTIFICATEVERIFY_OFFSET(signature) },
752 TLS_LAYOUT_DESCRIPTOR_END
754 static const struct msg_descriptor CertificateVerify_m = {
755 &ClientKeyExchange_m, "Certificate Verify", CertificateVerify_l, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
758 struct Finished_host {
759 struct tls_compile_verify verify;
761 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
763 static const struct layout_descriptor Finished_l[] = {
764 { "Verify Data", parse_array, compile_array, 0, TLS_ARRAY_VERIFY_LENGTH, FINISHED_OFFSET(verify) },
765 TLS_LAYOUT_DESCRIPTOR_END
767 static const struct msg_descriptor Finished_m = {
768 &CertificateVerify_m, "Finished", Finished_l, TLS_HANDSHAKE_TYPE_FINISHED
771 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
774 * TLS message parsers
776 static gboolean handshake_parse(struct tls_internal_state *state)
778 const guchar *bytes = state->msg_current;
779 gsize length = state->msg_remainder;
780 gboolean success = FALSE;
782 while (length > 0) {
783 const struct msg_descriptor *desc;
784 gsize msg_length;
785 guint msg_type;
787 /* header check */
788 if (length < TLS_HANDSHAKE_HEADER_LENGTH) {
789 debug_print(state, "CORRUPTED HANDSHAKE HEADER");
790 break;
793 /* msg length check */
794 msg_length = lowlevel_integer_to_host(bytes + TLS_HANDSHAKE_OFFSET_LENGTH,
796 if (msg_length > length) {
797 debug_print(state, "HANDSHAKE MESSAGE TOO LONG");
798 break;
801 /* msg type */
802 msg_type = bytes[TLS_HANDSHAKE_OFFSET_TYPE];
803 for (desc = HANDSHAKE_MSG_DESCRIPTORS;
804 desc;
805 desc = desc->next)
806 if (msg_type == desc->type)
807 break;
809 debug_printf(state, "TLS handshake (%" G_GSIZE_FORMAT " bytes) (%d)",
810 msg_length, msg_type);
812 state->msg_current = (guchar *) bytes + TLS_HANDSHAKE_HEADER_LENGTH;
813 state->msg_remainder = msg_length;
815 if (desc && desc->layouts) {
816 const struct layout_descriptor *ldesc = desc->layouts;
818 debug_printf(state, "%s\n", desc->description);
819 while (TLS_LAYOUT_IS_VALID(ldesc)) {
820 success = ldesc->parser(state, ldesc);
821 if (!success)
822 break;
823 ldesc++;
825 if (!success)
826 break;
827 } else {
828 debug_print(state, "ignored\n");
829 debug_hex(state, 0);
832 /* next message */
833 bytes += TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
834 length -= TLS_HANDSHAKE_HEADER_LENGTH + msg_length;
835 if (length > 0) {
836 debug_print(state, "------\n");
837 } else {
838 success = TRUE;
842 return(success);
845 static void free_parse_data(struct tls_internal_state *state)
847 if (state->data) {
848 g_hash_table_destroy(state->data);
849 state->data = NULL;
853 static gboolean tls_record_parse(struct tls_internal_state *state,
854 gboolean incoming)
856 const guchar *bytes = incoming ? state->common.in_buffer : state->common.out_buffer;
857 gsize length = incoming ? state->common.in_length : state->common.out_length;
858 guint version;
859 const gchar *version_str;
860 gsize record_length;
861 gboolean success = TRUE;
863 debug_printf(state, "TLS MESSAGE %s\n", incoming ? "INCOMING" : "OUTGOING");
865 /* Collect parser data for incoming messages */
866 if (incoming)
867 state->data = g_hash_table_new_full(g_str_hash, g_str_equal,
868 NULL, g_free);
870 while (success && (length > 0)) {
872 /* truncated header check */
873 if (length < TLS_RECORD_HEADER_LENGTH) {
874 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT " bytes)",
875 length);
876 success = FALSE;
877 break;
880 /* protocol version check */
881 version = lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_VERSION, 2);
882 if (version < TLS_PROTOCOL_VERSION_1_0) {
883 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
884 success = FALSE;
885 break;
887 switch (version) {
888 case TLS_PROTOCOL_VERSION_1_0:
889 version_str = "1.0 (RFC2246)";
890 break;
891 case TLS_PROTOCOL_VERSION_1_1:
892 version_str = "1.1 (RFC4346)";
893 break;
894 default:
895 version_str = "<future protocol version>";
896 break;
899 /* record length check */
900 record_length = TLS_RECORD_HEADER_LENGTH +
901 lowlevel_integer_to_host(bytes + TLS_RECORD_OFFSET_LENGTH, 2);
902 if (record_length > length) {
903 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
904 success = FALSE;
905 break;
908 /* TLS record header OK */
909 debug_printf(state, "TLS %s record (%" G_GSIZE_FORMAT " bytes)\n",
910 version_str, record_length);
911 state->msg_current = (guchar *) bytes + TLS_RECORD_HEADER_LENGTH;
912 state->msg_remainder = record_length - TLS_RECORD_HEADER_LENGTH;
914 /* Add incoming message contents to digest contexts */
915 if (incoming) {
916 sipe_digest_md5_update(state->md5_context,
917 state->msg_current,
918 state->msg_remainder);
919 sipe_digest_sha1_update(state->sha1_context,
920 state->msg_current,
921 state->msg_remainder);
924 switch (bytes[TLS_RECORD_OFFSET_TYPE]) {
925 case TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC:
926 debug_print(state, "Change Cipher Spec\n");
927 if (incoming) state->encrypted = TRUE;
928 break;
930 case TLS_RECORD_TYPE_HANDSHAKE:
931 if (incoming && state->encrypted) {
932 debug_print(state, "Encrypted handshake message\n");
933 debug_hex(state, 0);
934 } else {
935 success = handshake_parse(state);
937 break;
939 default:
940 debug_print(state, "Unsupported TLS message\n");
941 debug_hex(state, 0);
942 break;
945 /* next fragment */
946 bytes += record_length;
947 length -= record_length;
950 if (!success)
951 free_parse_data(state);
953 if (state->debug) {
954 SIPE_DEBUG_INFO_NOFORMAT(state->debug->str);
955 g_string_truncate(state->debug, 0);
958 return(success);
962 * TLS message compiler
964 static void compile_tls_record(struct tls_internal_state *state,
965 ...)
967 gsize total_size = 0;
968 guchar *current;
969 va_list ap;
971 /* calculate message size */
972 va_start(ap, state);
973 while (1) {
974 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
975 if (!msg) break;
976 total_size += msg->size;
978 va_end(ap);
980 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT,
981 total_size);
983 state->common.out_buffer = current = g_malloc(total_size + TLS_RECORD_HEADER_LENGTH);
984 state->common.out_length = total_size + TLS_RECORD_HEADER_LENGTH;
986 /* add TLS record header */
987 current[TLS_RECORD_OFFSET_TYPE] = TLS_RECORD_TYPE_HANDSHAKE;
988 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_VERSION, 2,
989 TLS_PROTOCOL_VERSION_1_0);
990 lowlevel_integer_to_tls(current + TLS_RECORD_OFFSET_LENGTH, 2,
991 total_size);
992 current += TLS_RECORD_HEADER_LENGTH;
994 /* copy messages */
995 va_start(ap, state);
996 while (1) {
997 const struct tls_compiled_message *msg = va_arg(ap, struct tls_compiled_message *);
998 if (!msg) break;
1000 memcpy(current, msg->data, msg->size);
1001 current += msg->size;
1003 va_end(ap);
1006 static void compile_encrypted_tls_record(struct tls_internal_state *state,
1007 const struct tls_compiled_message *msg)
1009 guchar *plaintext;
1010 gsize plaintext_length;
1011 guchar *mac;
1012 gsize mac_length;
1013 guchar *message;
1014 guchar *encrypted;
1015 gsize encrypted_length;
1017 /* Create plaintext TLS record */
1018 compile_tls_record(state, msg, NULL);
1019 plaintext = state->common.out_buffer;
1020 plaintext_length = state->common.out_length;
1021 if (plaintext_length == 0) /* make Coverity happy */
1022 return;
1024 /* Prepare encryption buffer */
1025 encrypted_length = plaintext_length + state->mac_length;
1026 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT,
1027 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1028 message = g_malloc(encrypted_length);
1029 memcpy(message, plaintext, plaintext_length);
1030 lowlevel_integer_to_tls(message + TLS_RECORD_OFFSET_LENGTH, 2,
1031 encrypted_length - TLS_RECORD_HEADER_LENGTH);
1034 * Calculate MAC
1036 * HMAC_hash(client_write_mac_secret,
1037 * sequence_number + type + version + length + fragment)
1038 * \--- == original TLS record ---/
1040 mac_length = sizeof(guint64) + plaintext_length;
1041 mac = g_malloc(mac_length);
1042 lowlevel_integer_to_tls(mac,
1043 sizeof(guint64),
1044 state->sequence_number++);
1045 memcpy(mac + sizeof(guint64), plaintext, plaintext_length);
1046 g_free(plaintext);
1047 state->mac_func(state->client_write_mac_secret,
1048 state->mac_length,
1049 mac,
1050 mac_length,
1051 message + plaintext_length);
1052 g_free(mac);
1054 /* Encrypt message + MAC */
1055 encrypted = g_malloc(encrypted_length);
1056 memcpy(encrypted, message, TLS_RECORD_HEADER_LENGTH);
1057 sipe_crypt_tls_stream(state->cipher_context,
1058 message + TLS_RECORD_HEADER_LENGTH,
1059 encrypted_length - TLS_RECORD_HEADER_LENGTH,
1060 encrypted + TLS_RECORD_HEADER_LENGTH);
1061 g_free(message);
1063 /* swap buffers */
1064 state->common.out_buffer = encrypted;
1065 state->common.out_length = encrypted_length;
1068 static struct tls_compiled_message *compile_handshake_msg(struct tls_internal_state *state,
1069 const struct msg_descriptor *desc,
1070 gpointer data,
1071 gsize size)
1074 * Estimate the size of the compiled message
1076 * The data structures in the host format have zero or more padding
1077 * bytes added by the compiler to ensure correct element alignments.
1078 * So the sizeof() of the data structure is always equal or greater
1079 * than the space needed for the compiled data. By adding the space
1080 * required for the headers we arrive at a safe estimate
1082 * Therefore we don't need space checks in the compiler functions
1084 gsize total_size = sizeof(struct tls_compiled_message) +
1085 size + TLS_HANDSHAKE_HEADER_LENGTH;
1086 struct tls_compiled_message *msg = g_malloc(total_size);
1087 guchar *handshake = msg->data;
1088 const struct layout_descriptor *ldesc = desc->layouts;
1089 gsize length;
1091 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT,
1092 total_size);
1094 /* add TLS handshake header */
1095 handshake[TLS_HANDSHAKE_OFFSET_TYPE] = desc->type;
1096 state->msg_current = handshake + TLS_HANDSHAKE_HEADER_LENGTH;
1098 while (TLS_LAYOUT_IS_VALID(ldesc)) {
1100 * Avoid "cast increases required alignment" errors
1102 * (void *) tells the compiler that we know what we're
1103 * doing, i.e. we know that the calculated address
1104 * points to correctly aligned data.
1106 ldesc->compiler(state, ldesc,
1107 (void *) ((guchar *) data + ldesc->offset));
1108 ldesc++;
1111 length = state->msg_current - handshake - TLS_HANDSHAKE_HEADER_LENGTH;
1112 lowlevel_integer_to_tls(handshake + TLS_HANDSHAKE_OFFSET_LENGTH,
1113 3, length);
1114 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT,
1115 desc->type, desc->description, length);
1117 msg->size = length + TLS_HANDSHAKE_HEADER_LENGTH;
1119 /* update digest contexts */
1120 sipe_digest_md5_update(state->md5_context, handshake, msg->size);
1121 sipe_digest_sha1_update(state->sha1_context, handshake, msg->size);
1123 return(msg);
1127 * Specific TLS data verficiation & message compilers
1129 static struct tls_compiled_message *tls_client_certificate(struct tls_internal_state *state)
1131 struct Certificate_host *certificate;
1132 gsize certificate_length = sipe_cert_crypto_raw_length(state->certificate);
1133 struct tls_compiled_message *msg;
1135 /* setup our response */
1136 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1137 certificate = g_malloc0(sizeof(struct Certificate_host) + 3 +
1138 certificate_length);
1139 certificate->certificate.elements = certificate_length + 3;
1140 lowlevel_integer_to_tls((guchar *) certificate->certificate.placeholder, 3,
1141 certificate_length);
1142 memcpy((guchar *) certificate->certificate.placeholder + 3,
1143 sipe_cert_crypto_raw(state->certificate),
1144 certificate_length);
1146 msg = compile_handshake_msg(state, &Certificate_m, certificate,
1147 sizeof(struct Certificate_host) + certificate_length + 3);
1148 g_free(certificate);
1150 return(msg);
1153 static gboolean check_cipher_suite(struct tls_internal_state *state)
1155 struct tls_parsed_integer *cipher_suite = g_hash_table_lookup(state->data,
1156 "CipherSuite");
1157 const gchar *label = NULL;
1159 if (!cipher_suite) {
1160 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1161 return(FALSE);
1164 switch (cipher_suite->value) {
1165 case TLS_RSA_EXPORT_WITH_RC4_40_MD5:
1166 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1167 state->key_length = 40 / 8;
1168 state->mac_func = sipe_digest_hmac_md5;
1169 label = "MD5";
1170 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1171 break;
1173 case TLS_RSA_WITH_RC4_128_MD5:
1174 state->mac_length = SIPE_DIGEST_HMAC_MD5_LENGTH;
1175 state->key_length = 128 / 8;
1176 state->mac_func = sipe_digest_hmac_md5;
1177 label = "MD5";
1178 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_MD5;
1179 break;
1181 case TLS_RSA_WITH_RC4_128_SHA:
1182 state->mac_length = SIPE_DIGEST_HMAC_SHA1_LENGTH;
1183 state->key_length = 128 / 8;
1184 state->mac_func = sipe_digest_hmac_sha1;
1185 label = "SHA-1";
1186 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_SHA1;
1187 break;
1189 default:
1190 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1191 cipher_suite->value);
1192 break;
1195 if (label)
1196 SIPE_DEBUG_INFO("check_cipher_suite: KEY(stream cipher RC4) %" G_GSIZE_FORMAT ", MAC(%s) %" G_GSIZE_FORMAT,
1197 state->key_length, label, state->mac_length);
1199 return(label != NULL);
1202 static void tls_calculate_secrets(struct tls_internal_state *state)
1204 gsize length = 2 * (state->mac_length + state->key_length);
1205 guchar *random;
1207 /* Generate pre-master secret */
1208 sipe_tls_fill_random(&state->pre_master_secret,
1209 TLS_ARRAY_MASTER_SECRET_LENGTH * 8); /* bits */
1210 lowlevel_integer_to_tls(state->pre_master_secret.buffer, 2,
1211 TLS_PROTOCOL_VERSION_1_0);
1212 debug_secrets(state, "tls_calculate_secrets: pre-master secret",
1213 state->pre_master_secret.buffer,
1214 state->pre_master_secret.length);
1217 * Calculate master secret
1219 * master_secret = PRF(pre_master_secret,
1220 * "master secret",
1221 * ClientHello.random + ServerHello.random)
1223 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1224 memcpy(random,
1225 state->client_random.buffer,
1226 TLS_ARRAY_RANDOM_LENGTH);
1227 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1228 state->server_random.buffer,
1229 TLS_ARRAY_RANDOM_LENGTH);
1230 state->master_secret = sipe_tls_prf(state,
1231 state->pre_master_secret.buffer,
1232 state->pre_master_secret.length,
1233 (guchar *) "master secret",
1235 random,
1236 TLS_ARRAY_RANDOM_LENGTH * 2,
1237 TLS_ARRAY_MASTER_SECRET_LENGTH);
1238 debug_secrets(state, "tls_calculate_secrets: master secret ",
1239 state->master_secret,
1240 TLS_ARRAY_MASTER_SECRET_LENGTH);
1243 * Calculate session key material
1245 * key_block = PRF(master_secret,
1246 * "key expansion",
1247 * ServerHello.random + ClientHello.random)
1249 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT,
1250 length);
1251 memcpy(random,
1252 state->server_random.buffer,
1253 TLS_ARRAY_RANDOM_LENGTH);
1254 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1255 state->client_random.buffer,
1256 TLS_ARRAY_RANDOM_LENGTH);
1257 state->key_block = sipe_tls_prf(state,
1258 state->master_secret,
1259 TLS_ARRAY_MASTER_SECRET_LENGTH,
1260 (guchar *) "key expansion",
1262 random,
1263 TLS_ARRAY_RANDOM_LENGTH * 2,
1264 length);
1265 g_free(random);
1266 debug_secrets(state, "tls_calculate_secrets: key block ",
1267 state->key_block, length);
1269 /* partition key block */
1270 state->client_write_mac_secret = state->key_block;
1271 state->server_write_mac_secret = state->key_block + state->mac_length;
1272 state->client_write_secret = state->key_block + 2 * state->mac_length;
1273 state->server_write_secret = state->key_block + 2 * state->mac_length + state->key_length;
1275 /* initialize cipher context */
1276 state->cipher_context = sipe_crypt_tls_start(state->client_write_secret,
1277 state->key_length);
1280 #if 0 /* NOT NEEDED? */
1281 /* signing */
1282 static guchar *tls_pkcs1_private_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1283 const guchar *data,
1284 gsize data_length,
1285 gsize buffer_length)
1287 gsize pad_length;
1288 guchar *pad_buffer;
1290 if (data_length + 3 > buffer_length) ||
1291 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */)
1292 return(NULL);
1294 pad_length = buffer_length - data_length - 3;
1295 pad_buffer = g_malloc(buffer_length);
1297 /* PKCS1 private key block padding */
1298 pad_buffer[0] = 0; /* +1 */
1299 pad_buffer[1] = 1; /* +2 */
1300 memset(pad_buffer + 2, 0xFF, pad_length);
1301 pad_buffer[2 + pad_length] = 0; /* +3 */
1302 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1304 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1305 debug_secrets(state, "tls_pkcs1_private_padding: ",
1306 pad_buffer, buffer_length);
1307 #endif
1309 return(pad_buffer);
1311 #endif
1313 /* encryption */
1314 static guchar *tls_pkcs1_public_padding(SIPE_UNUSED_PARAMETER struct tls_internal_state *state,
1315 const guchar *data,
1316 gsize data_length,
1317 gsize buffer_length)
1319 gsize pad_length, random_count;
1320 guchar *pad_buffer, *random;
1322 if ((data_length + 3 > buffer_length) ||
1323 (buffer_length == 0)) /* this is dead code, but makes Coverity happy */
1324 return(NULL);
1326 pad_length = buffer_length - data_length - 3;
1327 pad_buffer = g_malloc(buffer_length);
1329 /* PKCS1 public key block padding */
1330 pad_buffer[0] = 0; /* +1 */
1331 pad_buffer[1] = 2; /* +2 */
1332 for (random = pad_buffer + 2, random_count = pad_length;
1333 random_count > 0;
1334 random_count--) {
1335 guchar byte;
1336 /* non-zero random byte */
1337 while ((byte = rand() & 0xFF) == 0);
1338 *random++ = byte;
1340 pad_buffer[2 + pad_length] = 0; /* +3 */
1341 memcpy(pad_buffer + 3 + pad_length, data, data_length);
1343 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1344 debug_secrets(state, "tls_pkcs1_private_padding: ",
1345 pad_buffer, buffer_length);
1346 #endif
1348 return(pad_buffer);
1351 static struct tls_compiled_message *tls_client_key_exchange(struct tls_internal_state *state)
1353 struct tls_parsed_array *server_random;
1354 struct tls_parsed_array *server_certificate;
1355 struct ClientKeyExchange_host *exchange;
1356 gsize server_certificate_length;
1357 guchar *padded;
1358 struct tls_compiled_message *msg;
1360 /* check for required data fields */
1361 if (!check_cipher_suite(state))
1362 return(NULL);
1363 server_random = g_hash_table_lookup(state->data, "Random");
1364 if (!server_random) {
1365 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1366 return(NULL);
1368 server_certificate = g_hash_table_lookup(state->data, "Certificate");
1369 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1370 if (!server_certificate || (server_certificate->length < 3)) {
1371 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1372 return(FALSE);
1374 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT" bytes",
1375 server_certificate->length);
1376 /* first certificate is the server certificate */
1377 server_certificate_length = lowlevel_integer_to_host(server_certificate->data,
1379 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT" bytes",
1380 server_certificate_length);
1381 if ((server_certificate_length + 3) > server_certificate->length) {
1382 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1384 state->server_certificate = sipe_cert_crypto_import(server_certificate->data + 3,
1385 server_certificate_length);
1386 if (!state->server_certificate) {
1387 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1388 return(FALSE);
1390 /* server public key modulus length */
1391 server_certificate_length = sipe_cert_crypto_modulus_length(state->server_certificate);
1392 if (server_certificate_length < TLS_ARRAY_MASTER_SECRET_LENGTH) {
1393 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT ")",
1394 server_certificate_length);
1395 return(FALSE);
1397 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT,
1398 server_certificate_length);
1400 /* found all the required fields */
1401 state->server_random.length = server_random->length;
1402 state->server_random.buffer = g_memdup(server_random->data,
1403 server_random->length);
1404 tls_calculate_secrets(state);
1406 /* ClientKeyExchange */
1407 padded = tls_pkcs1_public_padding(state,
1408 state->pre_master_secret.buffer,
1409 state->pre_master_secret.length,
1410 server_certificate_length);
1411 if (!padded) {
1412 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: padding of pre-master secret failed");
1413 return(NULL);
1415 exchange = g_malloc0(sizeof(struct ClientKeyExchange_host) +
1416 server_certificate_length);
1417 exchange->secret.elements = server_certificate_length;
1418 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state->server_certificate),
1419 server_certificate_length,
1420 padded,
1421 (guchar *) exchange->secret.placeholder)) {
1422 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1423 g_free(exchange);
1424 g_free(padded);
1425 return(NULL);
1427 g_free(padded);
1429 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1430 debug_secrets(state, "tls_client_key_exchange: secret (encr) ",
1431 (guchar *) exchange->secret.placeholder,
1432 server_certificate_length);
1433 #endif
1435 msg = compile_handshake_msg(state, &ClientKeyExchange_m, exchange,
1436 sizeof(struct ClientKeyExchange_host) + server_certificate_length);
1437 g_free(exchange);
1439 return(msg);
1442 static struct tls_compiled_message *tls_certificate_verify(struct tls_internal_state *state)
1444 struct CertificateVerify_host *verify;
1445 struct tls_compiled_message *msg;
1446 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1447 guchar *signature;
1448 gsize length;
1450 /* calculate digests */
1451 sipe_digest_md5_end(state->md5_context, digests);
1452 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1454 /* sign digests */
1455 signature = sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state->certificate),
1456 digests,
1457 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1458 &length);
1459 g_free(digests);
1460 if (!signature) {
1461 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1462 return(NULL);
1465 /* CertificateVerify */
1466 verify = g_malloc0(sizeof(struct CertificateVerify_host) +
1467 length);
1468 verify->signature.elements = length;
1469 memcpy(verify->signature.placeholder, signature, length);
1470 g_free(signature);
1472 msg = compile_handshake_msg(state, &CertificateVerify_m, verify,
1473 sizeof(struct CertificateVerify_host) + length);
1474 g_free(verify);
1476 return(msg);
1479 static struct tls_compiled_message *tls_client_finished(struct tls_internal_state *state)
1481 guchar *digests = g_malloc(SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH);
1482 guchar *verify;
1483 struct tls_compiled_message *cmsg;
1484 struct Finished_host msg;
1486 /* calculate digests */
1487 sipe_digest_md5_end(state->md5_context, digests);
1488 sipe_digest_sha1_end(state->sha1_context, digests + SIPE_DIGEST_MD5_LENGTH);
1491 * verify_data = PRF(master_secret, "client finished",
1492 * MD5(handshake_messages) +
1493 * SHA-1(handshake_messages)) [0..11];
1495 verify = sipe_tls_prf(state,
1496 state->master_secret,
1497 TLS_ARRAY_MASTER_SECRET_LENGTH,
1498 (guchar *) "client finished",
1500 digests,
1501 SIPE_DIGEST_MD5_LENGTH + SIPE_DIGEST_SHA1_LENGTH,
1502 TLS_ARRAY_VERIFY_LENGTH);
1503 g_free(digests);
1504 memcpy(msg.verify.verify, verify, TLS_ARRAY_VERIFY_LENGTH);
1505 g_free(verify);
1507 cmsg = compile_handshake_msg(state, &Finished_m, &msg, sizeof(msg));
1509 return(cmsg);
1513 * TLS state handling
1516 static gboolean tls_client_hello(struct tls_internal_state *state)
1518 guint32 now = time(NULL);
1519 guint32 now_N = GUINT32_TO_BE(now);
1520 struct ClientHello_host msg = {
1521 { TLS_PROTOCOL_VERSION_1_0 },
1522 { 0, { 0 } },
1523 { 0 /* empty SessionID */ },
1524 { 3,
1526 TLS_RSA_WITH_RC4_128_MD5,
1527 TLS_RSA_WITH_RC4_128_SHA,
1528 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1531 { 1,
1533 TLS_COMP_METHOD_NULL
1537 struct tls_compiled_message *cmsg;
1539 /* First 4 bytes of client_random is the current timestamp */
1540 sipe_tls_fill_random(&state->client_random,
1541 TLS_ARRAY_RANDOM_LENGTH * 8); /* -> bits */
1542 memcpy(state->client_random.buffer, &now_N, sizeof(now_N));
1543 memcpy(msg.random.random, state->client_random.buffer,
1544 TLS_ARRAY_RANDOM_LENGTH);
1546 cmsg = compile_handshake_msg(state, &ClientHello_m, &msg, sizeof(msg));
1547 compile_tls_record(state, cmsg, NULL);
1548 g_free(cmsg);
1550 if (sipe_backend_debug_enabled())
1551 state->debug = g_string_new("");
1553 state->state = TLS_HANDSHAKE_STATE_SERVER_HELLO;
1554 return(tls_record_parse(state, FALSE));
1557 static gboolean tls_server_hello(struct tls_internal_state *state)
1559 struct tls_compiled_message *certificate = NULL;
1560 struct tls_compiled_message *exchange = NULL;
1561 struct tls_compiled_message *verify = NULL;
1562 struct tls_compiled_message *finished = NULL;
1563 gboolean success = FALSE;
1565 if (!tls_record_parse(state, TRUE))
1566 return(FALSE);
1568 if (((certificate = tls_client_certificate(state)) != NULL) &&
1569 ((exchange = tls_client_key_exchange(state)) != NULL) &&
1570 ((verify = tls_certificate_verify(state)) != NULL) &&
1571 ((finished = tls_client_finished(state)) != NULL)) {
1573 /* Part 1 */
1574 compile_tls_record(state, certificate, exchange, verify, NULL);
1576 success = tls_record_parse(state, FALSE);
1577 if (success) {
1578 guchar *part1 = state->common.out_buffer;
1579 gsize part1_length = state->common.out_length;
1580 guchar *part3;
1581 gsize part3_length;
1582 guchar *merged;
1583 gsize length;
1584 /* ChangeCipherSpec is always the same */
1585 static const guchar part2[] = {
1586 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC,
1587 (TLS_PROTOCOL_VERSION_1_0 >> 8) & 0xFF,
1588 TLS_PROTOCOL_VERSION_1_0 & 0xFF,
1589 0x00, 0x01, /* length: 1 byte */
1590 0x01 /* change_cipher_spec(1) */
1593 state->common.out_buffer = NULL;
1595 /* Part 3 - this is the first encrypted record */
1596 compile_encrypted_tls_record(state, finished);
1597 part3 = state->common.out_buffer;
1598 part3_length = state->common.out_length;
1600 /* merge TLS records */
1601 length = part1_length + sizeof(part2) + part3_length;
1602 merged = g_malloc(length);
1604 memcpy(merged, part1, part1_length);
1605 memcpy(merged + part1_length, part2, sizeof(part2));
1606 memcpy(merged + part1_length + sizeof(part2), part3, part3_length);
1607 g_free(part3);
1608 g_free(part1);
1610 /* replace output buffer with merged message */
1611 state->common.out_buffer = merged;
1612 state->common.out_length = length;
1614 state->state = TLS_HANDSHAKE_STATE_FINISHED;
1618 g_free(finished);
1619 g_free(verify);
1620 g_free(exchange);
1621 g_free(certificate);
1622 free_parse_data(state);
1624 return(success);
1627 static gboolean tls_finished(struct tls_internal_state *state)
1629 guchar *random;
1631 if (!tls_record_parse(state, TRUE))
1632 return(FALSE);
1634 /* we don't need the data */
1635 free_parse_data(state);
1638 * Calculate session keys [MS-SIPAE section 3.2.5.1]
1640 * key_material = PRF (master_secret,
1641 * "client EAP encryption",
1642 * ClientHello.random + ServerHello.random)[128]
1643 * = 4 x 32 Bytes
1645 * client key = key_material[3rd 32 Bytes]
1646 * server key = key_material[4th 32 Bytes]
1648 random = g_malloc(TLS_ARRAY_RANDOM_LENGTH * 2);
1649 memcpy(random,
1650 state->client_random.buffer,
1651 TLS_ARRAY_RANDOM_LENGTH);
1652 memcpy(random + TLS_ARRAY_RANDOM_LENGTH,
1653 state->server_random.buffer,
1654 TLS_ARRAY_RANDOM_LENGTH);
1655 state->tls_dsk_key_block = sipe_tls_prf(state,
1656 state->master_secret,
1657 TLS_ARRAY_MASTER_SECRET_LENGTH,
1658 (guchar *) "client EAP encryption",
1660 random,
1661 TLS_ARRAY_RANDOM_LENGTH * 2,
1662 4 * 32);
1663 g_free(random);
1665 #ifdef __SIPE_TLS_CRYPTO_DEBUG
1666 debug_secrets(state, "tls_finished: TLS-DSK key block ",
1667 state->tls_dsk_key_block, 4 * 32);
1668 #endif
1670 state->common.client_key = state->tls_dsk_key_block + 2 * 32;
1671 state->common.server_key = state->tls_dsk_key_block + 3 * 32;
1672 state->common.key_length = 32;
1674 debug_secrets(state, "tls_finished: TLS-DSK client key ",
1675 state->common.client_key,
1676 state->common.key_length);
1677 debug_secrets(state, "tls_finished: TLS-DSK server key ",
1678 state->common.server_key,
1679 state->common.key_length);
1681 state->common.out_buffer = NULL;
1682 state->common.out_length = 0;
1683 state->state = TLS_HANDSHAKE_STATE_COMPLETED;
1685 return(TRUE);
1689 * TLS public API
1692 struct sipe_tls_state *sipe_tls_start(gpointer certificate)
1694 struct tls_internal_state *state;
1696 if (!certificate)
1697 return(NULL);
1699 state = g_new0(struct tls_internal_state, 1);
1700 state->certificate = certificate;
1701 state->state = TLS_HANDSHAKE_STATE_START;
1702 state->md5_context = sipe_digest_md5_start();
1703 state->sha1_context = sipe_digest_sha1_start();
1704 state->common.algorithm = SIPE_TLS_DIGEST_ALGORITHM_NONE;
1706 return((struct sipe_tls_state *) state);
1709 gboolean sipe_tls_next(struct sipe_tls_state *state)
1711 /* Avoid "cast increases required alignment" errors */
1712 struct tls_internal_state *internal = (void *) state;
1713 gboolean success = FALSE;
1715 if (!state)
1716 return(FALSE);
1718 state->out_buffer = NULL;
1720 switch (internal->state) {
1721 case TLS_HANDSHAKE_STATE_START:
1722 success = tls_client_hello(internal);
1723 break;
1725 case TLS_HANDSHAKE_STATE_SERVER_HELLO:
1726 success = tls_server_hello(internal);
1727 break;
1729 case TLS_HANDSHAKE_STATE_FINISHED:
1730 success = tls_finished(internal);
1731 break;
1733 case TLS_HANDSHAKE_STATE_COMPLETED:
1734 case TLS_HANDSHAKE_STATE_FAILED:
1735 /* This should not happen */
1736 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1737 break;
1740 if (!success) {
1741 internal->state = TLS_HANDSHAKE_STATE_FAILED;
1744 return(success);
1747 guint sipe_tls_expires(struct sipe_tls_state *state)
1749 /* Avoid "cast increases required alignment" errors */
1750 struct tls_internal_state *internal = (void *) state;
1752 if (!state)
1753 return(0);
1755 return(sipe_cert_crypto_expires(internal->certificate));
1758 void sipe_tls_free(struct sipe_tls_state *state)
1760 if (state) {
1761 /* Avoid "cast increases required alignment" errors */
1762 struct tls_internal_state *internal = (void *) state;
1764 free_parse_data(internal);
1765 if (internal->debug)
1766 g_string_free(internal->debug, TRUE);
1767 g_free(internal->tls_dsk_key_block);
1768 g_free(internal->key_block);
1769 g_free(internal->master_secret);
1770 sipe_tls_free_random(&internal->pre_master_secret);
1771 sipe_tls_free_random(&internal->client_random);
1772 sipe_tls_free_random(&internal->server_random);
1773 if (internal->cipher_context)
1774 sipe_crypt_tls_destroy(internal->cipher_context);
1775 if (internal->md5_context)
1776 sipe_digest_md5_destroy(internal->md5_context);
1777 if (internal->sha1_context)
1778 sipe_digest_sha1_destroy(internal->sha1_context);
1779 sipe_cert_crypto_destroy(internal->server_certificate);
1780 g_free(state->out_buffer);
1781 g_free(state);
1786 Local Variables:
1787 mode: c
1788 c-file-style: "bsd"
1789 indent-tabs-mode: t
1790 tab-width: 8
1791 End: