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"
50 * Private part of TLS state tracking
52 enum tls_handshake_state
{
53 TLS_HANDSHAKE_STATE_START
,
54 TLS_HANDSHAKE_STATE_SERVER_HELLO
,
55 TLS_HANDSHAKE_STATE_FINISHED
,
56 TLS_HANDSHAKE_STATE_COMPLETED
,
57 TLS_HANDSHAKE_STATE_FAILED
60 struct tls_internal_state
{
61 struct sipe_tls_state common
;
63 enum tls_handshake_state state
;
68 gpointer server_certificate
;
69 struct sipe_svc_random client_random
;
70 struct sipe_svc_random server_random
;
71 struct sipe_svc_random premaster_secret
;
75 * TLS messages & layout descriptors
79 #define TLS_VECTOR_MAX8 255 /* 2^8 - 1 */
80 #define TLS_VECTOR_MAX16 65535 /* 2^16 - 1 */
81 #define TLS_VECTOR_MAX24 16777215 /* 2^24 - 1 */
83 #define TLS_DATATYPE_RANDOM_LENGTH 32
84 #define TLS_DATATYPE_PREMASTER_SECRET_LENGTH 48
86 #define TLS_PROTOCOL_VERSION_1_0 0x0301
87 #define TLS_PROTOCOL_VERSION_1_1 0x0302
90 #define TLS_RSA_EXPORT_WITH_RC4_40_MD5 0x0003
91 #define TLS_RSA_WITH_RC4_128_MD5 0x0004
92 #define TLS_RSA_WITH_RC4_128_SHA 0x0005
94 /* CompressionMethods */
95 #define TLS_COMP_METHOD_NULL 0
97 #define TLS_RECORD_HEADER_LENGTH 5
98 #define TLS_RECORD_OFFSET_TYPE 0
99 #define TLS_RECORD_TYPE_HANDSHAKE 22
100 #define TLS_RECORD_OFFSET_VERSION 1
101 #define TLS_RECORD_OFFSET_LENGTH 3
103 #define TLS_HANDSHAKE_HEADER_LENGTH 4
104 #define TLS_HANDSHAKE_OFFSET_TYPE 0
105 #define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 1
106 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO 2
107 #define TLS_HANDSHAKE_TYPE_CERTIFICATE 11
108 #define TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ 13
109 #define TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE 14
110 #define TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE 16
111 #define TLS_HANDSHAKE_OFFSET_LENGTH 1
113 struct layout_descriptor
;
114 typedef gboolean
parse_func(struct tls_internal_state
*state
,
115 const struct layout_descriptor
*desc
);
117 /* Defines the strictest alignment requirement */
118 struct tls_compile_integer
;
119 typedef void compile_func(struct tls_internal_state
*state
,
120 const struct layout_descriptor
*desc
,
121 const struct tls_compile_integer
*data
);
123 struct layout_descriptor
{
126 compile_func
*compiler
;
127 gsize min
; /* 0 for fixed/array */
132 #define TLS_LAYOUT_DESCRIPTOR_END { NULL, NULL, NULL, 0, 0, 0 }
133 #define TLS_LAYOUT_IS_VALID(desc) (desc->label)
135 struct msg_descriptor
{
136 const struct msg_descriptor
*next
;
137 const gchar
*description
;
138 const struct layout_descriptor
*layouts
;
143 struct tls_parsed_integer
{
147 struct tls_parsed_array
{
148 gsize length
; /* bytes */
149 const guchar data
[0];
153 struct tls_compile_integer
{
157 struct tls_compile_array
{
158 gsize elements
; /* unused */
159 guchar placeholder
[];
162 struct tls_compile_random
{
163 gsize elements
; /* unused */
164 guchar random
[TLS_DATATYPE_RANDOM_LENGTH
];
167 struct tls_compile_vector
{
168 gsize elements
; /* VECTOR */
172 struct tls_compile_sessionid
{
173 gsize elements
; /* VECTOR */
176 struct tls_compile_cipher
{
177 gsize elements
; /* VECTOR */
181 struct tls_compile_compression
{
182 gsize elements
; /* VECTOR */
187 * TLS message debugging
189 static void debug_hex(struct tls_internal_state
*state
,
190 gsize alternative_length
)
192 GString
*str
= state
->debug
;
199 bytes
= state
->msg_current
;
200 length
= alternative_length
? alternative_length
: state
->msg_remainder
;
203 while (length
-- > 0) {
206 } else if ((count
% 16) == 0) {
207 g_string_append(str
, "\n");
208 } else if ((count
% 8) == 0) {
209 g_string_append(str
, " ");
211 g_string_append_printf(str
, " %02X", *bytes
++);
213 g_string_append(str
, "\n");
216 #define debug_print(state, string) \
217 if (state->debug) g_string_append(state->debug, string)
218 #define debug_printf(state, format, ...) \
219 if (state->debug) g_string_append_printf(state->debug, format, __VA_ARGS__)
224 * Low-level data conversion routines
226 * - host alignment agnostic, i.e. can fetch a word from uneven address
227 * - TLS -> host endianess conversion
228 * - no length check, caller has to do it
229 * - don't modify state
231 static guint
lowlevel_integer_to_host(const guchar
*bytes
,
235 while (length
--) sum
= (sum
<< 8) + *bytes
++;
240 * Generic data type parser routines
242 static gboolean
msg_remainder_check(struct tls_internal_state
*state
,
246 if (length
> state
->msg_remainder
) {
247 SIPE_DEBUG_ERROR("msg_remainder_check: '%s' expected %" G_GSIZE_FORMAT
" bytes, remaining %" G_GSIZE_FORMAT
,
248 label
, length
, state
->msg_remainder
);
254 static gboolean
parse_integer_quiet(struct tls_internal_state
*state
,
259 if (!msg_remainder_check(state
, label
, length
)) return(FALSE
);
260 *result
= lowlevel_integer_to_host(state
->msg_current
, length
);
261 state
->msg_current
+= length
;
262 state
->msg_remainder
-= length
;
266 static gboolean
parse_integer(struct tls_internal_state
*state
,
267 const struct layout_descriptor
*desc
)
270 if (!parse_integer_quiet(state
, desc
->label
, desc
->max
, &value
))
272 debug_printf(state
, "%s/INTEGER%" G_GSIZE_FORMAT
" = %d\n",
273 desc
->label
, desc
->max
, value
);
275 struct tls_parsed_integer
*save
= g_new0(struct tls_parsed_integer
, 1);
277 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
282 static gboolean
parse_array(struct tls_internal_state
*state
,
283 const struct layout_descriptor
*desc
)
285 if (!msg_remainder_check(state
, desc
->label
, desc
->max
))
287 debug_printf(state
, "%s/ARRAY[%" G_GSIZE_FORMAT
"]\n",
288 desc
->label
, desc
->max
);
290 struct tls_parsed_array
*save
= g_malloc0(sizeof(struct tls_parsed_array
) +
292 save
->length
= desc
->max
;
293 memcpy((guchar
*)save
->data
, state
->msg_current
, desc
->max
);
294 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
297 state
->msg_current
+= desc
->max
;
298 state
->msg_remainder
-= desc
->max
;
302 static gboolean
parse_vector(struct tls_internal_state
*state
,
303 const struct layout_descriptor
*desc
)
306 if (!parse_integer_quiet(state
, desc
->label
,
307 (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
308 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1,
311 if (length
< desc
->min
) {
312 SIPE_DEBUG_ERROR("parse_vector: '%s' too short %d, expected %" G_GSIZE_FORMAT
,
313 desc
->label
, length
, desc
->min
);
316 debug_printf(state
, "%s/VECTOR<%d>\n", desc
->label
, length
);
318 struct tls_parsed_array
*save
= g_malloc0(sizeof(struct tls_parsed_array
) +
320 save
->length
= length
;
321 memcpy((guchar
*)save
->data
, state
->msg_current
, length
);
322 g_hash_table_insert(state
->data
, (gpointer
) desc
->label
, save
);
324 state
->msg_current
+= length
;
325 state
->msg_remainder
-= length
;
330 * Specific data type parser routines
338 * Low-level data conversion routines
340 * - host alignment agnostic, i.e. can fetch a word from uneven address
341 * - host -> TLS host endianess conversion
342 * - don't modify state
344 static void lowlevel_integer_to_tls(guchar
*bytes
,
349 bytes
[length
] = value
& 0xFF;
355 * Generic data type compiler routines
357 static void compile_integer(struct tls_internal_state
*state
,
358 const struct layout_descriptor
*desc
,
359 const struct tls_compile_integer
*data
)
361 lowlevel_integer_to_tls(state
->msg_current
, desc
->max
, data
->value
);
362 state
->msg_current
+= desc
->max
;
363 state
->msg_remainder
+= desc
->max
;
366 static void compile_array(struct tls_internal_state
*state
,
367 const struct layout_descriptor
*desc
,
368 const struct tls_compile_integer
*data
)
370 const struct tls_compile_array
*array
= (struct tls_compile_array
*) data
;
371 memcpy(state
->msg_current
, array
->placeholder
, desc
->max
);
372 state
->msg_current
+= desc
->max
;
373 state
->msg_remainder
+= desc
->max
;
376 static void compile_vector(struct tls_internal_state
*state
,
377 const struct layout_descriptor
*desc
,
378 const struct tls_compile_integer
*data
)
380 const struct tls_compile_vector
*vector
= (struct tls_compile_vector
*) data
;
381 gsize length
= vector
->elements
;
382 gsize length_field
= (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
383 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1;
385 lowlevel_integer_to_tls(state
->msg_current
, length_field
, length
);
386 state
->msg_current
+= length_field
;
387 state
->msg_remainder
+= length_field
;
388 memcpy(state
->msg_current
, vector
->placeholder
, length
);
389 state
->msg_current
+= length
;
390 state
->msg_remainder
+= length
;
393 static void compile_vector_int2(struct tls_internal_state
*state
,
394 const struct layout_descriptor
*desc
,
395 const struct tls_compile_integer
*data
)
397 const struct tls_compile_vector
*vector
= (struct tls_compile_vector
*) data
;
398 gsize elements
= vector
->elements
;
399 gsize length
= elements
* sizeof(guint16
);
400 gsize length_field
= (desc
->max
> TLS_VECTOR_MAX16
) ? 3 :
401 (desc
->max
> TLS_VECTOR_MAX8
) ? 2 : 1;
402 const guint
*p
= vector
->placeholder
;
404 lowlevel_integer_to_tls(state
->msg_current
, length_field
, length
);
405 state
->msg_current
+= length_field
;
406 state
->msg_remainder
+= length_field
;
408 lowlevel_integer_to_tls(state
->msg_current
, sizeof(guint16
), *p
++);
409 state
->msg_current
+= sizeof(guint16
);
410 state
->msg_remainder
+= sizeof(guint16
);
415 * Specific data type compiler routines
421 * TLS handshake message layout descriptors
423 struct ClientHello_host
{
424 const struct tls_compile_integer protocol_version
;
425 const struct tls_compile_random random
;
426 const struct tls_compile_sessionid sessionid
;
427 const struct tls_compile_cipher cipher
;
428 const struct tls_compile_compression compression
;
430 #define CLIENTHELLO_OFFSET(a) offsetof(struct ClientHello_host, a)
432 static const struct layout_descriptor
const ClientHello_l
[] = {
433 { "Client Protocol Version", parse_integer
, compile_integer
, 0, 2, CLIENTHELLO_OFFSET(protocol_version
) },
434 { "Random", parse_array
, compile_array
, 0, TLS_DATATYPE_RANDOM_LENGTH
, CLIENTHELLO_OFFSET(random
) },
435 { "SessionID", parse_vector
, compile_vector
, 0, 32, CLIENTHELLO_OFFSET(sessionid
) },
436 { "CipherSuite", parse_vector
, compile_vector_int2
, 2, TLS_VECTOR_MAX16
, CLIENTHELLO_OFFSET(cipher
)},
437 { "CompressionMethod", parse_vector
, compile_vector
, 1, TLS_VECTOR_MAX8
, CLIENTHELLO_OFFSET(compression
) },
438 TLS_LAYOUT_DESCRIPTOR_END
440 static const struct msg_descriptor
const ClientHello_m
= {
441 NULL
, "Client Hello", ClientHello_l
, TLS_HANDSHAKE_TYPE_CLIENT_HELLO
444 static const struct layout_descriptor
const ServerHello_l
[] = {
445 { "Server Protocol Version", parse_integer
, NULL
, 0, 2, 0 },
446 { "Random", parse_array
, NULL
, 0, TLS_DATATYPE_RANDOM_LENGTH
, 0 },
447 { "SessionID", parse_vector
, NULL
, 0, 32, 0 },
448 { "CipherSuite", parse_integer
, NULL
, 0, 2, 0 },
449 { "CompressionMethod", parse_integer
, NULL
, 0, 1, 0 },
450 TLS_LAYOUT_DESCRIPTOR_END
452 static const struct msg_descriptor
const ServerHello_m
= {
453 &ClientHello_m
, "Server Hello", ServerHello_l
, TLS_HANDSHAKE_TYPE_SERVER_HELLO
456 struct Certificate_host
{
457 struct tls_compile_vector certificate
;
459 #define CERTIFICATE_OFFSET(a) offsetof(struct Certificate_host, a)
461 static const struct layout_descriptor
const Certificate_l
[] = {
462 { "Certificate", parse_vector
, compile_vector
, 0, TLS_VECTOR_MAX24
, CERTIFICATE_OFFSET(certificate
) },
463 TLS_LAYOUT_DESCRIPTOR_END
465 static const struct msg_descriptor
const Certificate_m
= {
466 &ServerHello_m
, "Certificate", Certificate_l
, TLS_HANDSHAKE_TYPE_CERTIFICATE
469 static const struct layout_descriptor
const CertificateRequest_l
[] = {
470 { "CertificateType", parse_vector
, NULL
, 1, TLS_VECTOR_MAX8
, 0 },
471 { "DistinguishedName", parse_vector
, NULL
, 0, TLS_VECTOR_MAX16
, 0 },
472 TLS_LAYOUT_DESCRIPTOR_END
474 static const struct msg_descriptor
const CertificateRequest_m
= {
475 &Certificate_m
, "Certificate Request", CertificateRequest_l
, TLS_HANDSHAKE_TYPE_CERTIFICATE_REQ
478 static const struct layout_descriptor
const ServerHelloDone_l
[] = {
479 TLS_LAYOUT_DESCRIPTOR_END
481 static const struct msg_descriptor
const ServerHelloDone_m
= {
482 &CertificateRequest_m
, "Server Hello Done", ServerHelloDone_l
, TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
485 struct ClientKeyExchange_host
{
486 struct tls_compile_vector secret
;
488 #define CLIENTKEYEXCHANGE_OFFSET(a) offsetof(struct ClientKeyExchange_host, a)
490 static const struct layout_descriptor
const ClientKeyExchange_l
[] = {
491 { "Exchange Keys", parse_vector
, compile_vector
, 0, TLS_VECTOR_MAX16
, CLIENTKEYEXCHANGE_OFFSET(secret
) },
492 TLS_LAYOUT_DESCRIPTOR_END
494 static const struct msg_descriptor
const ClientKeyExchange_m
= {
495 &ServerHelloDone_m
, "Client Key Exchange", ClientKeyExchange_l
, TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE
498 #define HANDSHAKE_MSG_DESCRIPTORS &ClientKeyExchange_m
501 * TLS message parsers
503 static gboolean
handshake_parse(struct tls_internal_state
*state
)
505 const guchar
*bytes
= state
->msg_current
;
506 gsize length
= state
->msg_remainder
;
507 gboolean success
= FALSE
;
510 const struct msg_descriptor
*desc
;
515 if (length
< TLS_HANDSHAKE_HEADER_LENGTH
) {
516 debug_print(state
, "CORRUPTED HANDSHAKE HEADER");
520 /* msg length check */
521 msg_length
= lowlevel_integer_to_host(bytes
+ TLS_HANDSHAKE_OFFSET_LENGTH
,
523 if (msg_length
> length
) {
524 debug_print(state
, "HANDSHAKE MESSAGE TOO LONG");
529 msg_type
= bytes
[TLS_HANDSHAKE_OFFSET_TYPE
];
530 for (desc
= HANDSHAKE_MSG_DESCRIPTORS
;
533 if (msg_type
== desc
->type
)
536 debug_printf(state
, "TLS handshake (%" G_GSIZE_FORMAT
" bytes) (%d)",
537 msg_length
, msg_type
);
539 state
->msg_current
= (guchar
*) bytes
+ TLS_HANDSHAKE_HEADER_LENGTH
;
540 state
->msg_remainder
= msg_length
;
543 const struct layout_descriptor
*ldesc
= desc
->layouts
;
545 debug_printf(state
, "%s\n", desc
->description
);
546 while (TLS_LAYOUT_IS_VALID(ldesc
)) {
547 success
= ldesc
->parser(state
, ldesc
);
555 debug_print(state
, "ignored\n");
560 bytes
+= TLS_HANDSHAKE_HEADER_LENGTH
+ msg_length
;
561 length
-= TLS_HANDSHAKE_HEADER_LENGTH
+ msg_length
;
563 debug_print(state
, "------\n");
572 static void free_parse_data(struct tls_internal_state
*state
)
575 g_hash_table_destroy(state
->data
);
580 /* NOTE: we don't support record fragmentation */
581 static gboolean
tls_record_parse(struct tls_internal_state
*state
,
584 const guchar
*bytes
= incoming
? state
->common
.in_buffer
: state
->common
.out_buffer
;
585 gsize length
= incoming
? state
->common
.in_length
: state
->common
.out_length
;
587 const gchar
*version_str
;
589 gboolean success
= FALSE
;
591 debug_printf(state
, "TLS MESSAGE %s\n", incoming
? "INCOMING" : "OUTGOING");
593 /* truncated header check */
594 if (length
< TLS_RECORD_HEADER_LENGTH
) {
595 SIPE_DEBUG_ERROR("tls_record_parse: too short TLS record header (%" G_GSIZE_FORMAT
" bytes)",
600 /* protocol version check */
601 version
= lowlevel_integer_to_host(bytes
+ TLS_RECORD_OFFSET_VERSION
, 2);
602 if (version
< TLS_PROTOCOL_VERSION_1_0
) {
603 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: SSL1/2/3 not supported");
607 case TLS_PROTOCOL_VERSION_1_0
:
608 version_str
= "1.0 (RFC2246)";
610 case TLS_PROTOCOL_VERSION_1_1
:
611 version_str
= "1.1 (RFC4346)";
614 version_str
= "<future protocol version>";
618 /* record length check */
619 record_length
= TLS_RECORD_HEADER_LENGTH
+
620 lowlevel_integer_to_host(bytes
+ TLS_RECORD_OFFSET_LENGTH
, 2);
621 if (record_length
> length
) {
622 SIPE_DEBUG_ERROR_NOFORMAT("tls_record_parse: record too long");
626 /* TLS record header OK */
627 debug_printf(state
, "TLS %s record (%" G_GSIZE_FORMAT
" bytes)\n",
628 version_str
, length
);
629 state
->msg_current
= (guchar
*) bytes
+ TLS_RECORD_HEADER_LENGTH
;
630 state
->msg_remainder
= length
- TLS_RECORD_HEADER_LENGTH
;
632 /* Collect parser data for incoming messages */
634 state
->data
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
637 switch (bytes
[TLS_RECORD_OFFSET_TYPE
]) {
638 case TLS_RECORD_TYPE_HANDSHAKE
:
639 success
= handshake_parse(state
);
643 debug_print(state
, "Unsupported TLS message\n");
649 free_parse_data(state
);
652 SIPE_DEBUG_INFO_NOFORMAT(state
->debug
->str
);
653 g_string_truncate(state
->debug
, 0);
660 * TLS message compiler
662 static void compile_msg(struct tls_internal_state
*state
,
668 * Estimate the size of the compiled message
670 * The data structures in the host format have zero or more padding
671 * bytes added by the compiler to ensure correct element alignments.
672 * So the sizeof() of the data structure is always equal or greater
673 * than the space needed for the compiled data. By adding the space
674 * required for the headers we arrive at a safe estimate
676 * Therefore we don't need space checks in the compiler functions
678 gsize total_size
= size
+
679 TLS_RECORD_HEADER_LENGTH
+
680 TLS_HANDSHAKE_HEADER_LENGTH
* messages
;
681 guchar
*buffer
= g_malloc0(total_size
);
684 SIPE_DEBUG_INFO("compile_msg: buffer size %" G_GSIZE_FORMAT
,
687 state
->msg_current
= buffer
+ TLS_RECORD_HEADER_LENGTH
;
688 state
->msg_remainder
= 0;
690 va_start(ap
, messages
);
692 const struct msg_descriptor
*desc
= va_arg(ap
, struct msg_descriptor
*);
693 const guchar
*data
= va_arg(ap
, gpointer
);
694 const struct layout_descriptor
*ldesc
= desc
->layouts
;
695 guchar
*handshake
= state
->msg_current
;
698 /* add TLS handshake header */
699 handshake
[TLS_HANDSHAKE_OFFSET_TYPE
] = desc
->type
;
700 state
->msg_current
+= TLS_HANDSHAKE_HEADER_LENGTH
;
701 state
->msg_remainder
+= TLS_HANDSHAKE_HEADER_LENGTH
;
703 while (TLS_LAYOUT_IS_VALID(ldesc
)) {
705 * Avoid "cast increases required alignment" errors
707 * (void *) tells the compiler that we know what we're
708 * doing, i.e. we know that the calculated address
709 * points to correctly aligned data.
711 ldesc
->compiler(state
, ldesc
,
712 (void *) (data
+ ldesc
->offset
));
716 length
= state
->msg_current
- handshake
- TLS_HANDSHAKE_HEADER_LENGTH
;
717 lowlevel_integer_to_tls(handshake
+ TLS_HANDSHAKE_OFFSET_LENGTH
,
719 SIPE_DEBUG_INFO("compile_msg: (%d)%s, size %" G_GSIZE_FORMAT
,
720 desc
->type
, desc
->description
, length
);
726 /* add TLS record header */
727 buffer
[TLS_RECORD_OFFSET_TYPE
] = TLS_RECORD_TYPE_HANDSHAKE
;
728 lowlevel_integer_to_tls(buffer
+ TLS_RECORD_OFFSET_VERSION
, 2,
729 TLS_PROTOCOL_VERSION_1_0
);
730 lowlevel_integer_to_tls(buffer
+ TLS_RECORD_OFFSET_LENGTH
, 2,
731 state
->msg_remainder
);
733 state
->common
.out_buffer
= buffer
;
734 state
->common
.out_length
= state
->msg_remainder
+ TLS_RECORD_HEADER_LENGTH
;
736 SIPE_DEBUG_INFO("compile_msg: compiled size %" G_GSIZE_FORMAT
,
737 state
->common
.out_length
);
740 static struct Certificate_host
*tls_client_certificate(struct tls_internal_state
*state
,
741 gsize
*cumulative_length
)
743 struct Certificate_host
*certificate
;
744 gsize certificate_length
= sipe_cert_crypto_raw_length(state
->certificate
);
746 /* setup our response */
747 /* Client Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
748 certificate
= g_malloc0(sizeof(struct Certificate_host
) + 3 +
750 certificate
->certificate
.elements
= certificate_length
+ 3;
751 lowlevel_integer_to_tls((guchar
*) certificate
->certificate
.placeholder
, 3,
753 memcpy((guchar
*) certificate
->certificate
.placeholder
+ 3,
754 sipe_cert_crypto_raw(state
->certificate
),
757 *cumulative_length
+= sizeof(struct Certificate_host
) + certificate_length
;
761 static struct ClientKeyExchange_host
*tls_client_key_exchange(struct tls_internal_state
*state
,
762 gsize
*cumulative_length
)
764 struct tls_parsed_array
*server_random
;
765 struct tls_parsed_array
*server_certificate
;
766 struct ClientKeyExchange_host
*exchange
;
767 gsize server_certificate_length
;
769 /* check for required data fields */
770 server_random
= g_hash_table_lookup(state
->data
, "Random");
771 if (!server_random
) {
772 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server random");
775 server_certificate
= g_hash_table_lookup(state
->data
, "Certificate");
776 /* Server Certificate is VECTOR_MAX24 of VECTOR_MAX24s */
777 if (!server_certificate
|| (server_certificate
->length
< 3)) {
778 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: no server certificate");
781 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate list %" G_GSIZE_FORMAT
" bytes",
782 server_certificate
->length
);
783 /* first certificate is the server certificate */
784 server_certificate_length
= lowlevel_integer_to_host(server_certificate
->data
,
786 SIPE_DEBUG_INFO("tls_client_key_exchange: server certificate %" G_GSIZE_FORMAT
" bytes",
787 server_certificate_length
);
788 if ((server_certificate_length
+ 3) > server_certificate
->length
) {
789 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: truncated server certificate");
791 state
->server_certificate
= sipe_cert_crypto_import(server_certificate
->data
+ 3,
792 server_certificate_length
);
793 if (!state
->server_certificate
) {
794 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: corrupted server certificate");
797 /* server public key modulus length */
798 server_certificate_length
= sipe_cert_crypto_modulus_length(state
->server_certificate
);
799 if (server_certificate_length
< TLS_DATATYPE_PREMASTER_SECRET_LENGTH
) {
800 SIPE_DEBUG_ERROR("tls_client_key_exchange: server public key strength too low (%" G_GSIZE_FORMAT
")",
801 server_certificate_length
);
804 SIPE_DEBUG_INFO("tls_client_key_exchange: server public key strength = %" G_GSIZE_FORMAT
,
805 server_certificate_length
);
807 /* found all the required fields */
808 state
->server_random
.length
= server_random
->length
;
809 state
->server_random
.buffer
= g_memdup(server_random
->data
,
810 server_random
->length
);
812 /* ClientKeyExchange */
813 exchange
= g_malloc0(sizeof(struct ClientKeyExchange_host
) +
814 server_certificate_length
);
815 exchange
->secret
.elements
= server_certificate_length
;
816 sipe_svc_fill_random(&state
->premaster_secret
,
817 TLS_DATATYPE_PREMASTER_SECRET_LENGTH
* 8); /* bits */
818 lowlevel_integer_to_tls(state
->premaster_secret
.buffer
, 2,
819 TLS_PROTOCOL_VERSION_1_0
);
820 if (!sipe_crypt_rsa_encrypt(sipe_cert_crypto_public_key(state
->server_certificate
),
821 TLS_DATATYPE_PREMASTER_SECRET_LENGTH
,
822 state
->premaster_secret
.buffer
,
823 (guchar
*) exchange
->secret
.placeholder
)) {
824 SIPE_DEBUG_ERROR_NOFORMAT("tls_client_key_exchange: encryption of pre-master secret failed");
829 *cumulative_length
+= sizeof(struct ClientKeyExchange_host
) + server_certificate_length
;
837 static gboolean
tls_client_hello(struct tls_internal_state
*state
)
839 guint32 now
= time(NULL
);
840 guint32 now_N
= GUINT32_TO_BE(now
);
841 struct ClientHello_host msg
= {
842 { TLS_PROTOCOL_VERSION_1_0
},
844 { 0 /* empty SessionID */ },
847 TLS_RSA_WITH_RC4_128_MD5
,
848 TLS_RSA_WITH_RC4_128_SHA
,
849 TLS_RSA_EXPORT_WITH_RC4_40_MD5
859 /* First 4 bytes of client_random is the current timestamp */
860 sipe_svc_fill_random(&state
->client_random
,
861 TLS_DATATYPE_RANDOM_LENGTH
* 8); /* -> bits */
862 memcpy(state
->client_random
.buffer
, &now_N
, sizeof(now_N
));
863 memcpy((guchar
*) msg
.random
.random
, state
->client_random
.buffer
,
864 TLS_DATATYPE_RANDOM_LENGTH
);
869 &ClientHello_m
, &msg
);
871 if (sipe_backend_debug_enabled())
872 state
->debug
= g_string_new("");
874 state
->state
= TLS_HANDSHAKE_STATE_SERVER_HELLO
;
875 return(tls_record_parse(state
, FALSE
));
878 static gboolean
tls_server_hello(struct tls_internal_state
*state
)
880 struct Certificate_host
*certificate
= NULL
;
881 struct ClientKeyExchange_host
*exchange
= NULL
;
883 gboolean success
= FALSE
;
885 if (!tls_record_parse(state
, TRUE
))
888 if (((certificate
= tls_client_certificate(state
, &length
)) != NULL
) &&
889 ((exchange
= tls_client_key_exchange(state
, &length
)) != NULL
)) {
894 &Certificate_m
, certificate
,
895 &ClientKeyExchange_m
, exchange
);
897 success
= tls_record_parse(state
, FALSE
);
899 state
->state
= TLS_HANDSHAKE_STATE_FINISHED
;
904 free_parse_data(state
);
909 static gboolean
tls_finished(struct tls_internal_state
*state
)
911 if (!tls_record_parse(state
, TRUE
))
914 /* TBD: data is really not needed? */
915 free_parse_data(state
);
917 state
->common
.out_buffer
= NULL
;
918 state
->common
.out_length
= 0;
919 state
->state
= TLS_HANDSHAKE_STATE_COMPLETED
;
929 struct sipe_tls_state
*sipe_tls_start(gpointer certificate
)
931 struct tls_internal_state
*state
;
936 state
= g_new0(struct tls_internal_state
, 1);
937 state
->certificate
= certificate
;
938 state
->state
= TLS_HANDSHAKE_STATE_START
;
940 return((struct sipe_tls_state
*) state
);
943 gboolean
sipe_tls_next(struct sipe_tls_state
*state
)
945 struct tls_internal_state
*internal
= (struct tls_internal_state
*) state
;
946 gboolean success
= FALSE
;
951 state
->out_buffer
= NULL
;
953 switch (internal
->state
) {
954 case TLS_HANDSHAKE_STATE_START
:
955 success
= tls_client_hello(internal
);
958 case TLS_HANDSHAKE_STATE_SERVER_HELLO
:
959 success
= tls_server_hello(internal
);
962 case TLS_HANDSHAKE_STATE_FINISHED
:
963 success
= tls_finished(internal
);
966 case TLS_HANDSHAKE_STATE_COMPLETED
:
967 case TLS_HANDSHAKE_STATE_FAILED
:
968 /* This should not happen */
969 SIPE_DEBUG_ERROR_NOFORMAT("sipe_tls_next: called in incorrect state!");
974 internal
->state
= TLS_HANDSHAKE_STATE_FAILED
;
980 void sipe_tls_free(struct sipe_tls_state
*state
)
983 struct tls_internal_state
*internal
= (struct tls_internal_state
*) state
;
985 free_parse_data(internal
);
987 g_string_free(internal
->debug
, TRUE
);
988 sipe_svc_free_random(&internal
->client_random
);
989 sipe_svc_free_random(&internal
->server_random
);
990 sipe_svc_free_random(&internal
->premaster_secret
);
991 sipe_cert_crypto_destroy(internal
->server_certificate
);
992 g_free(state
->session_key
);
993 g_free(state
->out_buffer
);