139beb93cSSam Leffler /* 239beb93cSSam Leffler * TLSv1 common routines 339beb93cSSam Leffler * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 539beb93cSSam Leffler * This program is free software; you can redistribute it and/or modify 639beb93cSSam Leffler * it under the terms of the GNU General Public License version 2 as 739beb93cSSam Leffler * published by the Free Software Foundation. 839beb93cSSam Leffler * 939beb93cSSam Leffler * Alternatively, this software may be distributed under the terms of BSD 1039beb93cSSam Leffler * license. 1139beb93cSSam Leffler * 1239beb93cSSam Leffler * See README and COPYING for more details. 1339beb93cSSam Leffler */ 1439beb93cSSam Leffler 1539beb93cSSam Leffler #include "includes.h" 1639beb93cSSam Leffler 1739beb93cSSam Leffler #include "common.h" 1839beb93cSSam Leffler #include "x509v3.h" 1939beb93cSSam Leffler #include "tlsv1_common.h" 2039beb93cSSam Leffler 2139beb93cSSam Leffler 2239beb93cSSam Leffler /* 2339beb93cSSam Leffler * TODO: 2439beb93cSSam Leffler * RFC 2246 Section 9: Mandatory to implement TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA 2539beb93cSSam Leffler * Add support for commonly used cipher suites; don't bother with exportable 2639beb93cSSam Leffler * suites. 2739beb93cSSam Leffler */ 2839beb93cSSam Leffler 2939beb93cSSam Leffler static const struct tls_cipher_suite tls_cipher_suites[] = { 3039beb93cSSam Leffler { TLS_NULL_WITH_NULL_NULL, TLS_KEY_X_NULL, TLS_CIPHER_NULL, 3139beb93cSSam Leffler TLS_HASH_NULL }, 3239beb93cSSam Leffler { TLS_RSA_WITH_RC4_128_MD5, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 3339beb93cSSam Leffler TLS_HASH_MD5 }, 3439beb93cSSam Leffler { TLS_RSA_WITH_RC4_128_SHA, TLS_KEY_X_RSA, TLS_CIPHER_RC4_128, 3539beb93cSSam Leffler TLS_HASH_SHA }, 3639beb93cSSam Leffler { TLS_RSA_WITH_DES_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_DES_CBC, 3739beb93cSSam Leffler TLS_HASH_SHA }, 3839beb93cSSam Leffler { TLS_RSA_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_RSA, 3939beb93cSSam Leffler TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 4039beb93cSSam Leffler { TLS_DH_anon_WITH_RC4_128_MD5, TLS_KEY_X_DH_anon, 4139beb93cSSam Leffler TLS_CIPHER_RC4_128, TLS_HASH_MD5 }, 4239beb93cSSam Leffler { TLS_DH_anon_WITH_DES_CBC_SHA, TLS_KEY_X_DH_anon, 4339beb93cSSam Leffler TLS_CIPHER_DES_CBC, TLS_HASH_SHA }, 4439beb93cSSam Leffler { TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_KEY_X_DH_anon, 4539beb93cSSam Leffler TLS_CIPHER_3DES_EDE_CBC, TLS_HASH_SHA }, 4639beb93cSSam Leffler { TLS_RSA_WITH_AES_128_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_128_CBC, 4739beb93cSSam Leffler TLS_HASH_SHA }, 4839beb93cSSam Leffler { TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_KEY_X_DH_anon, 4939beb93cSSam Leffler TLS_CIPHER_AES_128_CBC, TLS_HASH_SHA }, 5039beb93cSSam Leffler { TLS_RSA_WITH_AES_256_CBC_SHA, TLS_KEY_X_RSA, TLS_CIPHER_AES_256_CBC, 5139beb93cSSam Leffler TLS_HASH_SHA }, 5239beb93cSSam Leffler { TLS_DH_anon_WITH_AES_256_CBC_SHA, TLS_KEY_X_DH_anon, 5339beb93cSSam Leffler TLS_CIPHER_AES_256_CBC, TLS_HASH_SHA } 5439beb93cSSam Leffler }; 5539beb93cSSam Leffler 5639beb93cSSam Leffler #define NUM_ELEMS(a) (sizeof(a) / sizeof((a)[0])) 5739beb93cSSam Leffler #define NUM_TLS_CIPHER_SUITES NUM_ELEMS(tls_cipher_suites) 5839beb93cSSam Leffler 5939beb93cSSam Leffler 6039beb93cSSam Leffler static const struct tls_cipher_data tls_ciphers[] = { 6139beb93cSSam Leffler { TLS_CIPHER_NULL, TLS_CIPHER_STREAM, 0, 0, 0, 6239beb93cSSam Leffler CRYPTO_CIPHER_NULL }, 6339beb93cSSam Leffler { TLS_CIPHER_IDEA_CBC, TLS_CIPHER_BLOCK, 16, 16, 8, 6439beb93cSSam Leffler CRYPTO_CIPHER_NULL }, 6539beb93cSSam Leffler { TLS_CIPHER_RC2_CBC_40, TLS_CIPHER_BLOCK, 5, 16, 0, 6639beb93cSSam Leffler CRYPTO_CIPHER_ALG_RC2 }, 6739beb93cSSam Leffler { TLS_CIPHER_RC4_40, TLS_CIPHER_STREAM, 5, 16, 0, 6839beb93cSSam Leffler CRYPTO_CIPHER_ALG_RC4 }, 6939beb93cSSam Leffler { TLS_CIPHER_RC4_128, TLS_CIPHER_STREAM, 16, 16, 0, 7039beb93cSSam Leffler CRYPTO_CIPHER_ALG_RC4 }, 7139beb93cSSam Leffler { TLS_CIPHER_DES40_CBC, TLS_CIPHER_BLOCK, 5, 8, 8, 7239beb93cSSam Leffler CRYPTO_CIPHER_ALG_DES }, 7339beb93cSSam Leffler { TLS_CIPHER_DES_CBC, TLS_CIPHER_BLOCK, 8, 8, 8, 7439beb93cSSam Leffler CRYPTO_CIPHER_ALG_DES }, 7539beb93cSSam Leffler { TLS_CIPHER_3DES_EDE_CBC, TLS_CIPHER_BLOCK, 24, 24, 8, 7639beb93cSSam Leffler CRYPTO_CIPHER_ALG_3DES }, 7739beb93cSSam Leffler { TLS_CIPHER_AES_128_CBC, TLS_CIPHER_BLOCK, 16, 16, 16, 7839beb93cSSam Leffler CRYPTO_CIPHER_ALG_AES }, 7939beb93cSSam Leffler { TLS_CIPHER_AES_256_CBC, TLS_CIPHER_BLOCK, 32, 32, 16, 8039beb93cSSam Leffler CRYPTO_CIPHER_ALG_AES } 8139beb93cSSam Leffler }; 8239beb93cSSam Leffler 8339beb93cSSam Leffler #define NUM_TLS_CIPHER_DATA NUM_ELEMS(tls_ciphers) 8439beb93cSSam Leffler 8539beb93cSSam Leffler 8639beb93cSSam Leffler /** 8739beb93cSSam Leffler * tls_get_cipher_suite - Get TLS cipher suite 8839beb93cSSam Leffler * @suite: Cipher suite identifier 8939beb93cSSam Leffler * Returns: Pointer to the cipher data or %NULL if not found 9039beb93cSSam Leffler */ 9139beb93cSSam Leffler const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite) 9239beb93cSSam Leffler { 9339beb93cSSam Leffler size_t i; 9439beb93cSSam Leffler for (i = 0; i < NUM_TLS_CIPHER_SUITES; i++) 9539beb93cSSam Leffler if (tls_cipher_suites[i].suite == suite) 9639beb93cSSam Leffler return &tls_cipher_suites[i]; 9739beb93cSSam Leffler return NULL; 9839beb93cSSam Leffler } 9939beb93cSSam Leffler 10039beb93cSSam Leffler 10139beb93cSSam Leffler const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher) 10239beb93cSSam Leffler { 10339beb93cSSam Leffler size_t i; 10439beb93cSSam Leffler for (i = 0; i < NUM_TLS_CIPHER_DATA; i++) 10539beb93cSSam Leffler if (tls_ciphers[i].cipher == cipher) 10639beb93cSSam Leffler return &tls_ciphers[i]; 10739beb93cSSam Leffler return NULL; 10839beb93cSSam Leffler } 10939beb93cSSam Leffler 11039beb93cSSam Leffler 11139beb93cSSam Leffler int tls_server_key_exchange_allowed(tls_cipher cipher) 11239beb93cSSam Leffler { 11339beb93cSSam Leffler const struct tls_cipher_suite *suite; 11439beb93cSSam Leffler 11539beb93cSSam Leffler /* RFC 2246, Section 7.4.3 */ 11639beb93cSSam Leffler suite = tls_get_cipher_suite(cipher); 11739beb93cSSam Leffler if (suite == NULL) 11839beb93cSSam Leffler return 0; 11939beb93cSSam Leffler 12039beb93cSSam Leffler switch (suite->key_exchange) { 12139beb93cSSam Leffler case TLS_KEY_X_DHE_DSS: 12239beb93cSSam Leffler case TLS_KEY_X_DHE_DSS_EXPORT: 12339beb93cSSam Leffler case TLS_KEY_X_DHE_RSA: 12439beb93cSSam Leffler case TLS_KEY_X_DHE_RSA_EXPORT: 12539beb93cSSam Leffler case TLS_KEY_X_DH_anon_EXPORT: 12639beb93cSSam Leffler case TLS_KEY_X_DH_anon: 12739beb93cSSam Leffler return 1; 12839beb93cSSam Leffler case TLS_KEY_X_RSA_EXPORT: 12939beb93cSSam Leffler return 1 /* FIX: public key len > 512 bits */; 13039beb93cSSam Leffler default: 13139beb93cSSam Leffler return 0; 13239beb93cSSam Leffler } 13339beb93cSSam Leffler } 13439beb93cSSam Leffler 13539beb93cSSam Leffler 13639beb93cSSam Leffler /** 13739beb93cSSam Leffler * tls_parse_cert - Parse DER encoded X.509 certificate and get public key 13839beb93cSSam Leffler * @buf: ASN.1 DER encoded certificate 13939beb93cSSam Leffler * @len: Length of the buffer 14039beb93cSSam Leffler * @pk: Buffer for returning the allocated public key 14139beb93cSSam Leffler * Returns: 0 on success, -1 on failure 14239beb93cSSam Leffler * 14339beb93cSSam Leffler * This functions parses an ASN.1 DER encoded X.509 certificate and retrieves 14439beb93cSSam Leffler * the public key from it. The caller is responsible for freeing the public key 14539beb93cSSam Leffler * by calling crypto_public_key_free(). 14639beb93cSSam Leffler */ 14739beb93cSSam Leffler int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk) 14839beb93cSSam Leffler { 14939beb93cSSam Leffler struct x509_certificate *cert; 15039beb93cSSam Leffler 15139beb93cSSam Leffler wpa_hexdump(MSG_MSGDUMP, "TLSv1: Parse ASN.1 DER certificate", 15239beb93cSSam Leffler buf, len); 15339beb93cSSam Leffler 15439beb93cSSam Leffler *pk = crypto_public_key_from_cert(buf, len); 15539beb93cSSam Leffler if (*pk) 15639beb93cSSam Leffler return 0; 15739beb93cSSam Leffler 15839beb93cSSam Leffler cert = x509_certificate_parse(buf, len); 15939beb93cSSam Leffler if (cert == NULL) { 16039beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse X.509 " 16139beb93cSSam Leffler "certificate"); 16239beb93cSSam Leffler return -1; 16339beb93cSSam Leffler } 16439beb93cSSam Leffler 16539beb93cSSam Leffler /* TODO 16639beb93cSSam Leffler * verify key usage (must allow encryption) 16739beb93cSSam Leffler * 16839beb93cSSam Leffler * All certificate profiles, key and cryptographic formats are 16939beb93cSSam Leffler * defined by the IETF PKIX working group [PKIX]. When a key 17039beb93cSSam Leffler * usage extension is present, the digitalSignature bit must be 17139beb93cSSam Leffler * set for the key to be eligible for signing, as described 17239beb93cSSam Leffler * above, and the keyEncipherment bit must be present to allow 17339beb93cSSam Leffler * encryption, as described above. The keyAgreement bit must be 17439beb93cSSam Leffler * set on Diffie-Hellman certificates. (PKIX: RFC 3280) 17539beb93cSSam Leffler */ 17639beb93cSSam Leffler 17739beb93cSSam Leffler *pk = crypto_public_key_import(cert->public_key, cert->public_key_len); 17839beb93cSSam Leffler x509_certificate_free(cert); 17939beb93cSSam Leffler 18039beb93cSSam Leffler if (*pk == NULL) { 18139beb93cSSam Leffler wpa_printf(MSG_ERROR, "TLSv1: Failed to import " 18239beb93cSSam Leffler "server public key"); 18339beb93cSSam Leffler return -1; 18439beb93cSSam Leffler } 18539beb93cSSam Leffler 18639beb93cSSam Leffler return 0; 18739beb93cSSam Leffler } 18839beb93cSSam Leffler 18939beb93cSSam Leffler 19039beb93cSSam Leffler int tls_verify_hash_init(struct tls_verify_hash *verify) 19139beb93cSSam Leffler { 19239beb93cSSam Leffler tls_verify_hash_free(verify); 19339beb93cSSam Leffler verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 19439beb93cSSam Leffler verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 19539beb93cSSam Leffler verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0); 19639beb93cSSam Leffler verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 19739beb93cSSam Leffler verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 19839beb93cSSam Leffler verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0); 19939beb93cSSam Leffler if (verify->md5_client == NULL || verify->md5_server == NULL || 20039beb93cSSam Leffler verify->md5_cert == NULL || verify->sha1_client == NULL || 20139beb93cSSam Leffler verify->sha1_server == NULL || verify->sha1_cert == NULL) { 20239beb93cSSam Leffler tls_verify_hash_free(verify); 20339beb93cSSam Leffler return -1; 20439beb93cSSam Leffler } 20539beb93cSSam Leffler return 0; 20639beb93cSSam Leffler } 20739beb93cSSam Leffler 20839beb93cSSam Leffler 20939beb93cSSam Leffler void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf, 21039beb93cSSam Leffler size_t len) 21139beb93cSSam Leffler { 21239beb93cSSam Leffler if (verify->md5_client && verify->sha1_client) { 21339beb93cSSam Leffler crypto_hash_update(verify->md5_client, buf, len); 21439beb93cSSam Leffler crypto_hash_update(verify->sha1_client, buf, len); 21539beb93cSSam Leffler } 21639beb93cSSam Leffler if (verify->md5_server && verify->sha1_server) { 21739beb93cSSam Leffler crypto_hash_update(verify->md5_server, buf, len); 21839beb93cSSam Leffler crypto_hash_update(verify->sha1_server, buf, len); 21939beb93cSSam Leffler } 22039beb93cSSam Leffler if (verify->md5_cert && verify->sha1_cert) { 22139beb93cSSam Leffler crypto_hash_update(verify->md5_cert, buf, len); 22239beb93cSSam Leffler crypto_hash_update(verify->sha1_cert, buf, len); 22339beb93cSSam Leffler } 22439beb93cSSam Leffler } 22539beb93cSSam Leffler 22639beb93cSSam Leffler 22739beb93cSSam Leffler void tls_verify_hash_free(struct tls_verify_hash *verify) 22839beb93cSSam Leffler { 22939beb93cSSam Leffler crypto_hash_finish(verify->md5_client, NULL, NULL); 23039beb93cSSam Leffler crypto_hash_finish(verify->md5_server, NULL, NULL); 23139beb93cSSam Leffler crypto_hash_finish(verify->md5_cert, NULL, NULL); 23239beb93cSSam Leffler crypto_hash_finish(verify->sha1_client, NULL, NULL); 23339beb93cSSam Leffler crypto_hash_finish(verify->sha1_server, NULL, NULL); 23439beb93cSSam Leffler crypto_hash_finish(verify->sha1_cert, NULL, NULL); 23539beb93cSSam Leffler verify->md5_client = NULL; 23639beb93cSSam Leffler verify->md5_server = NULL; 23739beb93cSSam Leffler verify->md5_cert = NULL; 23839beb93cSSam Leffler verify->sha1_client = NULL; 23939beb93cSSam Leffler verify->sha1_server = NULL; 24039beb93cSSam Leffler verify->sha1_cert = NULL; 24139beb93cSSam Leffler } 242