Merge branch 'vendor/NCURSES'
[dragonfly.git] / contrib / hostapd / src / tls / tlsv1_common.c
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  */
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
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
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  */
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
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
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
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 }