2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 typedef struct private_tls_peer_t private_tls_peer_t
;
30 * Private data of an tls_peer_t object.
32 struct private_tls_peer_t
{
35 * Public tls_peer_t interface.
50 METHOD(tls_handshake_t
, process
, status_t
,
51 private_tls_peer_t
*this, tls_handshake_type_t type
, chunk_t data
)
57 * Build the Client Hello using a given set of ciphers
59 static chunk_t
build_hello(int count
, tls_cipher_suite_t
*suite
, rng_t
*rng
)
63 struct __attribute__((packed
)) {
65 struct __attribute__((packed
)) {
69 struct __attribute__((packed
)) {
70 /* never send a session identifier */
74 struct __attribute__((packed
)) {
76 u_int16_t suite
[count
];
78 struct __attribute__((packed
)) {
79 /* currently NULL compression only */
83 u_int8_t extensions
[0];
86 htoun16(&hello
.session
.len
, 0);
87 htoun16(&hello
.version
, TLS_1_2
);
88 htoun32(&hello
.random
.gmt
, time(NULL
));
89 rng
->get_bytes(rng
, sizeof(hello
.random
.bytes
), (char*)&hello
.random
.bytes
);
90 htoun16(&hello
.cipher
.len
, count
* 2);
91 for (i
= 0; i
< count
; i
++)
93 htoun16(&hello
.cipher
.suite
[i
], suite
[i
]);
95 hello
.compression
.len
= 1;
96 hello
.compression
.method
[0] = 0;
97 return chunk_clone(chunk_create((char*)&hello
, sizeof(hello
)));
101 * Send a client hello
103 static status_t
send_hello(private_tls_peer_t
*this,
104 tls_handshake_type_t
*type
, chunk_t
*data
)
106 tls_cipher_suite_t
*suite
;
110 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
115 count
= this->crypto
->get_cipher_suites(this->crypto
, &suite
);
116 *data
= build_hello(count
, suite
, rng
);
117 *type
= TLS_CLIENT_HELLO
;
123 METHOD(tls_handshake_t
, build
, status_t
,
124 private_tls_peer_t
*this, tls_handshake_type_t
*type
, chunk_t
*data
)
129 this->state
= STATE_HELLO_SENT
;
130 return send_hello(this, type
, data
);
132 return INVALID_STATE
;
136 METHOD(tls_handshake_t
, destroy
, void,
137 private_tls_peer_t
*this)
145 tls_peer_t
*tls_peer_create(tls_crypto_t
*crypto
)
147 private_tls_peer_t
*this;
150 .public.handshake
= {
159 return &this->public;