1 /*
2 * TLSv1 common routines
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4 *
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"
18 #include "x509v3.h"
19 #include "tlsv1_common.h"
20
21
22 /*
23 * TODO:
24 * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
25 * Add support for commonly used cipher suites; don't bother with exportable
26 * suites.
27 */
28
29 static const struct tls_cipher_suite tls_cipher_suites[] = {
30 { TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL,
31 TLS_HASH_NULL },
32 { TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
33 TLS_HASH_MD5 },
34 { TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128,
35 TLS_HASH_SHA },
36 { TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC,
37 TLS_HASH_SHA },
38 { TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA,
39 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
40 { TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon,
41 TLS_CIPHER_RC4_128, TLS_HASH_MD5 },
42 { TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon,
43 TLS_CIPHER_DES_CBC, TLS_HASH_SHA },
44 { TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon,
45 TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA },
46 { TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC,
47 TLS_HASH_SHA },
48 { TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon,
49 TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA },
50 { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC,
51 TLS_HASH_SHA },
52 { TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon,
53 TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA }
54 };
55
56 #define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
57 #define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites)
58
59
60 static const struct tls_cipher_data tls_ciphers[] = {
61 { TLS_CIPHER_NULL, TLS_CIPHER_STREAM, 0, 0, 0,
62 CRYPTO_CIPHER_NULL },
63 { TLS_CIPHER_IDEA_CBC, TLS_CIPHER_BLOCK, 16, 16, 8,
64 CRYPTO_CIPHER_NULL },
65 { TLS_CIPHER_RC2_CBC_40, TLS_CIPHER_BLOCK, 5, 16, 0,
66 CRYPTO_CIPHER_ALG_RC2 },
67 { TLS_CIPHER_RC4_40, TLS_CIPHER_STREAM, 5, 16, 0,
68 CRYPTO_CIPHER_ALG_RC4 },
69 { TLS_CIPHER_RC4_128, TLS_CIPHER_STREAM, 16, 16, 0,
70 CRYPTO_CIPHER_ALG_RC4 },
71 { TLS_CIPHER_DES40_CBC, TLS_CIPHER_BLOCK, 5, 8, 8,
72 CRYPTO_CIPHER_ALG_DES },
73 { TLS_CIPHER_DES_CBC, TLS_CIPHER_BLOCK, 8, 8, 8,
74 CRYPTO_CIPHER_ALG_DES },
75 { TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK, 24, 24, 8,
76 CRYPTO_CIPHER_ALG_3DES },
77 { TLS_CIPHER_AES_128_CBC, TLS_CIPHER_BLOCK, 16, 16, 16,
78 CRYPTO_CIPHER_ALG_AES },
79 { TLS_CIPHER_AES_256_CBC, TLS_CIPHER_BLOCK, 32, 32, 16,
80 CRYPTO_CIPHER_ALG_AES }
81 };
82
83 #define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers)
84
85
86 /**
87 * tls_get_cipher_suite - Get TLS cipher suite
88 * @suite: Cipher suite identifier
89 * Returns: Pointer to the cipher data or %NULL if not found
90 */
tls_get_cipher_suite(u16 suite)91 const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite)
92 {
93 size_t i;
94 for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++)
95 if (tls_cipher_suites[i].suite == suite)
96 return &tls_cipher_suites[i];
97 return NULL;
98 }
99
100
tls_get_cipher_data(tls_cipher cipher)101 const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
102 {
103 size_t i;
104 for (i = 0; i < NUM_TLS_CIPHER_DATA; i++)
105 if (tls_ciphers[i].cipher == cipher)
106 return &tls_ciphers[i];
107 return NULL;
108 }
109
110
tls_server_key_exchange_allowed(tls_cipher cipher)111 int tls_server_key_exchange_allowed(tls_cipher cipher)
112 {
113 const struct tls_cipher_suite *suite;
114
115 /* RFC 2246, Section 7.4.3 */
116 suite = tls_get_cipher_suite(cipher);
117 if (suite == NULL)
118 return 0;
119
120 switch (suite->key_exchange) {
121 case TLS_KEY_X_DHE_DSS:
122 case TLS_KEY_X_DHE_DSS_EXPORT:
123 case TLS_KEY_X_DHE_RSA:
124 case TLS_KEY_X_DHE_RSA_EXPORT:
125 case TLS_KEY_X_DH_anon_EXPORT:
126 case TLS_KEY_X_DH_anon:
127 return 1;
128 case TLS_KEY_X_RSA_EXPORT:
129 return 1 /* FIX: public key len > 512 bits */;
130 default:
131 return 0;
132 }
133 }
134
135
136 /**
137 * tls_parse_cert - Parse DER encoded X.509 certificate and get public key
138 * @buf: ASN.1 DER encoded certificate
139 * @len: Length of the buffer
140 * @pk: Buffer for returning the allocated public key
141 * Returns: 0 on success, -1 on failure
142 *
143 * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves
144 * the public key from it. The caller is responsible for freeing the public key
145 * by calling crypto_public_key_free().
146 */
tls_parse_cert(const u8 * buf,size_t len,struct crypto_public_key ** pk)147 int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk)
148 {
149 struct x509_certificate *cert;
150
151 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate",
152 buf, len);
153
154 *pk = crypto_public_key_from_cert(buf, len);
155 if (*pk)
156 return 0;
157
158 cert = x509_certificate_parse(buf, len);
159 if (cert == NULL) {
160 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 "
161 "certificate");
162 return -1;
163 }
164
165 /* TODO
166 * verify key usage (must allow encryption)
167 *
168 * All certificate profiles, key and cryptographic formats are
169 * defined by the IETF PKIX working group [PKIX]. When a key
170 * usage extension is present, the digitalSignature bit must be
171 * set for the key to be eligible for signing, as described
172 * above, and the keyEncipherment bit must be present to allow
173 * encryption, as described above. The keyAgreement bit must be
174 * set on Diffie-Hellman certificates. (PKIX: RFC 3280)
175 */
176
177 *pk = crypto_public_key_import(cert->public_key, cert->public_key_len);
178 x509_certificate_free(cert);
179
180 if (*pk == NULL) {
181 wpa_printf(MSG_ERROR, "TLSv1: Failed to import "
182 "server public key");
183 return -1;
184 }
185
186 return 0;
187 }
188
189
tls_verify_hash_init(struct tls_verify_hash * verify)190 int tls_verify_hash_init(struct tls_verify_hash *verify)
191 {
192 tls_verify_hash_free(verify);
193 verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
194 verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
195 verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
196 verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
197 verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
198 verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
199 if (verify->md5_client == NULL || verify->md5_server == NULL ||
200 verify->md5_cert == NULL || verify->sha1_client == NULL ||
201 verify->sha1_server == NULL || verify->sha1_cert == NULL) {
202 tls_verify_hash_free(verify);
203 return -1;
204 }
205 return 0;
206 }
207
208
tls_verify_hash_add(struct tls_verify_hash * verify,const u8 * buf,size_t len)209 void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
210 size_t len)
211 {
212 if (verify->md5_client && verify->sha1_client) {
213 crypto_hash_update(verify->md5_client, buf, len);
214 crypto_hash_update(verify->sha1_client, buf, len);
215 }
216 if (verify->md5_server && verify->sha1_server) {
217 crypto_hash_update(verify->md5_server, buf, len);
218 crypto_hash_update(verify->sha1_server, buf, len);
219 }
220 if (verify->md5_cert && verify->sha1_cert) {
221 crypto_hash_update(verify->md5_cert, buf, len);
222 crypto_hash_update(verify->sha1_cert, buf, len);
223 }
224 }
225
226
tls_verify_hash_free(struct tls_verify_hash * verify)227 void tls_verify_hash_free(struct tls_verify_hash *verify)
228 {
229 crypto_hash_finish(verify->md5_client, NULL, NULL);
230 crypto_hash_finish(verify->md5_server, NULL, NULL);
231 crypto_hash_finish(verify->md5_cert, NULL, NULL);
232 crypto_hash_finish(verify->sha1_client, NULL, NULL);
233 crypto_hash_finish(verify->sha1_server, NULL, NULL);
234 crypto_hash_finish(verify->sha1_cert, NULL, NULL);
235 verify->md5_client = NULL;
236 verify->md5_server = NULL;
237 verify->md5_cert = NULL;
238 verify->sha1_client = NULL;
239 verify->sha1_server = NULL;
240 verify->sha1_cert = NULL;
241 }
242