]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libtls/tls.c
Introducing simple purposes for the TLS stack, switches various options
[thirdparty/strongswan.git] / src / libtls / tls.c
CommitLineData
f7f63c52
MW
1/*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 *
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>.
9 *
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
13 * for more details.
14 */
15
16#include "tls.h"
17
40e384ea
MW
18#include "tls_protection.h"
19#include "tls_compression.h"
20#include "tls_fragmentation.h"
536dbc00 21#include "tls_crypto.h"
4c0c2283
MW
22#include "tls_server.h"
23#include "tls_peer.h"
40e384ea 24
3e962b08
MW
25ENUM_BEGIN(tls_version_names, SSL_2_0, SSL_2_0,
26 "SSLv2");
27ENUM_NEXT(tls_version_names, SSL_3_0, TLS_1_2, SSL_2_0,
f7f63c52
MW
28 "SSLv3",
29 "TLS 1.0",
30 "TLS 1.1",
3e962b08
MW
31 "TLS 1.2");
32ENUM_END(tls_version_names, TLS_1_2);
f7f63c52
MW
33
34ENUM(tls_content_type_names, TLS_CHANGE_CIPHER_SPEC, TLS_APPLICATION_DATA,
35 "ChangeCipherSpec",
36 "Alert",
37 "Handshake",
38 "ApplicationData",
39);
40
41ENUM_BEGIN(tls_handshake_type_names, TLS_HELLO_REQUEST, TLS_SERVER_HELLO,
42 "HelloRequest",
43 "ClientHello",
44 "ServerHello");
45ENUM_NEXT(tls_handshake_type_names, TLS_CERTIFICATE, TLS_CLIENT_KEY_EXCHANGE, TLS_SERVER_HELLO,
46 "Certificate",
47 "ServerKeyExchange",
48 "CertificateRequest",
49 "ServerHelloDone",
50 "CertificateVerify",
51 "ClientKeyExchange");
52ENUM_NEXT(tls_handshake_type_names, TLS_FINISHED, TLS_FINISHED, TLS_CLIENT_KEY_EXCHANGE,
53 "Finished");
54ENUM_END(tls_handshake_type_names, TLS_FINISHED);
dcbbeb2d
MW
55
56
57typedef struct private_tls_t private_tls_t;
58
59/**
60 * Private data of an tls_protection_t object.
61 */
62struct private_tls_t {
63
64 /**
65 * Public tls_t interface.
66 */
67 tls_t public;
68
69 /**
70 * Role this TLS stack acts as.
71 */
72 bool is_server;
40e384ea 73
97abf954
MW
74 /**
75 * Server identity
76 */
77 identification_t *server;
78
79 /**
80 * Peer identity
81 */
82 identification_t *peer;
83
3e962b08
MW
84 /**
85 * Negotiated TLS version
86 */
87 tls_version_t version;
88
96b2fbcc
MW
89 /**
90 * TLS stack purpose, as given to constructor
91 */
92 tls_purpose_t purpose;
93
40e384ea
MW
94 /**
95 * TLS record protection layer
96 */
97 tls_protection_t *protection;
98
99 /**
100 * TLS record compression layer
101 */
102 tls_compression_t *compression;
103
104 /**
105 * TLS record fragmentation layer
106 */
107 tls_fragmentation_t *fragmentation;
4c0c2283 108
536dbc00
MW
109 /**
110 * TLS crypto helper context
111 */
112 tls_crypto_t *crypto;
113
4c0c2283
MW
114 /**
115 * TLS handshake protocol handler
116 */
117 tls_handshake_t *handshake;
1327839d
AS
118
119 /**
120 * TLS application data handler
121 */
122 tls_application_t *application;
dcbbeb2d
MW
123};
124
125METHOD(tls_t, process, status_t,
126 private_tls_t *this, tls_content_type_t type, chunk_t data)
127{
40e384ea 128 return this->protection->process(this->protection, type, data);
dcbbeb2d
MW
129}
130
131METHOD(tls_t, build, status_t,
132 private_tls_t *this, tls_content_type_t *type, chunk_t *data)
133{
40e384ea 134 return this->protection->build(this->protection, type, data);
dcbbeb2d
MW
135}
136
84543e6e
MW
137METHOD(tls_t, is_server, bool,
138 private_tls_t *this)
139{
140 return this->is_server;
141}
142
3e962b08
MW
143METHOD(tls_t, get_version, tls_version_t,
144 private_tls_t *this)
145{
146 return this->version;
147}
148
149METHOD(tls_t, set_version, void,
150 private_tls_t *this, tls_version_t version)
151{
152 this->version = version;
153}
154
96b2fbcc
MW
155METHOD(tls_t, get_purpose, tls_purpose_t,
156 private_tls_t *this)
157{
158 return this->purpose;
159}
160
400df4ca
MW
161METHOD(tls_t, is_complete, bool,
162 private_tls_t *this)
163{
164 return this->crypto->get_eap_msk(this->crypto).len != 0;
165}
166
51313a39
MW
167METHOD(tls_t, get_eap_msk, chunk_t,
168 private_tls_t *this)
169{
170 return this->crypto->get_eap_msk(this->crypto);
171}
172
dcbbeb2d
MW
173METHOD(tls_t, destroy, void,
174 private_tls_t *this)
175{
40e384ea
MW
176 this->protection->destroy(this->protection);
177 this->compression->destroy(this->compression);
178 this->fragmentation->destroy(this->fragmentation);
536dbc00 179 this->crypto->destroy(this->crypto);
4c0c2283 180 this->handshake->destroy(this->handshake);
97abf954
MW
181 this->peer->destroy(this->peer);
182 this->server->destroy(this->server);
1327839d 183 DESTROY_IF(this->application);
40e384ea 184
dcbbeb2d
MW
185 free(this);
186}
187
188/**
189 * See header
190 */
3ddd164e 191tls_t *tls_create(bool is_server, identification_t *server,
96b2fbcc
MW
192 identification_t *peer, tls_purpose_t purpose,
193 tls_application_t *application)
dcbbeb2d
MW
194{
195 private_tls_t *this;
196
96b2fbcc
MW
197 switch (purpose)
198 {
199 case TLS_PURPOSE_EAP_TLS:
200 case TLS_PURPOSE_EAP_TTLS:
201 break;
202 default:
203 return NULL;
204 }
205
dcbbeb2d
MW
206 INIT(this,
207 .public = {
208 .process = _process,
209 .build = _build,
84543e6e 210 .is_server = _is_server,
3e962b08
MW
211 .get_version = _get_version,
212 .set_version = _set_version,
96b2fbcc 213 .get_purpose = _get_purpose,
400df4ca 214 .is_complete = _is_complete,
51313a39 215 .get_eap_msk = _get_eap_msk,
dcbbeb2d
MW
216 .destroy = _destroy,
217 },
218 .is_server = is_server,
3e962b08 219 .version = TLS_1_2,
97abf954
MW
220 .server = server->clone(server),
221 .peer = peer->clone(peer),
1327839d 222 .application = application,
96b2fbcc 223 .purpose = purpose,
dcbbeb2d
MW
224 );
225
96b2fbcc 226 this->crypto = tls_crypto_create(&this->public);
4c0c2283
MW
227 if (is_server)
228 {
3ddd164e 229 this->handshake = &tls_server_create(&this->public, this->crypto,
96b2fbcc 230 this->server, this->peer)->handshake;
4c0c2283
MW
231 }
232 else
233 {
3ddd164e 234 this->handshake = &tls_peer_create(&this->public, this->crypto,
96b2fbcc 235 this->peer, this->server)->handshake;
4c0c2283 236 }
1327839d
AS
237 this->fragmentation = tls_fragmentation_create(this->handshake,
238 this->application);
40e384ea 239 this->compression = tls_compression_create(this->fragmentation);
84543e6e 240 this->protection = tls_protection_create(&this->public, this->compression);
dc9f34be 241 this->crypto->set_protection(this->crypto, this->protection);
40e384ea 242
dcbbeb2d
MW
243 return &this->public;
244}