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