blob: 871359af7ae61ff3959e1fcbd33f0f2532903e60 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * TLSv1 common routines
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003 * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 */
14
15#include "includes.h"
16
17#include "common.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080018#include "crypto/sha1.h"
19#include "crypto/sha256.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070020#include "x509v3.h"
21#include "tlsv1_common.h"
22
23
24/*
25 * TODO:
26 * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
27 * Add support for commonly used cipher suites; don't bother with exportable
28 * suites.
29 */
30
31static const struct tls_cipher_suite tls_cipher_suites[] = {
32 { TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL,
33 TLS_HASH_NULL },
34 { TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
35 TLS_HASH_MD5 },
36 { TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
37 TLS_HASH_SHA },
38 { TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC,
39 TLS_HASH_SHA },
40 { TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA,
41 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
42 { TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon,
43 TLS_CIPHER_RC4_128, TLS_HASH_MD5 },
44 { TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon,
45 TLS_CIPHER_DES_CBC, TLS_HASH_SHA },
46 { TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon,
47 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
48 { TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC,
49 TLS_HASH_SHA },
50 { TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon,
51 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA },
52 { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC,
53 TLS_HASH_SHA },
54 { TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080055 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA },
56 { TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_KEY_X_RSA,
57 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
58 { TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_KEY_X_RSA,
59 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 },
60 { TLS_DH_anon_WITH_AES_128_CBC_SHA256, TLS_KEY_X_DH_anon,
61 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA256 },
62 { TLS_DH_anon_WITH_AES_256_CBC_SHA256, TLS_KEY_X_DH_anon,
63 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA256 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070064};
65
66#define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
67#define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites)
68
69
70static const struct tls_cipher_data tls_ciphers[] = {
71 { TLS_CIPHER_NULL, TLS_CIPHER_STREAM, 0, 0, 0,
72 CRYPTO_CIPHER_NULL },
73 { TLS_CIPHER_IDEA_CBC, TLS_CIPHER_BLOCK, 16, 16, 8,
74 CRYPTO_CIPHER_NULL },
75 { TLS_CIPHER_RC2_CBC_40, TLS_CIPHER_BLOCK, 5, 16, 0,
76 CRYPTO_CIPHER_ALG_RC2 },
77 { TLS_CIPHER_RC4_40, TLS_CIPHER_STREAM, 5, 16, 0,
78 CRYPTO_CIPHER_ALG_RC4 },
79 { TLS_CIPHER_RC4_128, TLS_CIPHER_STREAM, 16, 16, 0,
80 CRYPTO_CIPHER_ALG_RC4 },
81 { TLS_CIPHER_DES40_CBC, TLS_CIPHER_BLOCK, 5, 8, 8,
82 CRYPTO_CIPHER_ALG_DES },
83 { TLS_CIPHER_DES_CBC, TLS_CIPHER_BLOCK, 8, 8, 8,
84 CRYPTO_CIPHER_ALG_DES },
85 { TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK, 24, 24, 8,
86 CRYPTO_CIPHER_ALG_3DES },
87 { TLS_CIPHER_AES_128_CBC, TLS_CIPHER_BLOCK, 16, 16, 16,
88 CRYPTO_CIPHER_ALG_AES },
89 { TLS_CIPHER_AES_256_CBC, TLS_CIPHER_BLOCK, 32, 32, 16,
90 CRYPTO_CIPHER_ALG_AES }
91};
92
93#define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers)
94
95
96/**
97 * tls_get_cipher_suite - Get TLS cipher suite
98 * @suite: Cipher suite identifier
99 * Returns: Pointer to the cipher data or %NULL if not found
100 */
101const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite)
102{
103 size_t i;
104 for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++)
105 if (tls_cipher_suites[i].suite == suite)
106 return &tls_cipher_suites[i];
107 return NULL;
108}
109
110
111const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
112{
113 size_t i;
114 for (i = 0; i < NUM_TLS_CIPHER_DATA; i++)
115 if (tls_ciphers[i].cipher == cipher)
116 return &tls_ciphers[i];
117 return NULL;
118}
119
120
121int tls_server_key_exchange_allowed(tls_cipher cipher)
122{
123 const struct tls_cipher_suite *suite;
124
125 /* RFC 2246, Section 7.4.3 */
126 suite = tls_get_cipher_suite(cipher);
127 if (suite == NULL)
128 return 0;
129
130 switch (suite->key_exchange) {
131 case TLS_KEY_X_DHE_DSS:
132 case TLS_KEY_X_DHE_DSS_EXPORT:
133 case TLS_KEY_X_DHE_RSA:
134 case TLS_KEY_X_DHE_RSA_EXPORT:
135 case TLS_KEY_X_DH_anon_EXPORT:
136 case TLS_KEY_X_DH_anon:
137 return 1;
138 case TLS_KEY_X_RSA_EXPORT:
139 return 1 /* FIX: public key len > 512 bits */;
140 default:
141 return 0;
142 }
143}
144
145
146/**
147 * tls_parse_cert - Parse DER encoded X.509 certificate and get public key
148 * @buf: ASN.1 DER encoded certificate
149 * @len: Length of the buffer
150 * @pk: Buffer for returning the allocated public key
151 * Returns: 0 on success, -1 on failure
152 *
153 * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves
154 * the public key from it. The caller is responsible for freeing the public key
155 * by calling crypto_public_key_free().
156 */
157int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk)
158{
159 struct x509_certificate *cert;
160
161 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate",
162 buf, len);
163
164 *pk = crypto_public_key_from_cert(buf, len);
165 if (*pk)
166 return 0;
167
168 cert = x509_certificate_parse(buf, len);
169 if (cert == NULL) {
170 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 "
171 "certificate");
172 return -1;
173 }
174
175 /* TODO
176 * verify key usage (must allow encryption)
177 *
178 * All certificate profiles, key and cryptographic formats are
179 * defined by the IETF PKIX working group [PKIX]. When a key
180 * usage extension is present, the digitalSignature bit must be
181 * set for the key to be eligible for signing, as described
182 * above, and the keyEncipherment bit must be present to allow
183 * encryption, as described above. The keyAgreement bit must be
184 * set on Diffie-Hellman certificates. (PKIX: RFC 3280)
185 */
186
187 *pk = crypto_public_key_import(cert->public_key, cert->public_key_len);
188 x509_certificate_free(cert);
189
190 if (*pk == NULL) {
191 wpa_printf(MSG_ERROR, "TLSv1: Failed to import "
192 "server public key");
193 return -1;
194 }
195
196 return 0;
197}
198
199
200int tls_verify_hash_init(struct tls_verify_hash *verify)
201{
202 tls_verify_hash_free(verify);
203 verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
204 verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
205 verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
206 verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
207 verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
208 verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
209 if (verify->md5_client == NULL || verify->md5_server == NULL ||
210 verify->md5_cert == NULL || verify->sha1_client == NULL ||
211 verify->sha1_server == NULL || verify->sha1_cert == NULL) {
212 tls_verify_hash_free(verify);
213 return -1;
214 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800215#ifdef CONFIG_TLSV12
216 verify->sha256_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
217 0);
218 verify->sha256_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
219 0);
220 verify->sha256_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA256, NULL,
221 0);
222 if (verify->sha256_client == NULL || verify->sha256_server == NULL ||
223 verify->sha256_cert == NULL) {
224 tls_verify_hash_free(verify);
225 return -1;
226 }
227#endif /* CONFIG_TLSV12 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700228 return 0;
229}
230
231
232void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
233 size_t len)
234{
235 if (verify->md5_client && verify->sha1_client) {
236 crypto_hash_update(verify->md5_client, buf, len);
237 crypto_hash_update(verify->sha1_client, buf, len);
238 }
239 if (verify->md5_server && verify->sha1_server) {
240 crypto_hash_update(verify->md5_server, buf, len);
241 crypto_hash_update(verify->sha1_server, buf, len);
242 }
243 if (verify->md5_cert && verify->sha1_cert) {
244 crypto_hash_update(verify->md5_cert, buf, len);
245 crypto_hash_update(verify->sha1_cert, buf, len);
246 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800247#ifdef CONFIG_TLSV12
248 if (verify->sha256_client)
249 crypto_hash_update(verify->sha256_client, buf, len);
250 if (verify->sha256_server)
251 crypto_hash_update(verify->sha256_server, buf, len);
252 if (verify->sha256_cert)
253 crypto_hash_update(verify->sha256_cert, buf, len);
254#endif /* CONFIG_TLSV12 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700255}
256
257
258void tls_verify_hash_free(struct tls_verify_hash *verify)
259{
260 crypto_hash_finish(verify->md5_client, NULL, NULL);
261 crypto_hash_finish(verify->md5_server, NULL, NULL);
262 crypto_hash_finish(verify->md5_cert, NULL, NULL);
263 crypto_hash_finish(verify->sha1_client, NULL, NULL);
264 crypto_hash_finish(verify->sha1_server, NULL, NULL);
265 crypto_hash_finish(verify->sha1_cert, NULL, NULL);
266 verify->md5_client = NULL;
267 verify->md5_server = NULL;
268 verify->md5_cert = NULL;
269 verify->sha1_client = NULL;
270 verify->sha1_server = NULL;
271 verify->sha1_cert = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800272#ifdef CONFIG_TLSV12
273 crypto_hash_finish(verify->sha256_client, NULL, NULL);
274 crypto_hash_finish(verify->sha256_server, NULL, NULL);
275 crypto_hash_finish(verify->sha256_cert, NULL, NULL);
276 verify->sha256_client = NULL;
277 verify->sha256_server = NULL;
278 verify->sha256_cert = NULL;
279#endif /* CONFIG_TLSV12 */
280}
281
282
283int tls_version_ok(u16 ver)
284{
285 if (ver == TLS_VERSION_1)
286 return 1;
287#ifdef CONFIG_TLSV11
288 if (ver == TLS_VERSION_1_1)
289 return 1;
290#endif /* CONFIG_TLSV11 */
291#ifdef CONFIG_TLSV12
292 if (ver == TLS_VERSION_1_2)
293 return 1;
294#endif /* CONFIG_TLSV12 */
295
296 return 0;
297}
298
299
300const char * tls_version_str(u16 ver)
301{
302 switch (ver) {
303 case TLS_VERSION_1:
304 return "1.0";
305 case TLS_VERSION_1_1:
306 return "1.1";
307 case TLS_VERSION_1_2:
308 return "1.2";
309 }
310
311 return "?";
312}
313
314
315int tls_prf(u16 ver, const u8 *secret, size_t secret_len, const char *label,
316 const u8 *seed, size_t seed_len, u8 *out, size_t outlen)
317{
318#ifdef CONFIG_TLSV12
319 if (ver >= TLS_VERSION_1_2) {
320 tls_prf_sha256(secret, secret_len, label, seed, seed_len,
321 out, outlen);
322 return 0;
323 }
324#endif /* CONFIG_TLSV12 */
325
326 return tls_prf_sha1_md5(secret, secret_len, label, seed, seed_len, out,
327 outlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700328}