2 * TLSv1 common routines
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "tlsv1_common.h"
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
29 static const struct tls_cipher_suite tls_cipher_suites
[] = {
30 { TLS_NULL_WITH_NULL_NULL
, TLS_KEY_X_NULL
, TLS_CIPHER_NULL
,
32 { TLS_RSA_WITH_RC4_128_MD5
, TLS_KEY_X_RSA
, TLS_CIPHER_RC4_128
,
34 { TLS_RSA_WITH_RC4_128_SHA
, TLS_KEY_X_RSA
, TLS_CIPHER_RC4_128
,
36 { TLS_RSA_WITH_DES_CBC_SHA
, TLS_KEY_X_RSA
, TLS_CIPHER_DES_CBC
,
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
,
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
,
52 { TLS_DH_anon_WITH_AES_256_CBC_SHA
, TLS_KEY_X_DH_anon
,
53 TLS_CIPHER_AES_256_CBC
, TLS_HASH_SHA
}
56 #define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
57 #define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites)
60 static const struct tls_cipher_data tls_ciphers
[] = {
61 { TLS_CIPHER_NULL
, TLS_CIPHER_STREAM
, 0, 0, 0,
63 { TLS_CIPHER_IDEA_CBC
, TLS_CIPHER_BLOCK
, 16, 16, 8,
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
}
83 #define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers)
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
91 const struct tls_cipher_suite
* tls_get_cipher_suite(u16 suite
)
94 for (i
= 0; i
< NUM_TLS_CIPHER_SUITES
; i
++)
95 if (tls_cipher_suites
[i
].suite
== suite
)
96 return &tls_cipher_suites
[i
];
101 const struct tls_cipher_data
* tls_get_cipher_data(tls_cipher cipher
)
104 for (i
= 0; i
< NUM_TLS_CIPHER_DATA
; i
++)
105 if (tls_ciphers
[i
].cipher
== cipher
)
106 return &tls_ciphers
[i
];
111 int tls_server_key_exchange_allowed(tls_cipher cipher
)
113 const struct tls_cipher_suite
*suite
;
115 /* RFC 2246, Section 7.4.3 */
116 suite
= tls_get_cipher_suite(cipher
);
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
:
128 case TLS_KEY_X_RSA_EXPORT
:
129 return 1 /* FIX: public key len > 512 bits */;
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
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().
147 int tls_parse_cert(const u8
*buf
, size_t len
, struct crypto_public_key
**pk
)
149 struct x509_certificate
*cert
;
151 wpa_hexdump(MSG_MSGDUMP
, "TLSv1: Parse ASN.1 DER certificate",
154 *pk
= crypto_public_key_from_cert(buf
, len
);
158 cert
= x509_certificate_parse(buf
, len
);
160 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to parse X.509 "
166 * verify key usage (must allow encryption)
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)
177 *pk
= crypto_public_key_import(cert
->public_key
, cert
->public_key_len
);
178 x509_certificate_free(cert
);
181 wpa_printf(MSG_ERROR
, "TLSv1: Failed to import "
182 "server public key");
190 int tls_verify_hash_init(struct tls_verify_hash
*verify
)
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
);
209 void tls_verify_hash_add(struct tls_verify_hash
*verify
, const u8
*buf
,
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
);
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
);
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
);
227 void tls_verify_hash_free(struct tls_verify_hash
*verify
)
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
;