6 * Copyright (C) 2011 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
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"
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
;
64 enum tls_handshake_state state
;
70 gpointer sha1_context
;
71 gpointer server_certificate
;
72 struct sipe_svc_random client_random
;
73 struct sipe_svc_random server_random
;
74 struct sipe_svc_random pre_master_secret
;
77 guchar
*master_secret
;
79 const guchar
*client_write_mac_secret
;
80 const guchar
*server_write_mac_secret
;
81 const guchar
*client_write_secret
;
82 const guchar
*server_write_secret
;
83 void (*mac_func
)(const guchar
*key
, gsize key_length
,
84 const guchar
*data
, gsize data_length
,
86 gpointer cipher_context
;
87 guint64 sequence_number
;
91 * TLS messages & layout descriptors
95 #define TLS_VECTOR_MAX8 255 /* 2^8 - 1 */
96 #define TLS_VECTOR_MAX16 65535 /* 2^16 - 1 */
97 #define TLS_VECTOR_MAX24 16777215 /* 2^24 - 1 */
99 #define TLS_PROTOCOL_VERSION_1_0 0x0301
100 #define TLS_PROTOCOL_VERSION_1_1 0x0302
103 #define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
104 #define TLS_RSA_WITH_RC4_128_MD5 0x0004
105 #define TLS_RSA_WITH_RC4_128_SHA 0x0005
107 /* CompressionMethods */
108 #define TLS_COMP_METHOD_NULL 0
110 /* various array lengths */
111 #define TLS_ARRAY_RANDOM_LENGTH 32
112 #define TLS_ARRAY_MASTER_SECRET_LENGTH 48
113 #define TLS_ARRAY_VERIFY_LENGTH 12
115 #define TLS_RECORD_HEADER_LENGTH 5
116 #define TLS_RECORD_OFFSET_TYPE 0
117 #define TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC 20
118 #define TLS_RECORD_TYPE_HANDSHAKE 22
119 #define TLS_RECORD_OFFSET_VERSION 1
120 #define TLS_RECORD_OFFSET_LENGTH 3
122 #define TLS_HANDSHAKE_HEADER_LENGTH 4
123 #define TLS_HANDSHAKE_OFFSET_TYPE 0
124 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
125 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
126 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
127 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
128 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
129 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY 15
130 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
131 #define TLS_HANDSHAKE_TYPE_FINISHED 20
132 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
134 struct layout_descriptor
;
135 typedef gboolean
parse_func(struct tls_internal_state
*state
,
136 const struct layout_descriptor
*desc
);
138 /* Defines the strictest alignment requirement */
139 struct tls_compile_integer
;
140 typedef void compile_func(struct tls_internal_state
*state
,
141 const struct layout_descriptor
*desc
,
142 const struct tls_compile_integer
*data
);
144 struct layout_descriptor
{
147 compile_func
*compiler
;
148 gsize min
; /* 0 for fixed/array */
153 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
154 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
156 struct msg_descriptor
{
157 const struct msg_descriptor
*next
;
158 const gchar
*description
;
159 const struct layout_descriptor
*layouts
;
164 struct tls_parsed_integer
{
168 struct tls_parsed_array
{
169 gsize length
; /* bytes */
170 const guchar data
[0];
174 struct tls_compile_integer
{
178 struct tls_compile_array
{
179 gsize elements
; /* unused */
180 guchar placeholder
[];
183 struct tls_compile_random
{
184 gsize elements
; /* unused */
185 guchar random
[TLS_ARRAY_RANDOM_LENGTH
];
188 struct tls_compile_verify
{
189 gsize elements
; /* unused */
190 guchar verify
[TLS_ARRAY_VERIFY_LENGTH
];
193 struct tls_compile_vector
{
194 gsize elements
; /* VECTOR */
198 struct tls_compile_sessionid
{
199 gsize elements
; /* VECTOR */
202 struct tls_compile_cipher
{
203 gsize elements
; /* VECTOR */
207 struct tls_compile_compression
{
208 gsize elements
; /* VECTOR */
212 /* compiled message */
213 struct tls_compiled_message
{
219 * TLS message debugging
221 static void debug_hex(struct tls_internal_state
*state
,
222 gsize alternative_length
)
224 GString
*str
= state
->debug
;
231 bytes
= state
->msg_current
;
232 length
= alternative_length
? alternative_length
: state
->msg_remainder
;
235 while (length
-- > 0) {
238 } else if ((count
% 16) == 0) {
239 g_string_append(str
, "\n");
240 } else if ((count
% 8) == 0) {
241 g_string_append(str
, " ");
243 g_string_append_printf(str
, " %02X", *bytes
++);
245 g_string_append(str
, "\n");
248 #define debug_print(state, string) \
249 if (state->debug) g_string_append(state->debug, string)
250 #define debug_printf(state, format, ...) \
251 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
254 * TLS Pseudorandom Function (PRF) - RFC2246, Section 5
256 static guchar
*sipe_tls_p_md5(const guchar
*secret
,
262 guchar
*output
= NULL
;
265 * output_length == 0 -> illegal
266 * output_length == 1..16 -> iterations = 1
267 * output_length == 17..32 -> iterations = 2
269 if (secret
&& seed
&& (output_length
> 0)) {
270 guint iterations
= (output_length
+ SIPE_DIGEST_HMAC_MD5_LENGTH
- 1) / SIPE_DIGEST_HMAC_MD5_LENGTH
;
271 guchar
*concat
= g_malloc(SIPE_DIGEST_HMAC_MD5_LENGTH
+ seed_length
);
272 guchar A
[SIPE_DIGEST_HMAC_MD5_LENGTH
];
275 SIPE_DEBUG_INFO("p_md5: secret %" G_GSIZE_FORMAT
" bytes, seed %" G_GSIZE_FORMAT
" bytes",
276 secret_length
, seed_length
);
277 SIPE_DEBUG_INFO("p_md5: output %" G_GSIZE_FORMAT
" bytes -> %d iterations",
278 output_length
, iterations
);
280 /* A(1) = HMAC_MD5(secret, A(0)), A(0) = seed */
281 sipe_digest_hmac_md5(secret
, secret_length
,
285 /* Each iteration adds SIPE_DIGEST_HMAC_MD5_LENGTH bytes */
286 p
= output
= g_malloc(iterations
* SIPE_DIGEST_HMAC_MD5_LENGTH
);
288 while (iterations
-- > 0) {
289 /* P_MD5(i) = HMAC_MD5(secret, A(i) + seed), i = 1, 2, ... */
290 guchar P
[SIPE_DIGEST_HMAC_MD5_LENGTH
];
291 memcpy(concat
, A
, SIPE_DIGEST_HMAC_MD5_LENGTH
);
292 memcpy(concat
+ SIPE_DIGEST_HMAC_MD5_LENGTH
, seed
, seed_length
);
293 sipe_digest_hmac_md5(secret
, secret_length
,
294 concat
, SIPE_DIGEST_HMAC_MD5_LENGTH
+ seed_length
,
296 memcpy(p
, P
, SIPE_DIGEST_HMAC_MD5_LENGTH
);
297 p
+= SIPE_DIGEST_HMAC_MD5_LENGTH
;
299 /* A(i+1) = HMAC_MD5(secret, A(i)) */
300 sipe_digest_hmac_md5(secret
, secret_length
,
301 A
, SIPE_DIGEST_HMAC_MD5_LENGTH
,
310 guchar
*sipe_tls_p_sha1(const guchar
*secret
,
316 guchar
*output
= NULL
;
319 * output_length == 0 -> illegal
320 * output_length == 1..20 -> iterations = 1
321 * output_length == 21..40 -> iterations = 2
323 if (secret
&& seed
&& (output_length
> 0)) {
324 guint iterations
= (output_length
+ SIPE_DIGEST_HMAC_SHA1_LENGTH
- 1) / SIPE_DIGEST_HMAC_SHA1_LENGTH
;
325 guchar
*concat
= g_malloc(SIPE_DIGEST_HMAC_SHA1_LENGTH
+ seed_length
);
326 guchar A
[SIPE_DIGEST_HMAC_SHA1_LENGTH
];
329 SIPE_DEBUG_INFO("p_sha1: secret %" G_GSIZE_FORMAT
" bytes, seed %" G_GSIZE_FORMAT
" bytes",
330 secret_length
, seed_length
);
331 SIPE_DEBUG_INFO("p_sha1: output %" G_GSIZE_FORMAT
" bytes -> %d iterations",
332 output_length
, iterations
);
334 /* A(1) = HMAC_SHA1(secret, A(0)), A(0) = seed */
335 sipe_digest_hmac_sha1(secret
, secret_length
,
339 /* Each iteration adds SIPE_DIGEST_HMAC_SHA1_LENGTH bytes */
340 p
= output
= g_malloc(iterations
* SIPE_DIGEST_HMAC_SHA1_LENGTH
);
342 while (iterations
-- > 0) {
343 /* P_SHA1(i) = HMAC_SHA1(secret, A(i) + seed), i = 1, 2, ... */
344 guchar P
[SIPE_DIGEST_HMAC_SHA1_LENGTH
];
345 memcpy(concat
, A
, SIPE_DIGEST_HMAC_SHA1_LENGTH
);
346 memcpy(concat
+ SIPE_DIGEST_HMAC_SHA1_LENGTH
, seed
, seed_length
);
347 sipe_digest_hmac_sha1(secret
, secret_length
,
348 concat
, SIPE_DIGEST_HMAC_SHA1_LENGTH
+ seed_length
,
350 memcpy(p
, P
, SIPE_DIGEST_HMAC_SHA1_LENGTH
);
351 p
+= SIPE_DIGEST_HMAC_SHA1_LENGTH
;
353 /* A(i+1) = HMAC_SHA1(secret, A(i)) */
354 sipe_digest_hmac_sha1(secret
, secret_length
,
355 A
, SIPE_DIGEST_HMAC_SHA1_LENGTH
,
364 static guchar
*sipe_tls_prf(const guchar
*secret
,
372 gsize half
= (secret_length
+ 1) / 2;
373 gsize newseed_length
= label_length
+ seed_length
;
374 /* secret: used as S1; secret2: last half of original secret (S2) */
375 guchar
*secret2
= g_memdup(secret
+ secret_length
- half
, half
);
376 guchar
*newseed
= g_malloc(newseed_length
);
381 * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
382 * P_SHA-1(S2, label + seed);
384 memcpy(newseed
, label
, label_length
);
385 memcpy(newseed
+ label_length
, seed
, seed_length
);
386 md5
= sipe_tls_p_md5(secret
, half
, newseed
, newseed_length
, output_length
);
387 sha1
= sipe_tls_p_sha1(secret2
, half
, newseed
, newseed_length
, output_length
);
388 for (dest
= md5
, src
= sha1
;
403 * Low-level data conversion routines
405 * - host alignment agnostic, i.e. can fetch a word from uneven address
406 * - TLS -> host endianess conversion
407 * - no length check, caller has to do it
408 * - don't modify state
410 static guint
lowlevel_integer_to_host(const guchar
*bytes
,
414 while (length
--) sum
= (sum
<< 8) + *bytes
++;
419 * Generic data type parser routines
421 static gboolean
msg_remainder_check(struct tls_internal_state
*state
,
425 if (length
> state
->msg_remainder
) {
426 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT
" bytes, remaining %" G_GSIZE_FORMAT
,
427 label
, length
, state
->msg_remainder
);
433 static gboolean
parse_integer_quiet(struct tls_internal_state
*state
,
438 if (!msg_remainder_check(state
, label
, length
)) return(FALSE
);
439 *result
= lowlevel_integer_to_host(state
->msg_current
, length
);
440 state
->msg_current
+= length
;
441 state
->msg_remainder
-= length
;
445 static gboolean
parse_integer(struct tls_internal_state
*state
,
446 const struct layout_descriptor
*desc
)
449 if (!parse_integer_quiet(state
, desc
->label
, desc
->max
, &value
))
451 debug_printf(state
, "%s/INTEGER%" G_GSIZE_FORMAT
" = %d\n",
452 desc
->label
, desc
->max
, value
);
454 struct tls_parsed_integer
*save
= g_new0(struct tls_parsed_integer
, 1);
456 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
461 static gboolean
parse_array(struct tls_internal_state
*state
,
462 const struct layout_descriptor
*desc
)
464 if (!msg_remainder_check(state
, desc
->label
, desc
->max
))
466 debug_printf(state
, "%s/ARRAY[%" G_GSIZE_FORMAT
"]\n",
467 desc
->label
, desc
->max
);
469 struct tls_parsed_array
*save
= g_malloc0(sizeof(struct tls_parsed_array
) +
471 save
->length
= desc
->max
;
472 memcpy((guchar
*)save
->data
, state
->msg_current
, desc
->max
);
473 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
476 state
->msg_current
+= desc
->max
;
477 state
->msg_remainder
-= desc
->max
;
481 static gboolean
parse_vector(struct tls_internal_state
*state
,
482 const struct layout_descriptor
*desc
)
485 if (!parse_integer_quiet(state
, desc
->label
,
486 (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
487 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1,
490 if (length
< desc
->min
) {
491 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT
,
492 desc
->label
, length
, desc
->min
);
495 debug_printf(state
, "%s/VECTOR<%d>\n", desc
->label
, length
);
497 struct tls_parsed_array
*save
= g_malloc0(sizeof(struct tls_parsed_array
) +
499 save
->length
= length
;
500 memcpy((guchar
*)save
->data
, state
->msg_current
, length
);
501 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
503 state
->msg_current
+= length
;
504 state
->msg_remainder
-= length
;
509 * Specific data type parser routines
517 * Low-level data conversion routines
519 * - host alignment agnostic, i.e. can fetch a word from uneven address
520 * - host -> TLS host endianess conversion
521 * - don't modify state
523 static void lowlevel_integer_to_tls(guchar
*bytes
,
528 bytes
[length
] = value
& 0xFF;
534 * Generic data type compiler routines
536 static void compile_integer(struct tls_internal_state
*state
,
537 const struct layout_descriptor
*desc
,
538 const struct tls_compile_integer
*data
)
540 lowlevel_integer_to_tls(state
->msg_current
, desc
->max
, data
->value
);
541 state
->msg_current
+= desc
->max
;
544 static void compile_array(struct tls_internal_state
*state
,
545 const struct layout_descriptor
*desc
,
546 const struct tls_compile_integer
*data
)
548 const struct tls_compile_array
*array
= (struct tls_compile_array
*) data
;
549 memcpy(state
->msg_current
, array
->placeholder
, desc
->max
);
550 state
->msg_current
+= desc
->max
;
553 static void compile_vector(struct tls_internal_state
*state
,
554 const struct layout_descriptor
*desc
,
555 const struct tls_compile_integer
*data
)
557 const struct tls_compile_vector
*vector
= (struct tls_compile_vector
*) data
;
558 gsize length
= vector
->elements
;
559 gsize length_field
= (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
560 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1;
562 lowlevel_integer_to_tls(state
->msg_current
, length_field
, length
);
563 state
->msg_current
+= length_field
;
564 memcpy(state
->msg_current
, vector
->placeholder
, length
);
565 state
->msg_current
+= length
;
568 static void compile_vector_int2(struct tls_internal_state
*state
,
569 const struct layout_descriptor
*desc
,
570 const struct tls_compile_integer
*data
)
572 const struct tls_compile_vector
*vector
= (struct tls_compile_vector
*) data
;
573 gsize elements
= vector
->elements
;
574 gsize length
= elements
* sizeof(guint16
);
575 gsize length_field
= (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
576 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1;
577 const guint
*p
= vector
->placeholder
;
579 lowlevel_integer_to_tls(state
->msg_current
, length_field
, length
);
580 state
->msg_current
+= length_field
;
582 lowlevel_integer_to_tls(state
->msg_current
, sizeof(guint16
), *p
++);
583 state
->msg_current
+= sizeof(guint16
);
588 * Specific data type compiler routines
594 * TLS handshake message layout descriptors
596 struct ClientHello_host
{
597 struct tls_compile_integer protocol_version
;
598 struct tls_compile_random random
;
599 struct tls_compile_sessionid sessionid
;
600 struct tls_compile_cipher cipher
;
601 struct tls_compile_compression compression
;
603 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
605 static const struct layout_descriptor
const ClientHello_l
[] = {
606 { "Client Protocol Version", parse_integer
, compile_integer
, 0, 2, CLIENTHELLO_OFFSET(protocol_version
) },
607 { "Random", parse_array
, compile_array
, 0, TLS_ARRAY_RANDOM_LENGTH
, CLIENTHELLO_OFFSET(random
) },
608 { "SessionID", parse_vector
, compile_vector
, 0, 32, CLIENTHELLO_OFFSET(sessionid
) },
609 { "CipherSuite", parse_vector
, compile_vector_int2
, 2, TLS_VECTOR_MAX16
, CLIENTHELLO_OFFSET(cipher
)},
610 { "CompressionMethod", parse_vector
, compile_vector
, 1, TLS_VECTOR_MAX8
, CLIENTHELLO_OFFSET(compression
) },
611 TLS_LAYOUT_DESCRIPTOR_END
613 static const struct msg_descriptor
const ClientHello_m
= {
614 NULL
, "Client Hello", ClientHello_l
, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
617 static const struct layout_descriptor
const ServerHello_l
[] = {
618 { "Server Protocol Version", parse_integer
, NULL
, 0, 2, 0 },
619 { "Random", parse_array
, NULL
, 0, TLS_ARRAY_RANDOM_LENGTH
, 0 },
620 { "SessionID", parse_vector
, NULL
, 0, 32, 0 },
621 { "CipherSuite", parse_integer
, NULL
, 0, 2, 0 },
622 { "CompressionMethod", parse_integer
, NULL
, 0, 1, 0 },
623 TLS_LAYOUT_DESCRIPTOR_END
625 static const struct msg_descriptor
const ServerHello_m
= {
626 &ClientHello_m
, "Server Hello", ServerHello_l
, TLS_HANDSHAKE_TYPE_SERVER_HELLO
629 struct Certificate_host
{
630 struct tls_compile_vector certificate
;
632 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
634 static const struct layout_descriptor
const Certificate_l
[] = {
635 { "Certificate", parse_vector
, compile_vector
, 0, TLS_VECTOR_MAX24
, CERTIFICATE_OFFSET(certificate
) },
636 TLS_LAYOUT_DESCRIPTOR_END
638 static const struct msg_descriptor
const Certificate_m
= {
639 &ServerHello_m
, "Certificate", Certificate_l
, TLS_HANDSHAKE_TYPE_CERTIFICATE
642 static const struct layout_descriptor
const CertificateRequest_l
[] = {
643 { "CertificateType", parse_vector
, NULL
, 1, TLS_VECTOR_MAX8
, 0 },
644 { "DistinguishedName", parse_vector
, NULL
, 0, TLS_VECTOR_MAX16
, 0 },
645 TLS_LAYOUT_DESCRIPTOR_END
647 static const struct msg_descriptor
const CertificateRequest_m
= {
648 &Certificate_m
, "Certificate Request", CertificateRequest_l
, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
651 static const struct layout_descriptor
const ServerHelloDone_l
[] = {
652 TLS_LAYOUT_DESCRIPTOR_END
654 static const struct msg_descriptor
const ServerHelloDone_m
= {
655 &CertificateRequest_m
, "Server Hello Done", ServerHelloDone_l
, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
658 struct ClientKeyExchange_host
{
659 struct tls_compile_vector secret
;
661 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
663 static const struct layout_descriptor
const ClientKeyExchange_l
[] = {
664 { "Exchange Keys", parse_vector
, compile_vector
, 0, TLS_VECTOR_MAX16
, CLIENTKEYEXCHANGE_OFFSET(secret
) },
665 TLS_LAYOUT_DESCRIPTOR_END
667 static const struct msg_descriptor
const ClientKeyExchange_m
= {
668 &ServerHelloDone_m
, "Client Key Exchange", ClientKeyExchange_l
, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
671 struct CertificateVerify_host
{
672 struct tls_compile_vector signature
;
674 #define CERTIFICATEVERIFY_OFFSET(a) offsetof(struct CertificateVerify_host, a)
676 static const struct layout_descriptor
const CertificateVerify_l
[] = {
677 { "Signature", parse_vector
, compile_vector
, 0, TLS_VECTOR_MAX16
, CERTIFICATEVERIFY_OFFSET(signature
) },
678 TLS_LAYOUT_DESCRIPTOR_END
680 static const struct msg_descriptor
const CertificateVerify_m
= {
681 &ClientKeyExchange_m
, "Certificate Verify", CertificateVerify_l
, TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY
684 struct Finished_host
{
685 struct tls_compile_verify verify
;
687 #define FINISHED_OFFSET(a) offsetof(struct Finished_host, a)
689 static const struct layout_descriptor
const Finished_l
[] = {
690 { "Verify Data", parse_array
, compile_array
, 0, TLS_ARRAY_VERIFY_LENGTH
, FINISHED_OFFSET(verify
) },
691 TLS_LAYOUT_DESCRIPTOR_END
693 static const struct msg_descriptor
const Finished_m
= {
694 &CertificateVerify_m
, "Finished", Finished_l
, TLS_HANDSHAKE_TYPE_FINISHED
697 #define HANDSHAKE_MSG_DESCRIPTORS &Finished_m
700 * TLS message parsers
702 static gboolean
handshake_parse(struct tls_internal_state
*state
)
704 const guchar
*bytes
= state
->msg_current
;
705 gsize length
= state
->msg_remainder
;
706 gboolean success
= FALSE
;
709 const struct msg_descriptor
*desc
;
714 if (length
< TLS_HANDSHAKE_HEADER_LENGTH
) {
715 debug_print(state
, "CORRUPTED HANDSHAKE HEADER");
719 /* msg length check */
720 msg_length
= lowlevel_integer_to_host(bytes
+ TLS_HANDSHAKE_OFFSET_LENGTH
,
722 if (msg_length
> length
) {
723 debug_print(state
, "HANDSHAKE MESSAGE TOO LONG");
728 msg_type
= bytes
[TLS_HANDSHAKE_OFFSET_TYPE
];
729 for (desc
= HANDSHAKE_MSG_DESCRIPTORS
;
732 if (msg_type
== desc
->type
)
735 debug_printf(state
, "TLS handshake (%" G_GSIZE_FORMAT
" bytes) (%d)",
736 msg_length
, msg_type
);
738 state
->msg_current
= (guchar
*) bytes
+ TLS_HANDSHAKE_HEADER_LENGTH
;
739 state
->msg_remainder
= msg_length
;
742 const struct layout_descriptor
*ldesc
= desc
->layouts
;
744 debug_printf(state
, "%s\n", desc
->description
);
745 while (TLS_LAYOUT_IS_VALID(ldesc
)) {
746 success
= ldesc
->parser(state
, ldesc
);
754 debug_print(state
, "ignored\n");
759 bytes
+= TLS_HANDSHAKE_HEADER_LENGTH
+ msg_length
;
760 length
-= TLS_HANDSHAKE_HEADER_LENGTH
+ msg_length
;
762 debug_print(state
, "------\n");
771 static void free_parse_data(struct tls_internal_state
*state
)
774 g_hash_table_destroy(state
->data
);
779 /* NOTE: we don't support record fragmentation */
780 static gboolean
tls_record_parse(struct tls_internal_state
*state
,
783 const guchar
*bytes
= incoming
? state
->common
.in_buffer
: state
->common
.out_buffer
;
784 gsize length
= incoming
? state
->common
.in_length
: state
->common
.out_length
;
786 const gchar
*version_str
;
788 gboolean success
= FALSE
;
790 debug_printf(state
, "TLS MESSAGE %s\n", incoming
? "INCOMING" : "OUTGOING");
792 /* truncated header check */
793 if (length
< TLS_RECORD_HEADER_LENGTH
) {
794 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT
" bytes)",
799 /* protocol version check */
800 version
= lowlevel_integer_to_host(bytes
+ TLS_RECORD_OFFSET_VERSION
, 2);
801 if (version
< TLS_PROTOCOL_VERSION_1_0
) {
802 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
806 case TLS_PROTOCOL_VERSION_1_0
:
807 version_str
= "1.0 (RFC2246)";
809 case TLS_PROTOCOL_VERSION_1_1
:
810 version_str
= "1.1 (RFC4346)";
813 version_str
= "<future protocol version>";
817 /* record length check */
818 record_length
= TLS_RECORD_HEADER_LENGTH
+
819 lowlevel_integer_to_host(bytes
+ TLS_RECORD_OFFSET_LENGTH
, 2);
820 if (record_length
> length
) {
821 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
825 /* TLS record header OK */
826 debug_printf(state
, "TLS %s record (%" G_GSIZE_FORMAT
" bytes)\n",
827 version_str
, length
);
828 state
->msg_current
= (guchar
*) bytes
+ TLS_RECORD_HEADER_LENGTH
;
829 state
->msg_remainder
= length
- TLS_RECORD_HEADER_LENGTH
;
831 /* Add incoming message contents to digest contexts */
833 sipe_digest_md5_update(state
->md5_context
,
835 state
->msg_remainder
);
836 sipe_digest_sha1_update(state
->sha1_context
,
838 state
->msg_remainder
);
841 /* Collect parser data for incoming messages */
843 state
->data
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
846 switch (bytes
[TLS_RECORD_OFFSET_TYPE
]) {
847 case TLS_RECORD_TYPE_HANDSHAKE
:
848 success
= handshake_parse(state
);
852 debug_print(state
, "Unsupported TLS message\n");
858 free_parse_data(state
);
861 SIPE_DEBUG_INFO_NOFORMAT(state
->debug
->str
);
862 g_string_truncate(state
->debug
, 0);
869 * TLS message compiler
871 static void compile_tls_record(struct tls_internal_state
*state
,
874 gsize total_size
= 0;
878 /* calculate message size */
881 const struct tls_compiled_message
*msg
= va_arg(ap
, struct tls_compiled_message
*);
883 total_size
+= msg
->size
;
887 SIPE_DEBUG_INFO("compile_tls_record: total size %" G_GSIZE_FORMAT
,
890 state
->common
.out_buffer
= current
= g_malloc(total_size
+ TLS_RECORD_HEADER_LENGTH
);
891 state
->common
.out_length
= total_size
+ TLS_RECORD_HEADER_LENGTH
;
893 /* add TLS record header */
894 current
[TLS_RECORD_OFFSET_TYPE
] = TLS_RECORD_TYPE_HANDSHAKE
;
895 lowlevel_integer_to_tls(current
+ TLS_RECORD_OFFSET_VERSION
, 2,
896 TLS_PROTOCOL_VERSION_1_0
);
897 lowlevel_integer_to_tls(current
+ TLS_RECORD_OFFSET_LENGTH
, 2,
899 current
+= TLS_RECORD_HEADER_LENGTH
;
904 const struct tls_compiled_message
*msg
= va_arg(ap
, struct tls_compiled_message
*);
907 memcpy(current
, msg
->data
, msg
->size
);
908 current
+= msg
->size
;
913 static void compile_encrypted_tls_record(struct tls_internal_state
*state
,
914 const struct tls_compiled_message
*msg
)
917 gsize plaintext_length
;
922 gsize encrypted_length
;
924 /* Create plaintext TLS record */
925 compile_tls_record(state
, msg
, NULL
);
926 plaintext
= state
->common
.out_buffer
;
927 plaintext_length
= state
->common
.out_length
;
929 /* Prepare encryption buffer */
930 encrypted_length
= plaintext_length
+ state
->mac_length
;
931 SIPE_DEBUG_INFO("compile_encrypted_tls_record: total size %" G_GSIZE_FORMAT
,
932 encrypted_length
- TLS_RECORD_HEADER_LENGTH
);
933 message
= g_malloc(encrypted_length
);
934 memcpy(message
, plaintext
, plaintext_length
);
935 lowlevel_integer_to_tls(message
+ TLS_RECORD_OFFSET_LENGTH
, 2,
936 encrypted_length
- TLS_RECORD_HEADER_LENGTH
);
939 mac_length
= sizeof(guint64
) + plaintext_length
;
940 mac
= g_malloc(mac_length
);
941 lowlevel_integer_to_tls(mac
,
943 state
->sequence_number
++);
944 memcpy(mac
+ sizeof(guint64
), plaintext
, plaintext_length
);
945 state
->mac_func(state
->client_write_mac_secret
,
949 message
+ encrypted_length
- state
->mac_length
);
951 /* Encrypt message + MAC */
952 encrypted
= g_malloc(encrypted_length
);
953 memcpy(encrypted
, message
, TLS_RECORD_HEADER_LENGTH
);
954 sipe_crypt_tls_stream(state
->cipher_context
,
955 message
+ TLS_RECORD_HEADER_LENGTH
,
956 encrypted_length
- TLS_RECORD_HEADER_LENGTH
,
957 encrypted
+ TLS_RECORD_HEADER_LENGTH
);
964 state
->common
.out_buffer
= encrypted
;
965 state
->common
.out_length
= encrypted_length
;
968 static struct tls_compiled_message
*compile_handshake_msg(struct tls_internal_state
*state
,
969 const struct msg_descriptor
*desc
,
974 * Estimate the size of the compiled message
976 * The data structures in the host format have zero or more padding
977 * bytes added by the compiler to ensure correct element alignments.
978 * So the sizeof() of the data structure is always equal or greater
979 * than the space needed for the compiled data. By adding the space
980 * required for the headers we arrive at a safe estimate
982 * Therefore we don't need space checks in the compiler functions
984 gsize total_size
= sizeof(struct tls_compiled_message
) +
985 size
+ TLS_HANDSHAKE_HEADER_LENGTH
;
986 struct tls_compiled_message
*msg
= g_malloc(total_size
);
987 guchar
*handshake
= msg
->data
;
988 const struct layout_descriptor
*ldesc
= desc
->layouts
;
991 SIPE_DEBUG_INFO("compile_handshake_msg: buffer size %" G_GSIZE_FORMAT
,
994 /* add TLS handshake header */
995 handshake
[TLS_HANDSHAKE_OFFSET_TYPE
] = desc
->type
;
996 state
->msg_current
= handshake
+ TLS_HANDSHAKE_HEADER_LENGTH
;
998 while (TLS_LAYOUT_IS_VALID(ldesc
)) {
1000 * Avoid "cast increases required alignment" errors
1002 * (void *) tells the compiler that we know what we're
1003 * doing, i.e. we know that the calculated address
1004 * points to correctly aligned data.
1006 ldesc
->compiler(state
, ldesc
,
1007 (void *) ((guchar
*) data
+ ldesc
->offset
));
1011 length
= state
->msg_current
- handshake
- TLS_HANDSHAKE_HEADER_LENGTH
;
1012 lowlevel_integer_to_tls(handshake
+ TLS_HANDSHAKE_OFFSET_LENGTH
,
1014 SIPE_DEBUG_INFO("compile_handshake_msg: (%d)%s, size %" G_GSIZE_FORMAT
,
1015 desc
->type
, desc
->description
, length
);
1017 msg
->size
= length
+ TLS_HANDSHAKE_HEADER_LENGTH
;
1019 /* update digest contexts */
1020 sipe_digest_md5_update(state
->md5_context
, handshake
, msg
->size
);
1021 sipe_digest_sha1_update(state
->sha1_context
, handshake
, msg
->size
);
1027 * Specific TLS data verficiation & message compilers
1029 static struct tls_compiled_message
*tls_client_certificate(struct tls_internal_state
*state
)
1031 struct Certificate_host
*certificate
;
1032 gsize certificate_length
= sipe_cert_crypto_raw_length(state
->certificate
);
1033 struct tls_compiled_message
*msg
;
1035 /* setup our response */
1036 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1037 certificate
= g_malloc0(sizeof(struct Certificate_host
) + 3 +
1038 certificate_length
);
1039 certificate
->certificate
.elements
= certificate_length
+ 3;
1040 lowlevel_integer_to_tls((guchar
*) certificate
->certificate
.placeholder
, 3,
1041 certificate_length
);
1042 memcpy((guchar
*) certificate
->certificate
.placeholder
+ 3,
1043 sipe_cert_crypto_raw(state
->certificate
),
1044 certificate_length
);
1046 msg
= compile_handshake_msg(state
, &Certificate_m
, certificate
,
1047 sizeof(struct Certificate_host
) + certificate_length
);
1048 g_free(certificate
);
1053 static gboolean
check_cipher_suite(struct tls_internal_state
*state
)
1055 struct tls_parsed_integer
*cipher_suite
= g_hash_table_lookup(state
->data
,
1057 const gchar
*label
= NULL
;
1059 if (!cipher_suite
) {
1060 SIPE_DEBUG_ERROR_NOFORMAT("check_cipher_suite: server didn't specify the cipher suite");
1064 switch (cipher_suite
->value
) {
1065 case TLS_RSA_EXPORT_WITH_RC4_40_MD5
:
1066 state
->mac_length
= SIPE_DIGEST_HMAC_MD5_LENGTH
;
1067 state
->key_length
= 40 / 8;
1068 state
->mac_func
= sipe_digest_hmac_md5
;
1072 case TLS_RSA_WITH_RC4_128_MD5
:
1073 state
->mac_length
= SIPE_DIGEST_HMAC_MD5_LENGTH
;
1074 state
->key_length
= 128 / 8;
1075 state
->mac_func
= sipe_digest_hmac_md5
;
1079 case TLS_RSA_WITH_RC4_128_SHA
:
1080 state
->mac_length
= SIPE_DIGEST_HMAC_SHA1_LENGTH
;
1081 state
->key_length
= 128 / 8;
1082 state
->mac_func
= sipe_digest_hmac_sha1
;
1087 SIPE_DEBUG_ERROR("check_cipher_suite: unsupported cipher suite %d",
1088 cipher_suite
->value
);
1093 SIPE_DEBUG_INFO("check_cipher_suite: KEY(stream cipher RC4) %" G_GSIZE_FORMAT
", MAC(%s) %" G_GSIZE_FORMAT
,
1094 state
->key_length
, label
, state
->mac_length
);
1096 return(label
!= NULL
);
1099 static void debug_secrets(struct tls_internal_state
*state
,
1101 const guchar
*secret
,
1102 gsize secret_length
)
1105 g_string_append_printf(state
->debug
, "tls_calculate_secrets: %s ",
1107 while (secret_length
--)
1108 g_string_append_printf(state
->debug
, "%02X", *secret
++);
1109 SIPE_DEBUG_INFO_NOFORMAT(state
->debug
->str
);
1110 g_string_truncate(state
->debug
, 0);
1114 static void tls_calculate_secrets(struct tls_internal_state
*state
)
1116 gsize length
= 2 * (state
->mac_length
+ state
->key_length
);
1119 /* Generate pre-master secret */
1120 sipe_svc_fill_random(&state
->pre_master_secret
,
1121 TLS_ARRAY_MASTER_SECRET_LENGTH
* 8); /* bits */
1122 lowlevel_integer_to_tls(state
->pre_master_secret
.buffer
, 2,
1123 TLS_PROTOCOL_VERSION_1_0
);
1124 debug_secrets(state
, "pre-master secret",
1125 state
->pre_master_secret
.buffer
,
1126 state
->pre_master_secret
.length
);
1129 * Calculate master secret
1131 * master_secret = PRF(pre_master_secret,
1133 * ClientHello.random + ServerHello.random)
1135 random
= g_malloc(TLS_ARRAY_RANDOM_LENGTH
* 2);
1137 state
->client_random
.buffer
,
1138 TLS_ARRAY_RANDOM_LENGTH
);
1139 memcpy(random
+ TLS_ARRAY_RANDOM_LENGTH
,
1140 state
->server_random
.buffer
,
1141 TLS_ARRAY_RANDOM_LENGTH
);
1142 state
->master_secret
= sipe_tls_prf(state
->pre_master_secret
.buffer
,
1143 state
->pre_master_secret
.length
,
1144 (guchar
*) "master secret",
1147 TLS_ARRAY_RANDOM_LENGTH
* 2,
1148 TLS_ARRAY_MASTER_SECRET_LENGTH
);
1149 debug_secrets(state
, "master secret",
1150 state
->master_secret
,
1151 TLS_ARRAY_MASTER_SECRET_LENGTH
);
1154 * Calculate session key material
1156 * key_block = PRF(master_secret,
1158 * ServerHello.random + ClientHello.random)
1160 SIPE_DEBUG_INFO("tls_calculate_secrets: key_block length %" G_GSIZE_FORMAT
,
1163 state
->server_random
.buffer
,
1164 TLS_ARRAY_RANDOM_LENGTH
);
1165 memcpy(random
+ TLS_ARRAY_RANDOM_LENGTH
,
1166 state
->client_random
.buffer
,
1167 TLS_ARRAY_RANDOM_LENGTH
);
1168 state
->key_block
= sipe_tls_prf(state
->master_secret
,
1169 TLS_ARRAY_MASTER_SECRET_LENGTH
,
1170 (guchar
*) "key expansion",
1173 TLS_ARRAY_RANDOM_LENGTH
* 2,
1176 debug_secrets(state
, "key block", state
->key_block
, length
);
1178 /* partition key block */
1179 state
->client_write_mac_secret
= state
->key_block
;
1180 state
->server_write_mac_secret
= state
->key_block
+ state
->mac_length
;
1181 state
->client_write_secret
= state
->key_block
+ 2 * state
->mac_length
;
1182 state
->server_write_secret
= state
->key_block
+ 2 * state
->mac_length
+ state
->key_length
;
1184 /* initialize cipher context */
1185 state
->cipher_context
= sipe_crypt_tls_start(state
->client_write_secret
,
1189 static struct tls_compiled_message
*tls_client_key_exchange(struct tls_internal_state
*state
)
1191 struct tls_parsed_array
*server_random
;
1192 struct tls_parsed_array
*server_certificate
;
1193 struct ClientKeyExchange_host
*exchange
;
1194 gsize server_certificate_length
;
1195 struct tls_compiled_message
*msg
;
1197 /* check for required data fields */
1198 if (!check_cipher_suite(state
))
1200 server_random
= g_hash_table_lookup(state
->data
, "Random");
1201 if (!server_random
) {
1202 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
1205 server_certificate
= g_hash_table_lookup(state
->data
, "Certificate");
1206 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
1207 if (!server_certificate
|| (server_certificate
->length
< 3)) {
1208 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
1211 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT
" bytes",
1212 server_certificate
->length
);
1213 /* first certificate is the server certificate */
1214 server_certificate_length
= lowlevel_integer_to_host(server_certificate
->data
,
1216 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT
" bytes",
1217 server_certificate_length
);
1218 if ((server_certificate_length
+ 3) > server_certificate
->length
) {
1219 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
1221 state
->server_certificate
= sipe_cert_crypto_import(server_certificate
->data
+ 3,
1222 server_certificate_length
);
1223 if (!state
->server_certificate
) {
1224 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
1227 /* server public key modulus length */
1228 server_certificate_length
= sipe_cert_crypto_modulus_length(state
->server_certificate
);
1229 if (server_certificate_length
< TLS_ARRAY_MASTER_SECRET_LENGTH
) {
1230 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT
")",
1231 server_certificate_length
);
1234 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT
,
1235 server_certificate_length
);
1237 /* found all the required fields */
1238 state
->server_random
.length
= server_random
->length
;
1239 state
->server_random
.buffer
= g_memdup(server_random
->data
,
1240 server_random
->length
);
1241 tls_calculate_secrets(state
);
1243 /* ClientKeyExchange */
1244 exchange
= g_malloc0(sizeof(struct ClientKeyExchange_host
) +
1245 server_certificate_length
);
1246 exchange
->secret
.elements
= server_certificate_length
;
1247 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state
->server_certificate
),
1248 TLS_ARRAY_MASTER_SECRET_LENGTH
,
1249 state
->pre_master_secret
.buffer
,
1250 (guchar
*) exchange
->secret
.placeholder
)) {
1251 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
1256 msg
= compile_handshake_msg(state
, &ClientKeyExchange_m
, exchange
,
1257 sizeof(struct ClientKeyExchange_host
) + server_certificate_length
);
1263 static struct tls_compiled_message
*tls_certificate_verify(struct tls_internal_state
*state
)
1265 struct CertificateVerify_host
*verify
;
1266 struct tls_compiled_message
*msg
;
1267 guchar
*digests
= g_malloc(SIPE_DIGEST_MD5_LENGTH
+ SIPE_DIGEST_SHA1_LENGTH
);
1271 /* calculate digests */
1272 sipe_digest_md5_end(state
->md5_context
, digests
);
1273 sipe_digest_sha1_end(state
->sha1_context
, digests
+ SIPE_DIGEST_MD5_LENGTH
);
1276 signature
= sipe_crypt_rsa_sign(sipe_cert_crypto_private_key(state
->certificate
),
1278 SIPE_DIGEST_MD5_LENGTH
+ SIPE_DIGEST_SHA1_LENGTH
,
1282 SIPE_DEBUG_ERROR_NOFORMAT("tls_certificate_verify: signing of handshake digests failed");
1286 /* CertificateVerify */
1287 verify
= g_malloc0(sizeof(struct CertificateVerify_host
) +
1289 verify
->signature
.elements
= length
;
1290 memcpy(verify
->signature
.placeholder
, signature
, length
);
1292 msg
= compile_handshake_msg(state
, &CertificateVerify_m
, verify
,
1293 sizeof(struct CertificateVerify_host
) + length
);
1299 static struct tls_compiled_message
*tls_client_finished(struct tls_internal_state
*state
)
1301 guchar
*digests
= g_malloc(SIPE_DIGEST_MD5_LENGTH
+ SIPE_DIGEST_SHA1_LENGTH
);
1303 struct tls_compiled_message
*cmsg
;
1304 struct Finished_host msg
;
1306 /* calculate digests */
1307 sipe_digest_md5_end(state
->md5_context
, digests
);
1308 sipe_digest_sha1_end(state
->sha1_context
, digests
+ SIPE_DIGEST_MD5_LENGTH
);
1311 * verify_data = PRF(master_secret, "client finished",
1312 * MD5(handshake_messages) +
1313 * SHA-1(handshake_messages)) [0..11];
1315 verify
= sipe_tls_prf(state
->master_secret
,
1316 TLS_ARRAY_MASTER_SECRET_LENGTH
,
1317 (guchar
*) "client finished",
1320 SIPE_DIGEST_MD5_LENGTH
+ SIPE_DIGEST_SHA1_LENGTH
,
1321 TLS_ARRAY_VERIFY_LENGTH
);
1323 memcpy(msg
.verify
.verify
, verify
, TLS_ARRAY_VERIFY_LENGTH
);
1326 cmsg
= compile_handshake_msg(state
, &Finished_m
, &msg
, sizeof(msg
));
1332 * TLS state handling
1335 static gboolean
tls_client_hello(struct tls_internal_state
*state
)
1337 guint32 now
= time(NULL
);
1338 guint32 now_N
= GUINT32_TO_BE(now
);
1339 struct ClientHello_host msg
= {
1340 { TLS_PROTOCOL_VERSION_1_0
},
1342 { 0 /* empty SessionID */ },
1345 TLS_RSA_WITH_RC4_128_MD5
,
1346 TLS_RSA_WITH_RC4_128_SHA
,
1347 TLS_RSA_EXPORT_WITH_RC4_40_MD5
1352 TLS_COMP_METHOD_NULL
1356 struct tls_compiled_message
*cmsg
;
1358 /* First 4 bytes of client_random is the current timestamp */
1359 sipe_svc_fill_random(&state
->client_random
,
1360 TLS_ARRAY_RANDOM_LENGTH
* 8); /* -> bits */
1361 memcpy(state
->client_random
.buffer
, &now_N
, sizeof(now_N
));
1362 memcpy(msg
.random
.random
, state
->client_random
.buffer
,
1363 TLS_ARRAY_RANDOM_LENGTH
);
1365 cmsg
= compile_handshake_msg(state
, &ClientHello_m
, &msg
, sizeof(msg
));
1366 compile_tls_record(state
, cmsg
, NULL
);
1369 if (sipe_backend_debug_enabled())
1370 state
->debug
= g_string_new("");
1372 state
->state
= TLS_HANDSHAKE_STATE_SERVER_HELLO
;
1373 return(tls_record_parse(state
, FALSE
));
1376 static gboolean
tls_server_hello(struct tls_internal_state
*state
)
1378 struct tls_compiled_message
*certificate
= NULL
;
1379 struct tls_compiled_message
*exchange
= NULL
;
1380 struct tls_compiled_message
*verify
= NULL
;
1381 struct tls_compiled_message
*finished
= NULL
;
1382 gboolean success
= FALSE
;
1384 if (!tls_record_parse(state
, TRUE
))
1387 if (((certificate
= tls_client_certificate(state
)) != NULL
) &&
1388 ((exchange
= tls_client_key_exchange(state
)) != NULL
) &&
1389 ((verify
= tls_certificate_verify(state
)) != NULL
) &&
1390 ((finished
= tls_client_finished(state
)) != NULL
)) {
1393 compile_tls_record(state
, certificate
, exchange
, verify
, NULL
);
1395 success
= tls_record_parse(state
, FALSE
);
1397 guchar
*part1
= state
->common
.out_buffer
;
1398 gsize part1_length
= state
->common
.out_length
;
1403 /* ChangeCipherSpec is always the same */
1404 static const guchar
const part2
[] = {
1405 TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC
,
1406 (TLS_PROTOCOL_VERSION_1_0
>> 8) & 0xFF,
1407 TLS_PROTOCOL_VERSION_1_0
& 0xFF,
1408 0x00, 0x01, /* length: 1 byte */
1409 0x01 /* change_cipher_spec(1) */
1412 state
->common
.out_buffer
= NULL
;
1414 /* Part 3 - this is the first encrypted record */
1415 compile_encrypted_tls_record(state
, finished
);
1416 part3
= state
->common
.out_buffer
;
1417 part3_length
= state
->common
.out_length
;
1419 /* merge TLS records */
1420 length
= part1_length
+ sizeof(part2
) + part3_length
;
1421 merged
= g_malloc(length
);
1423 memcpy(merged
, part1
, part1_length
);
1424 memcpy(merged
+ part1_length
, part2
, sizeof(part2
));
1425 memcpy(merged
+ part1_length
+ sizeof(part2
), part3
, part3_length
);
1429 /* replace output buffer with merged message */
1430 state
->common
.out_buffer
= merged
;
1431 state
->common
.out_length
= length
;
1433 state
->state
= TLS_HANDSHAKE_STATE_FINISHED
;
1440 g_free(certificate
);
1441 free_parse_data(state
);
1446 static gboolean
tls_finished(struct tls_internal_state
*state
)
1448 if (!tls_record_parse(state
, TRUE
))
1451 /* TBD: data is really not needed? */
1452 free_parse_data(state
);
1454 state
->common
.out_buffer
= NULL
;
1455 state
->common
.out_length
= 0;
1456 state
->state
= TLS_HANDSHAKE_STATE_COMPLETED
;
1466 struct sipe_tls_state
*sipe_tls_start(gpointer certificate
)
1468 struct tls_internal_state
*state
;
1473 state
= g_new0(struct tls_internal_state
, 1);
1474 state
->certificate
= certificate
;
1475 state
->state
= TLS_HANDSHAKE_STATE_START
;
1476 state
->md5_context
= sipe_digest_md5_start();
1477 state
->sha1_context
= sipe_digest_sha1_start();
1479 return((struct sipe_tls_state
*) state
);
1482 gboolean
sipe_tls_next(struct sipe_tls_state
*state
)
1484 struct tls_internal_state
*internal
= (struct tls_internal_state
*) state
;
1485 gboolean success
= FALSE
;
1490 state
->out_buffer
= NULL
;
1492 switch (internal
->state
) {
1493 case TLS_HANDSHAKE_STATE_START
:
1494 success
= tls_client_hello(internal
);
1497 case TLS_HANDSHAKE_STATE_SERVER_HELLO
:
1498 success
= tls_server_hello(internal
);
1501 case TLS_HANDSHAKE_STATE_FINISHED
:
1502 success
= tls_finished(internal
);
1505 case TLS_HANDSHAKE_STATE_COMPLETED
:
1506 case TLS_HANDSHAKE_STATE_FAILED
:
1507 /* This should not happen */
1508 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
1513 internal
->state
= TLS_HANDSHAKE_STATE_FAILED
;
1519 void sipe_tls_free(struct sipe_tls_state
*state
)
1522 struct tls_internal_state
*internal
= (struct tls_internal_state
*) state
;
1524 free_parse_data(internal
);
1525 if (internal
->debug
)
1526 g_string_free(internal
->debug
, TRUE
);
1527 g_free(internal
->key_block
);
1528 g_free(internal
->master_secret
);
1529 sipe_svc_free_random(&internal
->pre_master_secret
);
1530 sipe_svc_free_random(&internal
->client_random
);
1531 sipe_svc_free_random(&internal
->server_random
);
1532 if (internal
->cipher_context
)
1533 sipe_crypt_tls_destroy(internal
->cipher_context
);
1534 if (internal
->md5_context
)
1535 sipe_digest_md5_destroy(internal
->md5_context
);
1536 if (internal
->sha1_context
)
1537 sipe_digest_sha1_destroy(internal
->sha1_context
);
1538 sipe_cert_crypto_destroy(internal
->server_certificate
);
1539 g_free(state
->session_key
);
1540 g_free(state
->out_buffer
);