2010-01-25 11:21:57 +00:00
|
|
|
/*
|
2014-01-15 14:51:03 +00:00
|
|
|
* Copyright (C) 2010-2014 Martin Willi
|
|
|
|
* Copyright (C) 2010-2014 revosec AG
|
2010-01-25 11:21:57 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "tls_crypto.h"
|
2020-05-21 07:37:38 +00:00
|
|
|
#include "tls_hkdf.h"
|
2010-01-25 11:21:57 +00:00
|
|
|
|
2012-10-16 14:03:21 +00:00
|
|
|
#include <utils/debug.h>
|
2014-01-15 14:51:03 +00:00
|
|
|
#include <plugins/plugin_feature.h>
|
2010-02-04 10:17:48 +00:00
|
|
|
|
2010-08-04 23:21:59 +00:00
|
|
|
ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL,
|
|
|
|
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
|
|
|
|
"TLS_NULL_WITH_NULL_NULL",
|
|
|
|
"TLS_RSA_WITH_NULL_MD5",
|
|
|
|
"TLS_RSA_WITH_NULL_SHA",
|
|
|
|
"TLS_RSA_EXPORT_WITH_RC4_40_MD5",
|
|
|
|
"TLS_RSA_WITH_RC4_128_MD5",
|
|
|
|
"TLS_RSA_WITH_RC4_128_SHA",
|
|
|
|
"TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
|
|
|
|
"TLS_RSA_WITH_IDEA_CBC_SHA",
|
|
|
|
"TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
|
2010-08-05 11:58:49 +00:00
|
|
|
"TLS_DHE_DSS_WITH_DES_CBC_SHA",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
|
|
|
|
"TLS_DH_anon_WITH_RC4_128_MD5",
|
|
|
|
"TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_3DES_EDE_CBC_SHA");
|
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA,
|
|
|
|
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
|
|
|
|
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
|
|
|
|
"TLS_KRB5_WITH_DES_CBC_SHA",
|
|
|
|
"TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_KRB5_WITH_RC4_128_SHA",
|
|
|
|
"TLS_KRB5_WITH_IDEA_CBC_SHA",
|
|
|
|
"TLS_KRB5_WITH_DES_CBC_MD5",
|
|
|
|
"TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
|
|
|
|
"TLS_KRB5_WITH_RC4_128_MD5",
|
|
|
|
"TLS_KRB5_WITH_IDEA_CBC_MD5",
|
|
|
|
"TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
|
2010-08-05 11:58:49 +00:00
|
|
|
"TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
|
|
|
|
"TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
|
|
|
|
"TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",
|
|
|
|
"TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
|
|
|
|
"TLS_PSK_WITH_NULL_SHA",
|
|
|
|
"TLS_DHE_PSK_WITH_NULL_SHA",
|
|
|
|
"TLS_RSA_PSK_WITH_NULL_SHA",
|
|
|
|
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_NULL_SHA256",
|
2014-03-25 08:20:15 +00:00
|
|
|
"TLS_RSA_WITH_AES_128_CBC_SHA256",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_RSA_WITH_AES_256_CBC_SHA256",
|
|
|
|
"TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA",
|
2010-08-05 11:58:49 +00:00
|
|
|
"TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA");
|
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
|
|
|
TLS_DH_anon_WITH_AES_256_CBC_SHA256,
|
|
|
|
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
|
|
|
|
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_DH_DSS_WITH_AES_256_CBC_SHA256",
|
|
|
|
"TLS_DH_RSA_WITH_AES_256_CBC_SHA256",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
|
|
|
|
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
|
|
|
|
"TLS_DH_anon_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_DH_anon_WITH_AES_256_CBC_SHA256");
|
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
2010-08-05 11:58:49 +00:00
|
|
|
TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
|
2010-08-04 23:21:59 +00:00
|
|
|
TLS_DH_anon_WITH_AES_256_CBC_SHA256,
|
|
|
|
"TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",
|
|
|
|
"TLS_PSK_WITH_RC4_128_SHA",
|
2014-03-25 08:20:15 +00:00
|
|
|
"TLS_PSK_WITH_3DES_EDE_CBC_SHA",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_PSK_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_PSK_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_DHE_PSK_WITH_RC4_128_SHA",
|
|
|
|
"TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_DHE_PSK_WITH_AES_128_CBC_SHA",
|
2014-03-25 08:20:15 +00:00
|
|
|
"TLS_DHE_PSK_WITH_AES_256_CBC_SHA",
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_RSA_PSK_WITH_RC4_128_SHA",
|
|
|
|
"TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_DH_DSS_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_DH_RSA_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_DHE_DSS_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_DHE_RSA_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_DH_anon_WITH_SEED_CBC_SHA",
|
|
|
|
"TLS_RSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_RSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DH_DSS_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DH_anon_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DH_anon_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_PSK_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_PSK_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_PSK_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_PSK_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_PSK_WITH_NULL_SHA256",
|
|
|
|
"TLS_PSK_WITH_NULL_SHA384",
|
|
|
|
"TLS_DHE_PSK_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_DHE_PSK_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_DHE_PSK_WITH_NULL_SHA256",
|
|
|
|
"TLS_DHE_PSK_WITH_NULL_SHA384",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_RSA_PSK_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_RSA_PSK_WITH_NULL_SHA256",
|
|
|
|
"TLS_RSA_PSK_WITH_NULL_SHA384",
|
|
|
|
"TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256",
|
|
|
|
"TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",
|
|
|
|
"TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256",
|
|
|
|
"TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256",
|
|
|
|
"TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256",
|
|
|
|
"TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256",
|
|
|
|
"TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256");
|
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
|
2010-08-05 11:58:49 +00:00
|
|
|
TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
|
2010-08-04 23:21:59 +00:00
|
|
|
TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
|
|
|
|
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
|
2020-05-21 07:37:38 +00:00
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_AES_128_GCM_SHA256,
|
|
|
|
TLS_AES_128_CCM_8_SHA256,
|
|
|
|
TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
|
|
|
|
"TLS_AES_128_GCM_SHA256",
|
|
|
|
"TLS_AES_256_GCM_SHA384",
|
|
|
|
"TLS_CHACHA20_POLY1305_SHA256",
|
|
|
|
"TLS_AES_128_CCM_SHA256",
|
|
|
|
"TLS_AES_128_CCM_8_SHA256");
|
2010-08-04 23:21:59 +00:00
|
|
|
ENUM_NEXT(tls_cipher_suite_names, TLS_ECDH_ECDSA_WITH_NULL_SHA,
|
2010-08-05 11:58:49 +00:00
|
|
|
TLS_ECDHE_PSK_WITH_NULL_SHA384,
|
2020-05-21 07:37:38 +00:00
|
|
|
TLS_AES_128_CCM_8_SHA256,
|
2010-08-04 23:21:59 +00:00
|
|
|
"TLS_ECDH_ECDSA_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDH_RSA_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDHE_RSA_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDH_anon_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDH_anon_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
|
|
|
|
"TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
|
|
|
|
"TLS_ECDHE_PSK_WITH_RC4_128_SHA",
|
|
|
|
"TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA",
|
|
|
|
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
|
|
|
|
"TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
|
|
|
|
"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256",
|
|
|
|
"TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384",
|
|
|
|
"TLS_ECDHE_PSK_WITH_NULL_SHA",
|
|
|
|
"TLS_ECDHE_PSK_WITH_NULL_SHA256",
|
|
|
|
"TLS_ECDHE_PSK_WITH_NULL_SHA384");
|
|
|
|
ENUM_END(tls_cipher_suite_names, TLS_ECDHE_PSK_WITH_NULL_SHA384);
|
|
|
|
|
2010-09-02 07:21:45 +00:00
|
|
|
ENUM(tls_hash_algorithm_names, TLS_HASH_NONE, TLS_HASH_SHA512,
|
|
|
|
"NONE",
|
|
|
|
"MD5",
|
|
|
|
"SHA1",
|
|
|
|
"SHA224",
|
|
|
|
"SHA256",
|
|
|
|
"SHA384",
|
|
|
|
"SHA512",
|
|
|
|
);
|
|
|
|
|
|
|
|
ENUM(tls_signature_algorithm_names, TLS_SIG_RSA, TLS_SIG_ECDSA,
|
|
|
|
"RSA",
|
|
|
|
"DSA",
|
|
|
|
"ECDSA",
|
|
|
|
);
|
|
|
|
|
2010-09-02 08:05:11 +00:00
|
|
|
ENUM_BEGIN(tls_client_certificate_type_names,
|
|
|
|
TLS_RSA_SIGN, TLS_DSS_EPHEMERAL_DH,
|
|
|
|
"RSA_SIGN",
|
|
|
|
"DSA_SIGN",
|
|
|
|
"RSA_FIXED_DH",
|
|
|
|
"DSS_FIXED_DH",
|
|
|
|
"RSA_EPHEMERAL_DH",
|
|
|
|
"DSS_EPHEMERAL_DH");
|
|
|
|
ENUM_NEXT(tls_client_certificate_type_names,
|
|
|
|
TLS_FORTEZZA_DMS, TLS_FORTEZZA_DMS, TLS_DSS_EPHEMERAL_DH,
|
|
|
|
"FORTEZZA_DMS");
|
|
|
|
ENUM_NEXT(tls_client_certificate_type_names,
|
|
|
|
TLS_ECDSA_SIGN, TLS_ECDSA_FIXED_ECDH, TLS_FORTEZZA_DMS,
|
|
|
|
"ECDSA_SIGN",
|
|
|
|
"RSA_FIXED_ECDH",
|
|
|
|
"ECDSA_FIXED_ECDH");
|
|
|
|
ENUM_END(tls_client_certificate_type_names, TLS_ECDSA_FIXED_ECDH);
|
|
|
|
|
2010-09-03 08:59:01 +00:00
|
|
|
ENUM(tls_ecc_curve_type_names, TLS_ECC_EXPLICIT_PRIME, TLS_ECC_NAMED_CURVE,
|
|
|
|
"EXPLICIT_PRIME",
|
|
|
|
"EXPLICIT_CHAR2",
|
|
|
|
"NAMED_CURVE",
|
|
|
|
);
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
ENUM_BEGIN(tls_named_group_names, TLS_SECT163K1, TLS_SECP521R1,
|
2010-09-03 08:59:01 +00:00
|
|
|
"SECT163K1",
|
|
|
|
"SECT163R1",
|
|
|
|
"SECT163R2",
|
|
|
|
"SECT193R1",
|
|
|
|
"SECT193R2",
|
|
|
|
"SECT233K1",
|
|
|
|
"SECT233R1",
|
|
|
|
"SECT239K1",
|
|
|
|
"SECT283K1",
|
|
|
|
"SECT283R1",
|
|
|
|
"SECT409K1",
|
|
|
|
"SECT409R1",
|
|
|
|
"SECT571K1",
|
|
|
|
"SECT571R1",
|
|
|
|
"SECP160K1",
|
|
|
|
"SECP160R1",
|
|
|
|
"SECP160R2",
|
|
|
|
"SECP192K1",
|
|
|
|
"SECP192R1",
|
|
|
|
"SECP224K1",
|
|
|
|
"SECP224R1",
|
|
|
|
"SECP256K1",
|
|
|
|
"SECP256R1",
|
|
|
|
"SECP384R1",
|
|
|
|
"SECP521R1",
|
|
|
|
);
|
2020-05-21 07:37:38 +00:00
|
|
|
ENUM_NEXT(tls_named_group_names, TLS_CURVE25519, TLS_CURVE_448, TLS_SECP521R1,
|
|
|
|
"CURVE25519",
|
|
|
|
"CURVE448",
|
|
|
|
);
|
|
|
|
ENUM_NEXT(tls_named_group_names, TLS_FFDHE2048, TLS_FFDHE8192, TLS_CURVE_448,
|
|
|
|
"FFDHE2048",
|
|
|
|
"FFDHE3072",
|
|
|
|
"FFDHE4096",
|
|
|
|
"FFDHE6144",
|
|
|
|
"FFDHE8192",
|
|
|
|
);
|
|
|
|
ENUM_END(tls_named_group_names, TLS_FFDHE8192);
|
2010-09-03 08:59:01 +00:00
|
|
|
|
2010-09-06 16:36:27 +00:00
|
|
|
ENUM(tls_ansi_point_format_names, TLS_ANSI_COMPRESSED, TLS_ANSI_HYBRID_Y,
|
2010-09-06 13:31:32 +00:00
|
|
|
"compressed",
|
|
|
|
"compressed y",
|
|
|
|
"uncompressed",
|
|
|
|
"uncompressed y",
|
|
|
|
"hybrid",
|
|
|
|
"hybrid y",
|
|
|
|
);
|
2010-09-02 08:05:11 +00:00
|
|
|
|
2010-09-06 16:42:43 +00:00
|
|
|
ENUM(tls_ec_point_format_names,
|
|
|
|
TLS_EC_POINT_UNCOMPRESSED, TLS_EC_POINT_ANSIX962_COMPRESSED_CHAR2,
|
|
|
|
"uncompressed",
|
|
|
|
"ansiX962 compressed prime",
|
|
|
|
"ansiX962 compressed char2",
|
|
|
|
);
|
|
|
|
|
2010-01-25 11:21:57 +00:00
|
|
|
typedef struct private_tls_crypto_t private_tls_crypto_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Private data of an tls_crypto_t object.
|
|
|
|
*/
|
|
|
|
struct private_tls_crypto_t {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Public tls_crypto_t interface.
|
|
|
|
*/
|
|
|
|
tls_crypto_t public;
|
2010-02-04 10:17:48 +00:00
|
|
|
|
2010-02-05 13:39:19 +00:00
|
|
|
/**
|
|
|
|
* Protection layer
|
|
|
|
*/
|
|
|
|
tls_protection_t *protection;
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
/**
|
|
|
|
* List of supported/acceptable cipher suites
|
|
|
|
*/
|
|
|
|
tls_cipher_suite_t *suites;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of supported suites
|
|
|
|
*/
|
|
|
|
int suite_count;
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
/**
|
|
|
|
* HKDF for TLS 1.3
|
|
|
|
*/
|
|
|
|
tls_hkdf_t *hkdf;
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
/**
|
|
|
|
* Selected cipher suite
|
|
|
|
*/
|
|
|
|
tls_cipher_suite_t suite;
|
|
|
|
|
2010-09-03 16:11:03 +00:00
|
|
|
/**
|
|
|
|
* RSA supported?
|
|
|
|
*/
|
|
|
|
bool rsa;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ECDSA supported?
|
|
|
|
*/
|
|
|
|
bool ecdsa;
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
/**
|
|
|
|
* MD5 supported?
|
|
|
|
*/
|
|
|
|
bool md5;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SHA1 supported?
|
|
|
|
*/
|
|
|
|
bool sha1;
|
|
|
|
/**
|
|
|
|
* SHA224 supported?
|
|
|
|
*/
|
|
|
|
bool sha224;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SHA256 supported?
|
|
|
|
*/
|
|
|
|
bool sha256;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SHA384 supported?
|
|
|
|
*/
|
|
|
|
bool sha384;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SHA512 supported?
|
|
|
|
*/
|
|
|
|
bool sha512;
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
/**
|
|
|
|
* TLS context
|
|
|
|
*/
|
|
|
|
tls_t *tls;
|
|
|
|
|
2011-12-31 00:41:56 +00:00
|
|
|
/**
|
|
|
|
* TLS session cache
|
|
|
|
*/
|
|
|
|
tls_cache_t *cache;
|
|
|
|
|
2010-02-05 13:25:38 +00:00
|
|
|
/**
|
2018-02-13 11:04:12 +00:00
|
|
|
* All handshake data concatenated
|
2010-02-05 13:25:38 +00:00
|
|
|
*/
|
|
|
|
chunk_t handshake;
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
/**
|
|
|
|
* Connection state TLS PRF
|
|
|
|
*/
|
|
|
|
tls_prf_t *prf;
|
2010-02-04 17:18:10 +00:00
|
|
|
|
|
|
|
/**
|
2014-02-03 12:20:46 +00:00
|
|
|
* AEAD transform for inbound traffic
|
2010-02-04 17:18:10 +00:00
|
|
|
*/
|
2014-02-03 12:20:46 +00:00
|
|
|
tls_aead_t *aead_in;
|
2010-02-04 17:18:10 +00:00
|
|
|
|
|
|
|
/**
|
2014-02-03 12:20:46 +00:00
|
|
|
* AEAD transform for outbound traffic
|
2010-02-04 17:18:10 +00:00
|
|
|
*/
|
2014-02-03 12:20:46 +00:00
|
|
|
tls_aead_t *aead_out;
|
2010-02-05 11:28:48 +00:00
|
|
|
|
|
|
|
/**
|
2010-08-06 15:33:46 +00:00
|
|
|
* EAP-[T]TLS MSK
|
2010-02-05 11:28:48 +00:00
|
|
|
*/
|
|
|
|
chunk_t msk;
|
2010-08-06 15:33:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ASCII string constant used as seed for EAP-[T]TLS MSK PRF
|
|
|
|
*/
|
|
|
|
char *msk_label;
|
2010-01-25 11:21:57 +00:00
|
|
|
};
|
|
|
|
|
2010-02-04 17:18:10 +00:00
|
|
|
typedef struct {
|
|
|
|
tls_cipher_suite_t suite;
|
2010-09-03 10:50:18 +00:00
|
|
|
key_type_t key;
|
|
|
|
diffie_hellman_group_t dh;
|
2010-02-04 17:18:10 +00:00
|
|
|
hash_algorithm_t hash;
|
|
|
|
pseudo_random_function_t prf;
|
|
|
|
integrity_algorithm_t mac;
|
|
|
|
encryption_algorithm_t encr;
|
|
|
|
size_t encr_size;
|
2020-05-21 07:37:38 +00:00
|
|
|
tls_version_t tls_version;
|
2010-02-04 17:18:10 +00:00
|
|
|
} suite_algs_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mapping suites to a set of algorithms
|
|
|
|
*/
|
|
|
|
static suite_algs_t suite_algs[] = {
|
2020-05-21 07:37:38 +00:00
|
|
|
/* Cipher suites of TLS 1.3: key exchange and authentication
|
|
|
|
* delegated to extensions, therefore KEY_ANY, MODP_NONE, PRF_UNDEFINED */
|
|
|
|
{ TLS_AES_128_GCM_SHA256,
|
|
|
|
KEY_ANY, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_UNDEFINED,
|
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_GCM_ICV16, 16,
|
|
|
|
TLS_1_3,
|
|
|
|
},
|
|
|
|
{ TLS_AES_256_GCM_SHA384,
|
|
|
|
KEY_ANY, MODP_NONE,
|
|
|
|
HASH_SHA384, PRF_UNDEFINED,
|
|
|
|
AUTH_HMAC_SHA2_384_384, ENCR_AES_GCM_ICV16, 32,
|
|
|
|
TLS_1_3,
|
|
|
|
},
|
|
|
|
{ TLS_CHACHA20_POLY1305_SHA256,
|
|
|
|
KEY_ANY, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_UNDEFINED,
|
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_CHACHA20_POLY1305, 16,
|
|
|
|
TLS_1_3,
|
|
|
|
},
|
|
|
|
{ TLS_AES_128_CCM_SHA256,
|
|
|
|
KEY_ANY, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_UNDEFINED,
|
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV16, 16,
|
|
|
|
TLS_1_3,
|
|
|
|
},
|
|
|
|
{ TLS_AES_128_CCM_8_SHA256,
|
|
|
|
KEY_ANY, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_UNDEFINED,
|
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV8, 16,
|
|
|
|
TLS_1_3,
|
|
|
|
},
|
|
|
|
/* Legacy TLS cipher suites */
|
2010-09-03 10:54:40 +00:00
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
|
|
|
KEY_ECDSA, ECP_384_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
|
|
|
|
KEY_ECDSA, ECP_384_BIT,
|
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
2014-02-03 17:08:11 +00:00
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
KEY_ECDSA, ECP_384_BIT,
|
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
2010-09-03 10:54:40 +00:00
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
2010-09-03 15:24:39 +00:00
|
|
|
KEY_RSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
|
2010-09-03 15:24:39 +00:00
|
|
|
KEY_RSA, ECP_256_BIT,
|
2010-09-03 10:54:40 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
2010-09-03 15:24:39 +00:00
|
|
|
KEY_RSA, ECP_384_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
|
2010-09-03 15:24:39 +00:00
|
|
|
KEY_RSA, ECP_384_BIT,
|
2010-09-03 10:54:40 +00:00
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
2014-02-03 17:08:11 +00:00
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
KEY_RSA, ECP_256_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
KEY_RSA, ECP_384_BIT,
|
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
2010-09-02 17:27:37 +00:00
|
|
|
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_2048_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256,PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_3072_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_3072_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_4096_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
2014-02-03 17:08:11 +00:00
|
|
|
{ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
KEY_RSA, MODP_3072_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
KEY_RSA, MODP_4096_BIT,
|
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
2010-09-02 17:27:37 +00:00
|
|
|
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_2048_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_3072_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_3072_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_4096_BIT,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
|
|
|
{ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_2048_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_3DES, 0,
|
|
|
|
TLS_1_2,
|
2010-09-02 17:27:37 +00:00
|
|
|
},
|
2010-02-04 17:18:10 +00:00
|
|
|
{ TLS_RSA_WITH_AES_128_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-08-20 09:01:57 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_AES_128_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-02-04 17:18:10 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_AES_256_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-02-04 17:18:10 +00:00
|
|
|
},
|
2010-08-20 09:01:57 +00:00
|
|
|
{ TLS_RSA_WITH_AES_256_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-02-04 17:18:10 +00:00
|
|
|
},
|
2014-02-03 17:08:11 +00:00
|
|
|
{ TLS_RSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_AES_256_GCM_SHA384,
|
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA384, PRF_HMAC_SHA2_384,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32,
|
|
|
|
TLS_1_2,
|
2014-02-03 17:08:11 +00:00
|
|
|
},
|
2010-08-20 09:01:57 +00:00
|
|
|
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-08-20 09:01:57 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16,
|
|
|
|
TLS_1_2,
|
2010-08-20 09:01:57 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-08-20 09:01:57 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32,
|
|
|
|
TLS_1_2,
|
2010-02-04 17:18:10 +00:00
|
|
|
},
|
2010-09-03 10:54:40 +00:00
|
|
|
{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_3DES, 0,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
|
2010-09-06 14:35:53 +00:00
|
|
|
KEY_RSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_3DES, 0,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
2010-08-25 16:30:09 +00:00
|
|
|
{ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_3DES, 0,
|
|
|
|
TLS_1_2,
|
2010-08-25 16:30:09 +00:00
|
|
|
},
|
2010-09-03 10:54:40 +00:00
|
|
|
{ TLS_ECDHE_ECDSA_WITH_NULL_SHA,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_NULL, 0,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
|
|
|
{ TLS_ECDHE_RSA_WITH_NULL_SHA,
|
|
|
|
KEY_ECDSA, ECP_256_BIT,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_NULL, 0,
|
|
|
|
TLS_1_2,
|
2010-09-03 10:54:40 +00:00
|
|
|
},
|
2010-08-25 16:30:09 +00:00
|
|
|
{ TLS_RSA_WITH_NULL_SHA,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA1_160, ENCR_NULL, 0,
|
|
|
|
TLS_1_2,
|
2010-08-25 16:30:09 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_NULL_SHA256,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0,
|
|
|
|
TLS_1_2,
|
2010-08-25 16:30:09 +00:00
|
|
|
},
|
|
|
|
{ TLS_RSA_WITH_NULL_MD5,
|
2010-09-03 10:50:18 +00:00
|
|
|
KEY_RSA, MODP_NONE,
|
2011-12-24 11:35:28 +00:00
|
|
|
HASH_SHA256, PRF_HMAC_SHA2_256,
|
2020-05-21 07:37:38 +00:00
|
|
|
AUTH_HMAC_MD5_128, ENCR_NULL, 0,
|
|
|
|
TLS_1_2,
|
2010-08-25 16:30:09 +00:00
|
|
|
},
|
2010-02-04 17:18:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2011-07-20 13:57:53 +00:00
|
|
|
* Look up algorithms by a suite
|
2010-02-04 17:18:10 +00:00
|
|
|
*/
|
|
|
|
static suite_algs_t *find_suite(tls_cipher_suite_t suite)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < countof(suite_algs); i++)
|
|
|
|
{
|
|
|
|
if (suite_algs[i].suite == suite)
|
|
|
|
{
|
|
|
|
return &suite_algs[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
/**
|
2010-08-20 10:10:21 +00:00
|
|
|
* Filter a suite list using a transform enumerator
|
2010-02-04 10:17:48 +00:00
|
|
|
*/
|
2014-03-24 13:28:50 +00:00
|
|
|
static void filter_suite(suite_algs_t suites[], int *count, int offset,
|
2010-08-20 10:10:21 +00:00
|
|
|
enumerator_t*(*create_enumerator)(crypto_factory_t*))
|
2010-01-25 11:21:57 +00:00
|
|
|
{
|
2010-12-18 15:31:01 +00:00
|
|
|
const char *plugin_name;
|
2010-08-20 10:10:21 +00:00
|
|
|
suite_algs_t current;
|
2010-12-18 19:24:53 +00:00
|
|
|
int *current_alg, i, remaining = 0;
|
2010-08-20 10:10:21 +00:00
|
|
|
enumerator_t *enumerator;
|
2010-01-25 11:21:57 +00:00
|
|
|
|
2010-08-20 10:10:21 +00:00
|
|
|
memset(¤t, 0, sizeof(current));
|
2010-12-18 19:24:53 +00:00
|
|
|
current_alg = (int*)((char*)¤t + offset);
|
|
|
|
|
2010-08-20 10:10:21 +00:00
|
|
|
for (i = 0; i < *count; i++)
|
2010-01-25 11:21:57 +00:00
|
|
|
{
|
2014-03-11 09:57:18 +00:00
|
|
|
if (create_enumerator == lib->crypto->create_crypter_enumerator &&
|
|
|
|
encryption_algorithm_is_aead(suites[i].encr))
|
|
|
|
{ /* filtering crypters, but current suite uses an AEAD, apply */
|
|
|
|
suites[remaining] = suites[i];
|
|
|
|
remaining++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (create_enumerator == lib->crypto->create_aead_enumerator &&
|
|
|
|
!encryption_algorithm_is_aead(suites[i].encr))
|
|
|
|
{ /* filtering AEADs, but current suite doesn't use one, apply */
|
|
|
|
suites[remaining] = suites[i];
|
|
|
|
remaining++;
|
|
|
|
continue;
|
|
|
|
}
|
2010-08-20 10:10:21 +00:00
|
|
|
enumerator = create_enumerator(lib->crypto);
|
2010-12-18 19:24:53 +00:00
|
|
|
while (enumerator->enumerate(enumerator, current_alg, &plugin_name))
|
2010-01-25 11:21:57 +00:00
|
|
|
{
|
2014-03-11 09:57:18 +00:00
|
|
|
if (current.encr && current.encr != suites[i].encr)
|
2010-01-25 11:21:57 +00:00
|
|
|
{
|
2014-03-11 09:57:18 +00:00
|
|
|
if (suites[i].encr != ENCR_NULL)
|
|
|
|
{ /* skip, ENCR does not match nor is NULL */
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-25 11:21:57 +00:00
|
|
|
}
|
2014-03-11 09:57:18 +00:00
|
|
|
if (current.mac && current.mac != suites[i].mac)
|
|
|
|
{
|
|
|
|
if (suites[i].mac != AUTH_UNDEFINED)
|
|
|
|
{ /* skip, MAC does not match nor is it undefined */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (current.prf && current.prf != suites[i].prf)
|
|
|
|
{ /* skip, PRF does not match */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (current.hash && current.hash != suites[i].hash)
|
|
|
|
{ /* skip, hash does not match */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (current.dh && current.dh != suites[i].dh)
|
|
|
|
{
|
|
|
|
if (suites[i].dh != MODP_NONE)
|
|
|
|
{ /* skip DH group, does not match nor NONE */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* suite supported, apply */
|
|
|
|
suites[remaining] = suites[i];
|
|
|
|
remaining++;
|
|
|
|
break;
|
2010-01-25 11:21:57 +00:00
|
|
|
}
|
2010-08-20 10:10:21 +00:00
|
|
|
enumerator->destroy(enumerator);
|
2010-01-25 11:21:57 +00:00
|
|
|
}
|
2010-08-20 10:10:21 +00:00
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
|
2010-08-20 13:02:25 +00:00
|
|
|
/**
|
|
|
|
* Purge NULL encryption cipher suites from list
|
|
|
|
*/
|
2014-03-24 13:28:50 +00:00
|
|
|
static void filter_null_suites(suite_algs_t suites[], int *count)
|
2010-08-20 13:02:25 +00:00
|
|
|
{
|
|
|
|
int i, remaining = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
if (suites[i].encr != ENCR_NULL)
|
|
|
|
{
|
|
|
|
suites[remaining] = suites[i];
|
|
|
|
remaining++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
|
2010-09-03 16:11:03 +00:00
|
|
|
/**
|
|
|
|
* Purge suites using a given key type
|
|
|
|
*/
|
|
|
|
static void filter_key_suites(private_tls_crypto_t *this,
|
|
|
|
suite_algs_t suites[], int *count, key_type_t key)
|
|
|
|
{
|
|
|
|
int i, remaining = 0;
|
|
|
|
|
|
|
|
DBG2(DBG_TLS, "disabling %N suites, no backend found", key_type_names, key);
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
if (suites[i].key != key)
|
|
|
|
{
|
|
|
|
suites[remaining] = suites[i];
|
|
|
|
remaining++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
|
2010-09-06 14:37:45 +00:00
|
|
|
/**
|
|
|
|
* Filter suites by key exchange user config
|
|
|
|
*/
|
|
|
|
static void filter_key_exchange_config_suites(private_tls_crypto_t *this,
|
|
|
|
suite_algs_t suites[], int *count)
|
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
int i, remaining = 0;
|
|
|
|
char *token, *config;
|
|
|
|
|
2014-01-28 16:26:50 +00:00
|
|
|
config = lib->settings->get_str(lib->settings, "%s.tls.key_exchange", NULL,
|
|
|
|
lib->ns);
|
2010-09-06 14:37:45 +00:00
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
enumerator = enumerator_create_token(config, ",", " ");
|
|
|
|
while (enumerator->enumerate(enumerator, &token))
|
|
|
|
{
|
|
|
|
if (strcaseeq(token, "ecdhe-ecdsa") &&
|
|
|
|
diffie_hellman_group_is_ec(suites[i].dh) &&
|
|
|
|
suites[i].key == KEY_ECDSA)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "ecdhe-rsa") &&
|
|
|
|
diffie_hellman_group_is_ec(suites[i].dh) &&
|
|
|
|
suites[i].key == KEY_RSA)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "dhe-rsa") &&
|
|
|
|
!diffie_hellman_group_is_ec(suites[i].dh) &&
|
|
|
|
suites[i].dh != MODP_NONE &&
|
|
|
|
suites[i].key == KEY_RSA)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "rsa") &&
|
|
|
|
suites[i].dh == MODP_NONE &&
|
|
|
|
suites[i].key == KEY_RSA)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter suites by cipher user config
|
|
|
|
*/
|
|
|
|
static void filter_cipher_config_suites(private_tls_crypto_t *this,
|
|
|
|
suite_algs_t suites[], int *count)
|
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
int i, remaining = 0;
|
|
|
|
char *token, *config;
|
|
|
|
|
2014-01-28 16:26:50 +00:00
|
|
|
config = lib->settings->get_str(lib->settings, "%s.tls.cipher", NULL,
|
|
|
|
lib->ns);
|
2010-09-06 14:37:45 +00:00
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
enumerator = enumerator_create_token(config, ",", " ");
|
|
|
|
while (enumerator->enumerate(enumerator, &token))
|
|
|
|
{
|
|
|
|
if (strcaseeq(token, "aes128") &&
|
|
|
|
suites[i].encr == ENCR_AES_CBC &&
|
|
|
|
suites[i].encr_size == 16)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "aes256") &&
|
|
|
|
suites[i].encr == ENCR_AES_CBC &&
|
|
|
|
suites[i].encr_size == 32)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
2014-02-03 17:08:11 +00:00
|
|
|
if (strcaseeq(token, "aes128gcm") &&
|
|
|
|
suites[i].encr == ENCR_AES_GCM_ICV16 &&
|
|
|
|
suites[i].encr_size == 16)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "aes256gcm") &&
|
|
|
|
suites[i].encr == ENCR_AES_GCM_ICV16 &&
|
|
|
|
suites[i].encr_size == 32)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
2010-09-06 14:37:45 +00:00
|
|
|
if (strcaseeq(token, "camellia128") &&
|
|
|
|
suites[i].encr == ENCR_CAMELLIA_CBC &&
|
|
|
|
suites[i].encr_size == 16)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "camellia256") &&
|
|
|
|
suites[i].encr == ENCR_CAMELLIA_CBC &&
|
|
|
|
suites[i].encr_size == 32)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "3des") &&
|
|
|
|
suites[i].encr == ENCR_3DES)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "null") &&
|
|
|
|
suites[i].encr == ENCR_NULL)
|
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter suites by mac user config
|
|
|
|
*/
|
|
|
|
static void filter_mac_config_suites(private_tls_crypto_t *this,
|
|
|
|
suite_algs_t suites[], int *count)
|
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
int i, remaining = 0;
|
|
|
|
char *token, *config;
|
|
|
|
|
2014-01-28 16:26:50 +00:00
|
|
|
config = lib->settings->get_str(lib->settings, "%s.tls.mac", NULL,
|
|
|
|
lib->ns);
|
2010-09-06 14:37:45 +00:00
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
enumerator = enumerator_create_token(config, ",", " ");
|
|
|
|
while (enumerator->enumerate(enumerator, &token))
|
|
|
|
{
|
|
|
|
if (strcaseeq(token, "md5") &&
|
2012-02-07 08:37:51 +00:00
|
|
|
suites[i].mac == AUTH_HMAC_MD5_128)
|
2010-09-06 14:37:45 +00:00
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "sha1") &&
|
2012-02-07 08:37:51 +00:00
|
|
|
suites[i].mac == AUTH_HMAC_SHA1_160)
|
2010-09-06 14:37:45 +00:00
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "sha256") &&
|
2012-02-07 08:37:51 +00:00
|
|
|
suites[i].mac == AUTH_HMAC_SHA2_256_256)
|
2010-09-06 14:37:45 +00:00
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (strcaseeq(token, "sha384") &&
|
2012-02-07 08:37:51 +00:00
|
|
|
suites[i].mac == AUTH_HMAC_SHA2_384_384)
|
2010-09-06 14:37:45 +00:00
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-06 14:44:47 +00:00
|
|
|
/**
|
|
|
|
* Filter for specific suites specified in strongswan.conf
|
|
|
|
*/
|
|
|
|
static void filter_specific_config_suites(private_tls_crypto_t *this,
|
|
|
|
suite_algs_t suites[], int *count)
|
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
int i, remaining = 0, suite;
|
|
|
|
char *token, *config;
|
|
|
|
|
2014-01-28 16:26:50 +00:00
|
|
|
config = lib->settings->get_str(lib->settings, "%s.tls.suites", NULL,
|
|
|
|
lib->ns);
|
2010-09-06 14:44:47 +00:00
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
for (i = 0; i < *count; i++)
|
|
|
|
{
|
|
|
|
enumerator = enumerator_create_token(config, ",", " ");
|
|
|
|
while (enumerator->enumerate(enumerator, &token))
|
|
|
|
{
|
2014-05-16 09:57:54 +00:00
|
|
|
if (enum_from_name(tls_cipher_suite_names, token, &suite) &&
|
|
|
|
suite == suites[i].suite)
|
2010-09-06 14:44:47 +00:00
|
|
|
{
|
|
|
|
suites[remaining++] = suites[i];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
|
|
|
*count = remaining;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-24 13:28:50 +00:00
|
|
|
/**
|
|
|
|
* Filter out unsupported suites on given suite array
|
|
|
|
*/
|
|
|
|
static void filter_unsupported_suites(suite_algs_t suites[], int *count)
|
|
|
|
{
|
|
|
|
/* filter suite list by each algorithm */
|
2020-05-21 07:37:38 +00:00
|
|
|
if (suites->tls_version < TLS_1_3)
|
|
|
|
{
|
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, encr),
|
|
|
|
lib->crypto->create_aead_enumerator);
|
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, prf),
|
|
|
|
lib->crypto->create_prf_enumerator);
|
|
|
|
}
|
2014-03-24 13:28:50 +00:00
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, encr),
|
|
|
|
lib->crypto->create_crypter_enumerator);
|
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, mac),
|
|
|
|
lib->crypto->create_signer_enumerator);
|
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, hash),
|
|
|
|
lib->crypto->create_hasher_enumerator);
|
|
|
|
filter_suite(suites, count, offsetof(suite_algs_t, dh),
|
|
|
|
lib->crypto->create_dh_enumerator);
|
|
|
|
}
|
|
|
|
|
2010-08-20 10:10:21 +00:00
|
|
|
/**
|
|
|
|
* Initialize the cipher suite list
|
|
|
|
*/
|
2010-08-20 13:02:25 +00:00
|
|
|
static void build_cipher_suite_list(private_tls_crypto_t *this,
|
|
|
|
bool require_encryption)
|
2010-08-20 10:10:21 +00:00
|
|
|
{
|
|
|
|
suite_algs_t suites[countof(suite_algs)];
|
|
|
|
int count = countof(suite_algs), i;
|
2010-01-25 11:21:57 +00:00
|
|
|
|
2010-08-20 10:10:21 +00:00
|
|
|
/* copy all suites */
|
2010-01-25 11:21:57 +00:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
2010-08-20 10:10:21 +00:00
|
|
|
suites[i] = suite_algs[i];
|
2010-02-04 10:17:48 +00:00
|
|
|
}
|
2014-03-24 13:28:50 +00:00
|
|
|
|
2010-08-20 13:02:25 +00:00
|
|
|
if (require_encryption)
|
|
|
|
{
|
2014-03-24 13:28:50 +00:00
|
|
|
filter_null_suites(suites, &count);
|
2010-08-20 13:02:25 +00:00
|
|
|
}
|
2010-09-03 16:11:03 +00:00
|
|
|
if (!this->rsa)
|
|
|
|
{
|
|
|
|
filter_key_suites(this, suites, &count, KEY_RSA);
|
|
|
|
}
|
|
|
|
if (!this->ecdsa)
|
|
|
|
{
|
|
|
|
filter_key_suites(this, suites, &count, KEY_ECDSA);
|
|
|
|
}
|
|
|
|
|
2014-03-24 13:28:50 +00:00
|
|
|
filter_unsupported_suites(suites, &count);
|
2010-08-20 10:10:21 +00:00
|
|
|
|
2010-09-06 14:37:45 +00:00
|
|
|
/* filter suites with strongswan.conf options */
|
|
|
|
filter_key_exchange_config_suites(this, suites, &count);
|
|
|
|
filter_cipher_config_suites(this, suites, &count);
|
|
|
|
filter_mac_config_suites(this, suites, &count);
|
2010-09-06 14:44:47 +00:00
|
|
|
filter_specific_config_suites(this, suites, &count);
|
2010-09-06 14:37:45 +00:00
|
|
|
|
2010-08-21 10:51:54 +00:00
|
|
|
free(this->suites);
|
|
|
|
this->suite_count = count;
|
|
|
|
this->suites = malloc(sizeof(tls_cipher_suite_t) * count);
|
|
|
|
|
2010-08-20 13:57:47 +00:00
|
|
|
DBG2(DBG_TLS, "%d supported TLS cipher suites:", count);
|
2010-08-20 10:10:21 +00:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
2010-08-20 13:57:47 +00:00
|
|
|
DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i].suite);
|
2010-08-21 10:51:54 +00:00
|
|
|
this->suites[i] = suites[i].suite;
|
2010-08-20 10:10:21 +00:00
|
|
|
}
|
2010-02-04 10:17:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(tls_crypto_t, get_cipher_suites, int,
|
|
|
|
private_tls_crypto_t *this, tls_cipher_suite_t **suites)
|
|
|
|
{
|
|
|
|
*suites = this->suites;
|
|
|
|
return this->suite_count;
|
|
|
|
}
|
|
|
|
|
2014-02-03 12:20:46 +00:00
|
|
|
/**
|
|
|
|
* Create NULL encryption transforms
|
|
|
|
*/
|
|
|
|
static bool create_null(private_tls_crypto_t *this, suite_algs_t *algs)
|
|
|
|
{
|
|
|
|
this->aead_in = tls_aead_create_null(algs->mac);
|
|
|
|
this->aead_out = tls_aead_create_null(algs->mac);
|
|
|
|
if (!this->aead_in || !this->aead_out)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "selected TLS MAC %N not supported",
|
|
|
|
integrity_algorithm_names, algs->mac);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create traditional transforms
|
|
|
|
*/
|
|
|
|
static bool create_traditional(private_tls_crypto_t *this, suite_algs_t *algs)
|
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) < TLS_1_1)
|
2014-02-03 12:20:46 +00:00
|
|
|
{
|
|
|
|
this->aead_in = tls_aead_create_implicit(algs->mac,
|
|
|
|
algs->encr, algs->encr_size);
|
|
|
|
this->aead_out = tls_aead_create_implicit(algs->mac,
|
|
|
|
algs->encr, algs->encr_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->aead_in = tls_aead_create_explicit(algs->mac,
|
|
|
|
algs->encr, algs->encr_size);
|
|
|
|
this->aead_out = tls_aead_create_explicit(algs->mac,
|
|
|
|
algs->encr, algs->encr_size);
|
|
|
|
}
|
|
|
|
if (!this->aead_in || !this->aead_out)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "selected TLS transforms %N-%u-%N not supported",
|
|
|
|
encryption_algorithm_names, algs->encr, algs->encr_size * 8,
|
|
|
|
integrity_algorithm_names, algs->mac);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-02-03 17:03:41 +00:00
|
|
|
/**
|
|
|
|
* Create AEAD transforms
|
|
|
|
*/
|
|
|
|
static bool create_aead(private_tls_crypto_t *this, suite_algs_t *algs)
|
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) < TLS_1_3)
|
|
|
|
{
|
|
|
|
this->aead_in = tls_aead_create_aead(algs->encr, algs->encr_size);
|
|
|
|
this->aead_out = tls_aead_create_aead(algs->encr, algs->encr_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->aead_in = tls_aead_create_seq(algs->encr, algs->encr_size);
|
|
|
|
this->aead_out = tls_aead_create_seq(algs->encr, algs->encr_size);
|
|
|
|
|
|
|
|
this->protection->set_cipher(this->protection, TRUE, this->aead_in);
|
|
|
|
this->protection->set_cipher(this->protection, FALSE, this->aead_out);
|
|
|
|
|
|
|
|
}
|
2014-02-03 17:03:41 +00:00
|
|
|
if (!this->aead_in || !this->aead_out)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "selected TLS transforms %N-%u not supported",
|
|
|
|
encryption_algorithm_names, algs->encr, algs->encr_size * 8);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-02-03 12:20:46 +00:00
|
|
|
/**
|
|
|
|
* Clean up and unset AEAD transforms
|
|
|
|
*/
|
|
|
|
static void destroy_aeads(private_tls_crypto_t *this)
|
|
|
|
{
|
|
|
|
DESTROY_IF(this->aead_in);
|
|
|
|
DESTROY_IF(this->aead_out);
|
|
|
|
this->aead_in = this->aead_out = NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-04 17:18:10 +00:00
|
|
|
/**
|
|
|
|
* Create crypto primitives
|
|
|
|
*/
|
2010-09-03 10:50:18 +00:00
|
|
|
static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs)
|
2010-02-04 17:18:10 +00:00
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
destroy_aeads(this);
|
2010-02-04 17:18:10 +00:00
|
|
|
DESTROY_IF(this->prf);
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) < TLS_1_3)
|
2010-02-04 17:18:10 +00:00
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) < TLS_1_2)
|
|
|
|
{
|
|
|
|
this->prf = tls_prf_create_10();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->prf = tls_prf_create_12(algs->prf);
|
|
|
|
}
|
|
|
|
if (!this->prf)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "selected TLS PRF not supported");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
this->hkdf = tls_hkdf_create(algs->hash, chunk_empty);
|
|
|
|
if (!this->hkdf)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "TLS HKDF creation unsuccessful");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
if (algs->encr == ENCR_NULL)
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
if (create_null(this, algs))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
2014-02-03 17:03:41 +00:00
|
|
|
else if (encryption_algorithm_is_aead(algs->encr))
|
|
|
|
{
|
|
|
|
if (create_aead(this, algs))
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
else
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
if (create_traditional(this, algs))
|
2010-02-04 17:18:10 +00:00
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
return TRUE;
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-03 12:20:46 +00:00
|
|
|
destroy_aeads(this);
|
|
|
|
return FALSE;
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
|
2010-02-04 10:17:48 +00:00
|
|
|
METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
|
2010-09-03 10:50:18 +00:00
|
|
|
private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count,
|
|
|
|
key_type_t key)
|
2010-02-04 10:17:48 +00:00
|
|
|
{
|
2010-09-03 10:50:18 +00:00
|
|
|
suite_algs_t *algs;
|
2010-02-04 10:17:48 +00:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i = 0; i < this->suite_count; i++)
|
|
|
|
{
|
|
|
|
for (j = 0; j < count; j++)
|
|
|
|
{
|
|
|
|
if (this->suites[i] == suites[j])
|
|
|
|
{
|
2010-09-03 10:50:18 +00:00
|
|
|
algs = find_suite(this->suites[i]);
|
|
|
|
if (algs)
|
2010-02-04 17:18:10 +00:00
|
|
|
{
|
2010-09-03 10:50:18 +00:00
|
|
|
if (key == KEY_ANY || key == algs->key)
|
|
|
|
{
|
|
|
|
if (create_ciphers(this, algs))
|
|
|
|
{
|
|
|
|
this->suite = this->suites[i];
|
|
|
|
return this->suite;
|
|
|
|
}
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
2010-02-04 10:17:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-09-02 17:24:56 +00:00
|
|
|
METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t,
|
|
|
|
private_tls_crypto_t *this)
|
|
|
|
{
|
|
|
|
suite_algs_t *algs;
|
|
|
|
|
|
|
|
algs = find_suite(this->suite);
|
|
|
|
if (algs)
|
|
|
|
{
|
|
|
|
return algs->dh;
|
|
|
|
}
|
|
|
|
return MODP_NONE;
|
|
|
|
}
|
|
|
|
|
2014-01-15 14:51:03 +00:00
|
|
|
/**
|
|
|
|
* Map signature schemes to TLS key types and hashes, ordered by preference
|
|
|
|
*/
|
|
|
|
static struct {
|
|
|
|
tls_signature_algorithm_t sig;
|
|
|
|
tls_hash_algorithm_t hash;
|
|
|
|
signature_scheme_t scheme;
|
|
|
|
} schemes[] = {
|
2016-09-22 06:50:43 +00:00
|
|
|
{ TLS_SIG_ECDSA, TLS_HASH_SHA256, SIGN_ECDSA_WITH_SHA256_DER },
|
|
|
|
{ TLS_SIG_ECDSA, TLS_HASH_SHA384, SIGN_ECDSA_WITH_SHA384_DER },
|
|
|
|
{ TLS_SIG_ECDSA, TLS_HASH_SHA512, SIGN_ECDSA_WITH_SHA512_DER },
|
|
|
|
{ TLS_SIG_ECDSA, TLS_HASH_SHA1, SIGN_ECDSA_WITH_SHA1_DER },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_SHA256, SIGN_RSA_EMSA_PKCS1_SHA2_256 },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_SHA384, SIGN_RSA_EMSA_PKCS1_SHA2_384 },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_SHA512, SIGN_RSA_EMSA_PKCS1_SHA2_512 },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_SHA224, SIGN_RSA_EMSA_PKCS1_SHA2_224 },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_SHA1, SIGN_RSA_EMSA_PKCS1_SHA1 },
|
|
|
|
{ TLS_SIG_RSA, TLS_HASH_MD5, SIGN_RSA_EMSA_PKCS1_MD5 },
|
2014-01-15 14:51:03 +00:00
|
|
|
};
|
|
|
|
|
2010-09-02 17:15:16 +00:00
|
|
|
METHOD(tls_crypto_t, get_signature_algorithms, void,
|
2011-05-31 13:46:30 +00:00
|
|
|
private_tls_crypto_t *this, bio_writer_t *writer)
|
2010-09-02 17:15:16 +00:00
|
|
|
{
|
2011-05-31 13:46:30 +00:00
|
|
|
bio_writer_t *supported;
|
2014-01-15 14:51:03 +00:00
|
|
|
int i;
|
2010-09-02 17:15:16 +00:00
|
|
|
|
2011-05-31 13:46:30 +00:00
|
|
|
supported = bio_writer_create(32);
|
2014-01-15 14:51:03 +00:00
|
|
|
|
|
|
|
for (i = 0; i < countof(schemes); i++)
|
2010-09-02 17:15:16 +00:00
|
|
|
{
|
2014-01-15 14:51:03 +00:00
|
|
|
if (schemes[i].sig == TLS_SIG_RSA && !this->rsa)
|
2010-09-02 17:15:16 +00:00
|
|
|
{
|
2014-01-15 14:51:03 +00:00
|
|
|
continue;
|
2010-09-02 17:15:16 +00:00
|
|
|
}
|
2014-01-15 14:51:03 +00:00
|
|
|
if (schemes[i].sig == TLS_SIG_ECDSA && !this->ecdsa)
|
2010-09-02 17:15:16 +00:00
|
|
|
{
|
2014-01-15 14:51:03 +00:00
|
|
|
continue;
|
2010-09-03 16:11:03 +00:00
|
|
|
}
|
2020-05-21 07:37:38 +00:00
|
|
|
if (schemes[i].hash == TLS_HASH_MD5 && !this->md5)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (schemes[i].hash == TLS_HASH_SHA1 && !this->sha1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (schemes[i].hash == TLS_HASH_SHA224 && !this->sha224)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (schemes[i].hash == TLS_HASH_SHA256 && !this->sha256)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (schemes[i].hash == TLS_HASH_SHA384 && !this->sha384)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (schemes[i].hash == TLS_HASH_SHA512 && !this->sha512)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2014-01-15 14:51:03 +00:00
|
|
|
if (!lib->plugins->has_feature(lib->plugins,
|
|
|
|
PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)))
|
|
|
|
{
|
|
|
|
continue;
|
2010-09-02 17:15:16 +00:00
|
|
|
}
|
2014-01-15 14:51:03 +00:00
|
|
|
supported->write_uint8(supported, schemes[i].hash);
|
|
|
|
supported->write_uint8(supported, schemes[i].sig);
|
2010-09-02 17:15:16 +00:00
|
|
|
}
|
|
|
|
|
2012-11-28 09:18:28 +00:00
|
|
|
supported->wrap16(supported);
|
2010-09-02 17:15:16 +00:00
|
|
|
writer->write_data16(writer, supported->get_buf(supported));
|
|
|
|
supported->destroy(supported);
|
|
|
|
}
|
|
|
|
|
2014-01-15 14:51:03 +00:00
|
|
|
/**
|
|
|
|
* Get the signature scheme from a TLS 1.2 hash/sig algorithm pair
|
|
|
|
*/
|
|
|
|
static signature_scheme_t hashsig_to_scheme(key_type_t type,
|
|
|
|
tls_hash_algorithm_t hash,
|
|
|
|
tls_signature_algorithm_t sig)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ((sig == TLS_SIG_RSA && type == KEY_RSA) ||
|
|
|
|
(sig == TLS_SIG_ECDSA && type == KEY_ECDSA))
|
|
|
|
{
|
|
|
|
for (i = 0; i < countof(schemes); i++)
|
|
|
|
{
|
|
|
|
if (schemes[i].sig == sig && schemes[i].hash == hash)
|
|
|
|
{
|
|
|
|
return schemes[i].scheme;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return SIGN_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2010-09-03 15:05:39 +00:00
|
|
|
/**
|
|
|
|
* Mapping groups to TLS named curves
|
|
|
|
*/
|
|
|
|
static struct {
|
|
|
|
diffie_hellman_group_t group;
|
2020-05-21 07:37:38 +00:00
|
|
|
tls_named_group_t curve;
|
2010-09-03 15:05:39 +00:00
|
|
|
} curves[] = {
|
|
|
|
{ ECP_256_BIT, TLS_SECP256R1},
|
|
|
|
{ ECP_384_BIT, TLS_SECP384R1},
|
|
|
|
{ ECP_521_BIT, TLS_SECP521R1},
|
|
|
|
{ ECP_224_BIT, TLS_SECP224R1},
|
|
|
|
{ ECP_192_BIT, TLS_SECP192R1},
|
|
|
|
};
|
|
|
|
|
2017-05-12 10:10:27 +00:00
|
|
|
CALLBACK(group_filter, bool,
|
|
|
|
void *null, enumerator_t *orig, va_list args)
|
2010-09-03 15:05:39 +00:00
|
|
|
{
|
2017-05-12 10:10:27 +00:00
|
|
|
diffie_hellman_group_t group, *out;
|
2020-05-21 07:37:38 +00:00
|
|
|
tls_named_group_t *curve;
|
2017-05-12 10:10:27 +00:00
|
|
|
char *plugin;
|
2010-09-03 15:05:39 +00:00
|
|
|
int i;
|
|
|
|
|
2017-05-12 10:10:27 +00:00
|
|
|
VA_ARGS_VGET(args, out, curve);
|
|
|
|
|
|
|
|
while (orig->enumerate(orig, &group, &plugin))
|
2010-09-03 15:05:39 +00:00
|
|
|
{
|
2017-05-12 10:10:27 +00:00
|
|
|
for (i = 0; i < countof(curves); i++)
|
2010-09-03 15:05:39 +00:00
|
|
|
{
|
2017-05-12 10:10:27 +00:00
|
|
|
if (curves[i].group == group)
|
2010-09-03 15:05:39 +00:00
|
|
|
{
|
2017-05-12 10:10:27 +00:00
|
|
|
if (out)
|
|
|
|
{
|
|
|
|
*out = curves[i].group;
|
|
|
|
}
|
|
|
|
if (curve)
|
|
|
|
{
|
|
|
|
*curve = curves[i].curve;
|
|
|
|
}
|
|
|
|
return TRUE;
|
2010-09-03 15:05:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*,
|
|
|
|
private_tls_crypto_t *this)
|
2010-09-03 09:45:55 +00:00
|
|
|
{
|
2010-09-03 15:05:39 +00:00
|
|
|
return enumerator_create_filter(
|
2017-05-12 10:10:27 +00:00
|
|
|
lib->crypto->create_dh_enumerator(lib->crypto),
|
|
|
|
group_filter, NULL, NULL);
|
2010-09-03 09:45:55 +00:00
|
|
|
}
|
|
|
|
|
2010-02-05 13:39:19 +00:00
|
|
|
METHOD(tls_crypto_t, set_protection, void,
|
|
|
|
private_tls_crypto_t *this, tls_protection_t *protection)
|
|
|
|
{
|
|
|
|
this->protection = protection;
|
|
|
|
}
|
|
|
|
|
2010-02-05 13:25:38 +00:00
|
|
|
METHOD(tls_crypto_t, append_handshake, void,
|
|
|
|
private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
|
|
|
|
{
|
2016-03-22 12:22:01 +00:00
|
|
|
uint32_t header;
|
2010-02-05 13:25:38 +00:00
|
|
|
|
|
|
|
/* reconstruct handshake header */
|
|
|
|
header = htonl(data.len | (type << 24));
|
|
|
|
this->handshake = chunk_cat("mcc", this->handshake,
|
|
|
|
chunk_from_thing(header), data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2010-09-02 17:15:16 +00:00
|
|
|
* Create a hash using the suites HASH algorithm
|
2010-02-05 13:25:38 +00:00
|
|
|
*/
|
2010-09-02 17:15:16 +00:00
|
|
|
static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) >= TLS_1_2)
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
|
|
|
hasher_t *hasher;
|
|
|
|
suite_algs_t *alg;
|
|
|
|
|
|
|
|
alg = find_suite(this->suite);
|
|
|
|
if (!alg)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
|
2012-07-09 15:15:52 +00:00
|
|
|
if (!hasher || !hasher->allocate_hash(hasher, data, hash))
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2010-08-20 13:57:47 +00:00
|
|
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
|
2012-07-09 15:15:52 +00:00
|
|
|
DESTROY_IF(hasher);
|
2010-02-05 13:25:38 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
hasher->destroy(hasher);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hasher_t *md5, *sha1;
|
|
|
|
char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
|
|
|
|
|
|
|
|
md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
|
2012-07-09 13:33:41 +00:00
|
|
|
if (!md5 || !md5->get_hash(md5, data, buf))
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2010-08-20 13:57:47 +00:00
|
|
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
|
2012-07-09 13:33:41 +00:00
|
|
|
DESTROY_IF(md5);
|
2010-02-05 13:25:38 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
md5->destroy(md5);
|
|
|
|
sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
2012-07-09 13:33:41 +00:00
|
|
|
if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5))
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2010-08-20 13:57:47 +00:00
|
|
|
DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
|
2012-07-09 13:33:41 +00:00
|
|
|
DESTROY_IF(sha1);
|
2010-02-05 13:25:38 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
sha1->destroy(sha1);
|
|
|
|
|
|
|
|
*hash = chunk_clone(chunk_from_thing(buf));
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-09-02 17:15:16 +00:00
|
|
|
METHOD(tls_crypto_t, sign, bool,
|
2011-05-31 13:46:30 +00:00
|
|
|
private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
|
2010-09-02 17:15:16 +00:00
|
|
|
chunk_t data, chunk_t hashsig)
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) >= TLS_1_2)
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2020-01-29 09:02:38 +00:00
|
|
|
const chunk_t hashsig_def = chunk_from_chars(
|
|
|
|
TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA);
|
2010-09-02 08:29:32 +00:00
|
|
|
signature_scheme_t scheme;
|
2011-05-31 13:46:30 +00:00
|
|
|
bio_reader_t *reader;
|
2016-03-22 12:22:01 +00:00
|
|
|
uint8_t hash, alg;
|
2010-09-02 08:29:32 +00:00
|
|
|
chunk_t sig;
|
|
|
|
bool done = FALSE;
|
|
|
|
|
2010-09-02 17:15:16 +00:00
|
|
|
if (!hashsig.len)
|
|
|
|
{ /* fallback if none given */
|
2020-01-29 09:02:38 +00:00
|
|
|
hashsig = hashsig_def;
|
2010-09-02 17:15:16 +00:00
|
|
|
}
|
2011-05-31 13:46:30 +00:00
|
|
|
reader = bio_reader_create(hashsig);
|
2010-09-02 08:29:32 +00:00
|
|
|
while (reader->remaining(reader) >= 2)
|
2010-02-09 17:19:25 +00:00
|
|
|
{
|
2010-09-02 08:29:32 +00:00
|
|
|
if (reader->read_uint8(reader, &hash) &&
|
|
|
|
reader->read_uint8(reader, &alg))
|
|
|
|
{
|
|
|
|
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
|
|
|
if (scheme != SIGN_UNKNOWN &&
|
2017-09-19 15:26:58 +00:00
|
|
|
key->sign(key, scheme, NULL, data, &sig))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
done = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
reader->destroy(reader);
|
|
|
|
if (!done)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported");
|
2010-02-09 17:19:25 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "created signature with %N/%N",
|
2010-09-02 08:29:32 +00:00
|
|
|
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
|
|
|
writer->write_uint8(writer, hash);
|
|
|
|
writer->write_uint8(writer, alg);
|
2010-02-09 17:19:25 +00:00
|
|
|
writer->write_data16(writer, sig);
|
|
|
|
free(sig.ptr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-09-02 08:29:32 +00:00
|
|
|
chunk_t sig, hash;
|
2010-09-02 17:15:16 +00:00
|
|
|
bool done;
|
2010-09-02 08:29:32 +00:00
|
|
|
|
|
|
|
switch (key->get_type(key))
|
2010-02-09 17:19:25 +00:00
|
|
|
{
|
2010-09-02 08:29:32 +00:00
|
|
|
case KEY_RSA:
|
2010-09-02 17:15:16 +00:00
|
|
|
if (!hash_data(this, data, &hash))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-09-19 15:26:58 +00:00
|
|
|
done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
|
|
|
|
&sig);
|
2010-09-02 17:15:16 +00:00
|
|
|
free(hash.ptr);
|
|
|
|
if (!done)
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA");
|
2010-09-02 08:29:32 +00:00
|
|
|
break;
|
|
|
|
case KEY_ECDSA:
|
2017-09-19 15:26:58 +00:00
|
|
|
if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, &sig))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "created signature with SHA1/ECDSA");
|
2010-09-02 08:29:32 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
2010-02-09 17:19:25 +00:00
|
|
|
}
|
|
|
|
writer->write_data16(writer, sig);
|
|
|
|
free(sig.ptr);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-09-02 17:15:16 +00:00
|
|
|
METHOD(tls_crypto_t, verify, bool,
|
2011-05-31 13:46:30 +00:00
|
|
|
private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader,
|
2010-09-02 17:15:16 +00:00
|
|
|
chunk_t data)
|
2010-02-09 17:19:25 +00:00
|
|
|
{
|
2020-05-21 07:37:38 +00:00
|
|
|
if (this->tls->get_version_max(this->tls) == TLS_1_3)
|
|
|
|
{
|
|
|
|
signature_scheme_t scheme = SIGN_UNKNOWN;
|
|
|
|
uint8_t hash, alg;
|
|
|
|
chunk_t sig, transcript_hash, static_sig_data_all;
|
|
|
|
|
|
|
|
chunk_t static_sig_data = chunk_from_chars(
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
|
|
0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c,
|
|
|
|
0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
|
|
|
|
0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
|
|
|
|
0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66,
|
|
|
|
0x79, 0x00,
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!reader->read_uint8(reader, &hash) ||
|
|
|
|
!reader->read_uint8(reader, &alg) ||
|
|
|
|
!reader->read_data16(reader, &sig))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "received invalid signature");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hash_data(this, data, &transcript_hash))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "Unable to hash");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static_sig_data_all = chunk_cat("cc", static_sig_data, transcript_hash);
|
|
|
|
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
|
|
|
if (scheme == SIGN_UNKNOWN)
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "signature algorithms %N/%N not supported",
|
|
|
|
tls_hash_algorithm_names, hash,
|
|
|
|
tls_signature_algorithm_names, alg);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!key->verify(key, scheme, NULL, static_sig_data_all, sig))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "verification of signature failed");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
DBG2(DBG_TLS,
|
|
|
|
"verified signature with %N/%N",
|
|
|
|
tls_hash_algorithm_names,
|
|
|
|
hash,
|
|
|
|
tls_signature_algorithm_names,
|
|
|
|
alg);
|
|
|
|
}
|
|
|
|
else if (this->tls->get_version_max(this->tls) == TLS_1_2)
|
2010-02-09 17:19:25 +00:00
|
|
|
{
|
2010-09-02 08:29:32 +00:00
|
|
|
signature_scheme_t scheme = SIGN_UNKNOWN;
|
2016-03-22 12:22:01 +00:00
|
|
|
uint8_t hash, alg;
|
2010-02-09 17:19:25 +00:00
|
|
|
chunk_t sig;
|
2010-02-05 13:25:38 +00:00
|
|
|
|
2010-02-09 17:19:25 +00:00
|
|
|
if (!reader->read_uint8(reader, &hash) ||
|
|
|
|
!reader->read_uint8(reader, &alg) ||
|
|
|
|
!reader->read_data16(reader, &sig))
|
|
|
|
{
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG1(DBG_TLS, "received invalid signature");
|
2010-02-09 17:19:25 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 08:29:32 +00:00
|
|
|
scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
|
|
|
|
if (scheme == SIGN_UNKNOWN)
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG1(DBG_TLS, "signature algorithms %N/%N not supported",
|
2010-09-02 08:29:32 +00:00
|
|
|
tls_hash_algorithm_names, hash,
|
|
|
|
tls_signature_algorithm_names, alg);
|
2010-02-05 13:25:38 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2017-09-19 15:15:18 +00:00
|
|
|
if (!key->verify(key, scheme, NULL, data, sig))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "verified signature with %N/%N",
|
2010-09-02 08:29:32 +00:00
|
|
|
tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
|
2010-02-05 13:25:38 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-02-09 17:19:25 +00:00
|
|
|
chunk_t sig, hash;
|
2010-09-02 17:15:16 +00:00
|
|
|
bool done;
|
2010-02-05 13:25:38 +00:00
|
|
|
|
2010-02-09 17:19:25 +00:00
|
|
|
if (!reader->read_data16(reader, &sig))
|
|
|
|
{
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG1(DBG_TLS, "received invalid signature");
|
2010-02-09 17:19:25 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 08:29:32 +00:00
|
|
|
switch (key->get_type(key))
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
2010-09-02 08:29:32 +00:00
|
|
|
case KEY_RSA:
|
2010-09-02 17:15:16 +00:00
|
|
|
if (!hash_data(this, data, &hash))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2017-09-19 15:15:18 +00:00
|
|
|
done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
|
|
|
|
sig);
|
2010-09-02 17:15:16 +00:00
|
|
|
free(hash.ptr);
|
|
|
|
if (!done)
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA");
|
2010-09-02 08:29:32 +00:00
|
|
|
break;
|
|
|
|
case KEY_ECDSA:
|
2017-09-19 15:15:18 +00:00
|
|
|
if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data,
|
|
|
|
sig))
|
2010-09-02 08:29:32 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
DBG2(DBG_TLS, "verified signature with SHA1/ECDSA");
|
2010-09-02 08:29:32 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
2010-02-05 13:25:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2010-09-02 17:15:16 +00:00
|
|
|
METHOD(tls_crypto_t, sign_handshake, bool,
|
2011-05-31 13:46:30 +00:00
|
|
|
private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
|
2010-09-02 17:15:16 +00:00
|
|
|
chunk_t hashsig)
|
|
|
|
{
|
|
|
|
return sign(this, key, writer, this->handshake, hashsig);
|
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(tls_crypto_t, verify_handshake, bool,
|
2011-05-31 13:46:30 +00:00
|
|
|
private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader)
|
2010-09-02 17:15:16 +00:00
|
|
|
{
|
|
|
|
return verify(this, key, reader, this->handshake);
|
|
|
|
}
|
|
|
|
|
2010-02-05 13:25:38 +00:00
|
|
|
METHOD(tls_crypto_t, calculate_finished, bool,
|
|
|
|
private_tls_crypto_t *this, char *label, char out[12])
|
|
|
|
{
|
|
|
|
chunk_t seed;
|
|
|
|
|
|
|
|
if (!this->prf)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-09-02 17:15:16 +00:00
|
|
|
if (!hash_data(this, this->handshake, &seed))
|
2010-02-05 13:25:38 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2012-07-06 07:49:16 +00:00
|
|
|
if (!this->prf->get_bytes(this->prf, label, seed, 12, out))
|
|
|
|
{
|
|
|
|
free(seed.ptr);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-05 13:25:38 +00:00
|
|
|
free(seed.ptr);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
METHOD(tls_crypto_t, calculate_finished_tls13, bool,
|
|
|
|
private_tls_crypto_t *this, bool is_server, chunk_t *out)
|
|
|
|
{
|
|
|
|
chunk_t finished_key, finished_hash;
|
|
|
|
prf_t *prf;
|
|
|
|
|
|
|
|
this->hkdf->derive_finished(this->hkdf, is_server, &finished_key);
|
|
|
|
if (!hash_data(this, this->handshake, &finished_hash))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "creating hash of handshake failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->suite == TLS_AES_256_GCM_SHA384)
|
|
|
|
{
|
|
|
|
prf = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA2_384);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prf = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA2_256);
|
|
|
|
}
|
|
|
|
if(!prf->set_key(prf, finished_key) ||
|
|
|
|
!prf->allocate_bytes(prf, finished_hash, out))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "setting key or generating hash for HMAC failed");
|
|
|
|
chunk_clear(&finished_key);
|
|
|
|
chunk_clear(&finished_hash);
|
|
|
|
prf->destroy(prf);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
chunk_clear(&finished_key);
|
|
|
|
chunk_clear(&finished_hash);
|
|
|
|
prf->destroy(prf);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-12-31 00:41:56 +00:00
|
|
|
/**
|
|
|
|
* Derive master secret from premaster, optionally save session
|
|
|
|
*/
|
2012-07-06 07:49:16 +00:00
|
|
|
static bool derive_master(private_tls_crypto_t *this, chunk_t premaster,
|
2011-12-31 00:41:56 +00:00
|
|
|
chunk_t session, identification_t *id,
|
|
|
|
chunk_t client_random, chunk_t server_random)
|
2010-02-04 10:17:48 +00:00
|
|
|
{
|
2010-02-04 17:18:10 +00:00
|
|
|
char master[48];
|
2011-12-31 00:41:56 +00:00
|
|
|
chunk_t seed;
|
2010-02-04 17:18:10 +00:00
|
|
|
|
|
|
|
/* derive master secret */
|
|
|
|
seed = chunk_cata("cc", client_random, server_random);
|
2012-07-06 07:49:25 +00:00
|
|
|
|
|
|
|
if (!this->prf->set_key(this->prf, premaster) ||
|
|
|
|
!this->prf->get_bytes(this->prf, "master secret", seed,
|
|
|
|
sizeof(master), master) ||
|
|
|
|
!this->prf->set_key(this->prf, chunk_from_thing(master)))
|
2012-07-06 07:49:16 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2011-12-31 00:41:56 +00:00
|
|
|
if (this->cache && session.len)
|
|
|
|
{
|
|
|
|
this->cache->create(this->cache, session, id, chunk_from_thing(master),
|
|
|
|
this->suite);
|
|
|
|
}
|
|
|
|
memwipe(master, sizeof(master));
|
2012-07-06 07:49:16 +00:00
|
|
|
return TRUE;
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Expand key material from master secret
|
|
|
|
*/
|
2012-07-06 07:28:25 +00:00
|
|
|
static bool expand_keys(private_tls_crypto_t *this,
|
2011-12-31 00:41:56 +00:00
|
|
|
chunk_t client_random, chunk_t server_random)
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
chunk_t seed, block;
|
|
|
|
chunk_t cw_mac, cw, cw_iv;
|
|
|
|
chunk_t sw_mac, sw, sw_iv;
|
|
|
|
int mklen, eklen, ivlen;
|
2010-02-04 17:18:10 +00:00
|
|
|
|
2014-02-03 12:20:46 +00:00
|
|
|
if (!this->aead_in || !this->aead_out)
|
2010-02-04 10:17:48 +00:00
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
return FALSE;
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
2014-02-03 12:20:46 +00:00
|
|
|
|
|
|
|
/* derive key block for key expansion */
|
|
|
|
mklen = this->aead_in->get_mac_key_size(this->aead_in);
|
|
|
|
eklen = this->aead_in->get_encr_key_size(this->aead_in);
|
|
|
|
ivlen = this->aead_in->get_iv_size(this->aead_in);
|
2010-02-04 17:18:10 +00:00
|
|
|
seed = chunk_cata("cc", server_random, client_random);
|
2014-02-03 12:20:46 +00:00
|
|
|
block = chunk_alloca((mklen + eklen + ivlen) * 2);
|
2012-07-06 07:49:16 +00:00
|
|
|
if (!this->prf->get_bytes(this->prf, "key expansion", seed,
|
|
|
|
block.len, block.ptr))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
|
2014-02-03 12:20:46 +00:00
|
|
|
/* client/server write signer keys */
|
|
|
|
cw_mac = chunk_create(block.ptr, mklen);
|
|
|
|
block = chunk_skip(block, mklen);
|
|
|
|
sw_mac = chunk_create(block.ptr, mklen);
|
|
|
|
block = chunk_skip(block, mklen);
|
|
|
|
|
|
|
|
/* client/server write encryption keys */
|
|
|
|
cw = chunk_create(block.ptr, eklen);
|
|
|
|
block = chunk_skip(block, eklen);
|
|
|
|
sw = chunk_create(block.ptr, eklen);
|
|
|
|
block = chunk_skip(block, eklen);
|
|
|
|
|
|
|
|
/* client/server write IV; TLS 1.0 implicit IVs or AEAD salt, if any */
|
|
|
|
cw_iv = chunk_create(block.ptr, ivlen);
|
|
|
|
block = chunk_skip(block, ivlen);
|
|
|
|
sw_iv = chunk_create(block.ptr, ivlen);
|
|
|
|
block = chunk_skip(block, ivlen);
|
|
|
|
|
2010-02-04 17:18:10 +00:00
|
|
|
if (this->tls->is_server(this->tls))
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
if (!this->aead_in->set_keys(this->aead_in, cw_mac, cw, cw_iv) ||
|
|
|
|
!this->aead_out->set_keys(this->aead_out, sw_mac, sw, sw_iv))
|
2012-07-06 07:33:10 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
if (!this->aead_out->set_keys(this->aead_out, cw_mac, cw, cw_iv) ||
|
|
|
|
!this->aead_in->set_keys(this->aead_in, sw_mac, sw, sw_iv))
|
2012-07-06 07:33:10 +00:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
|
|
|
|
2011-12-31 00:41:56 +00:00
|
|
|
/* EAP-MSK */
|
|
|
|
if (this->msk_label)
|
|
|
|
{
|
2012-02-07 09:50:02 +00:00
|
|
|
seed = chunk_cata("cc", client_random, server_random);
|
2011-12-31 00:41:56 +00:00
|
|
|
this->msk = chunk_alloc(64);
|
2012-07-06 07:49:16 +00:00
|
|
|
if (!this->prf->get_bytes(this->prf, this->msk_label, seed,
|
|
|
|
this->msk.len, this->msk.ptr))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
2012-07-06 07:28:25 +00:00
|
|
|
return TRUE;
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
|
|
|
|
2012-07-06 07:28:25 +00:00
|
|
|
METHOD(tls_crypto_t, derive_secrets, bool,
|
2011-12-31 00:41:56 +00:00
|
|
|
private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
|
|
|
|
identification_t *id, chunk_t client_random, chunk_t server_random)
|
|
|
|
{
|
2012-07-06 07:49:16 +00:00
|
|
|
return derive_master(this, premaster, session, id,
|
|
|
|
client_random, server_random) &&
|
|
|
|
expand_keys(this, client_random, server_random);
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
METHOD(tls_crypto_t, derive_handshake_secret, bool,
|
|
|
|
private_tls_crypto_t *this, chunk_t shared_secret)
|
|
|
|
{
|
|
|
|
chunk_t c_key, c_iv, s_key, s_iv;
|
|
|
|
|
|
|
|
this->hkdf->set_shared_secret(this->hkdf, shared_secret);
|
|
|
|
|
|
|
|
/* client key material */
|
|
|
|
if (!this->hkdf->generate_secret(this->hkdf, TLS_HKDF_C_HS_TRAFFIC,
|
|
|
|
this->handshake, NULL) ||
|
|
|
|
!this->hkdf->derive_key(this->hkdf, FALSE,
|
|
|
|
this->aead_out->
|
|
|
|
get_encr_key_size(this->aead_out), &c_key) ||
|
|
|
|
!this->hkdf->derive_iv(this->hkdf, FALSE,
|
|
|
|
this->aead_out->
|
|
|
|
get_iv_size(this->aead_out), &c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "deriving client key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* server key material */
|
|
|
|
if (!this->hkdf->generate_secret(this->hkdf, TLS_HKDF_S_HS_TRAFFIC,
|
|
|
|
this->handshake, NULL) ||
|
|
|
|
!this->hkdf->derive_key(this->hkdf, TRUE, this->aead_in->
|
|
|
|
get_encr_key_size(this->aead_in), &s_key) ||
|
|
|
|
!this->hkdf->derive_iv(this->hkdf, TRUE, this->aead_in->
|
|
|
|
get_iv_size(this->aead_in), &s_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "deriving server key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->tls->is_server(this->tls))
|
|
|
|
{
|
|
|
|
if (!this->aead_in->set_keys(this->aead_in, chunk_empty, s_key, s_iv) ||
|
|
|
|
!this->aead_out->set_keys(this->aead_out, chunk_empty, c_key, c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "setting aead server key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!this->aead_in->set_keys(this->aead_in, chunk_empty, s_key, s_iv) ||
|
|
|
|
!this->aead_out->set_keys(this->aead_out, chunk_empty, c_key, c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "setting aead client key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(tls_crypto_t, derive_app_secret, bool,
|
|
|
|
private_tls_crypto_t *this)
|
|
|
|
{
|
|
|
|
chunk_t c_key, c_iv, s_key, s_iv;
|
|
|
|
|
|
|
|
/* client key material */
|
|
|
|
if (!this->hkdf->generate_secret(this->hkdf, TLS_HKDF_C_AP_TRAFFIC,
|
|
|
|
this->handshake, NULL) ||
|
|
|
|
!this->hkdf->derive_key(this->hkdf, FALSE,
|
|
|
|
this->aead_out->
|
|
|
|
get_encr_key_size(this->aead_out), &c_key) ||
|
|
|
|
!this->hkdf->derive_iv(this->hkdf, FALSE,
|
|
|
|
this->aead_out->
|
|
|
|
get_iv_size(this->aead_out), &c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "deriving client key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* server key material */
|
|
|
|
if (!this->hkdf->generate_secret(this->hkdf, TLS_HKDF_S_AP_TRAFFIC,
|
|
|
|
this->handshake, NULL) ||
|
|
|
|
!this->hkdf->derive_key(this->hkdf, TRUE, this->aead_in->
|
|
|
|
get_encr_key_size(this->aead_in), &s_key) ||
|
|
|
|
!this->hkdf->derive_iv(this->hkdf, TRUE, this->aead_in->
|
|
|
|
get_iv_size(this->aead_in), &s_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "deriving server key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->tls->is_server(this->tls))
|
|
|
|
{
|
|
|
|
if (!this->aead_in->set_keys(this->aead_in, chunk_empty, s_key, s_iv) ||
|
|
|
|
!this->aead_out->set_keys(this->aead_out, chunk_empty, c_key, c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "setting aead server key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!this->aead_in->set_keys(this->aead_in, chunk_empty, s_key, s_iv) ||
|
|
|
|
!this->aead_out->set_keys(this->aead_out, chunk_empty, c_key, c_iv))
|
|
|
|
{
|
|
|
|
DBG1(DBG_TLS, "setting aead client key material failed");
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
chunk_clear(&c_key);
|
|
|
|
chunk_clear(&c_iv);
|
|
|
|
chunk_clear(&s_key);
|
|
|
|
chunk_clear(&s_iv);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-12-31 00:41:56 +00:00
|
|
|
METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
|
|
|
|
private_tls_crypto_t *this, chunk_t session, identification_t *id,
|
|
|
|
chunk_t client_random, chunk_t server_random)
|
|
|
|
{
|
|
|
|
chunk_t master;
|
|
|
|
|
|
|
|
if (this->cache && session.len)
|
|
|
|
{
|
|
|
|
this->suite = this->cache->lookup(this->cache, session, id, &master);
|
|
|
|
if (this->suite)
|
|
|
|
{
|
2012-02-07 10:41:56 +00:00
|
|
|
this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY);
|
2011-12-31 00:41:56 +00:00
|
|
|
if (this->suite)
|
|
|
|
{
|
2012-07-06 07:49:25 +00:00
|
|
|
if (!this->prf->set_key(this->prf, master) ||
|
|
|
|
!expand_keys(this, client_random, server_random))
|
2012-07-06 07:28:25 +00:00
|
|
|
{
|
|
|
|
this->suite = 0;
|
|
|
|
}
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
|
|
|
chunk_clear(&master);
|
|
|
|
}
|
2012-02-07 10:41:56 +00:00
|
|
|
return this->suite;
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
2012-02-07 10:41:56 +00:00
|
|
|
return 0;
|
2011-12-31 00:41:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(tls_crypto_t, get_session, chunk_t,
|
|
|
|
private_tls_crypto_t *this, identification_t *server)
|
|
|
|
{
|
|
|
|
if (this->cache)
|
|
|
|
{
|
|
|
|
return this->cache->check(this->cache, server);
|
|
|
|
}
|
|
|
|
return chunk_empty;
|
2010-02-04 17:18:10 +00:00
|
|
|
}
|
2010-02-04 10:17:48 +00:00
|
|
|
|
2010-02-04 17:18:10 +00:00
|
|
|
METHOD(tls_crypto_t, change_cipher, void,
|
|
|
|
private_tls_crypto_t *this, bool inbound)
|
|
|
|
{
|
2010-02-05 13:39:19 +00:00
|
|
|
if (this->protection)
|
2010-02-04 17:18:10 +00:00
|
|
|
{
|
2010-02-05 13:39:19 +00:00
|
|
|
if (inbound)
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
this->protection->set_cipher(this->protection, TRUE, this->aead_in);
|
2010-02-05 13:39:19 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
this->protection->set_cipher(this->protection, FALSE, this->aead_out);
|
2010-02-05 13:39:19 +00:00
|
|
|
}
|
2010-02-04 10:17:48 +00:00
|
|
|
}
|
2010-01-25 11:21:57 +00:00
|
|
|
}
|
|
|
|
|
2010-02-05 11:28:48 +00:00
|
|
|
METHOD(tls_crypto_t, get_eap_msk, chunk_t,
|
|
|
|
private_tls_crypto_t *this)
|
|
|
|
{
|
|
|
|
return this->msk;
|
|
|
|
}
|
|
|
|
|
2010-01-25 11:21:57 +00:00
|
|
|
METHOD(tls_crypto_t, destroy, void,
|
|
|
|
private_tls_crypto_t *this)
|
|
|
|
{
|
2014-02-03 12:20:46 +00:00
|
|
|
destroy_aeads(this);
|
2010-02-05 13:25:38 +00:00
|
|
|
free(this->handshake.ptr);
|
2010-02-05 11:28:48 +00:00
|
|
|
free(this->msk.ptr);
|
2010-02-04 10:17:48 +00:00
|
|
|
DESTROY_IF(this->prf);
|
2020-05-21 07:37:38 +00:00
|
|
|
DESTROY_IF(this->hkdf);
|
2010-02-04 17:18:10 +00:00
|
|
|
free(this->suites);
|
2010-01-25 11:21:57 +00:00
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See header
|
|
|
|
*/
|
2011-12-31 00:41:56 +00:00
|
|
|
tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
|
2010-01-25 11:21:57 +00:00
|
|
|
{
|
|
|
|
private_tls_crypto_t *this;
|
2010-09-03 16:11:03 +00:00
|
|
|
enumerator_t *enumerator;
|
|
|
|
credential_type_t type;
|
|
|
|
int subtype;
|
2020-05-21 07:37:38 +00:00
|
|
|
int hash_algorithm;
|
|
|
|
const char *plugin;
|
2010-01-25 11:21:57 +00:00
|
|
|
|
|
|
|
INIT(this,
|
|
|
|
.public = {
|
|
|
|
.get_cipher_suites = _get_cipher_suites,
|
2010-02-04 10:17:48 +00:00
|
|
|
.select_cipher_suite = _select_cipher_suite,
|
2010-09-02 17:24:56 +00:00
|
|
|
.get_dh_group = _get_dh_group,
|
2010-09-02 17:15:16 +00:00
|
|
|
.get_signature_algorithms = _get_signature_algorithms,
|
2010-09-03 15:05:39 +00:00
|
|
|
.create_ec_enumerator = _create_ec_enumerator,
|
2010-02-05 13:39:19 +00:00
|
|
|
.set_protection = _set_protection,
|
2010-02-05 13:25:38 +00:00
|
|
|
.append_handshake = _append_handshake,
|
2010-09-02 17:15:16 +00:00
|
|
|
.sign = _sign,
|
|
|
|
.verify = _verify,
|
2010-02-05 13:25:38 +00:00
|
|
|
.sign_handshake = _sign_handshake,
|
2010-02-09 17:19:25 +00:00
|
|
|
.verify_handshake = _verify_handshake,
|
2010-02-05 13:25:38 +00:00
|
|
|
.calculate_finished = _calculate_finished,
|
2020-05-21 07:37:38 +00:00
|
|
|
.calculate_finished_tls13 = _calculate_finished_tls13,
|
2010-02-05 13:25:38 +00:00
|
|
|
.derive_secrets = _derive_secrets,
|
2020-05-21 07:37:38 +00:00
|
|
|
.derive_handshake_secret = _derive_handshake_secret,
|
|
|
|
.derive_app_secret = _derive_app_secret,
|
2011-12-31 00:41:56 +00:00
|
|
|
.resume_session = _resume_session,
|
|
|
|
.get_session = _get_session,
|
2010-02-04 17:18:10 +00:00
|
|
|
.change_cipher = _change_cipher,
|
2010-02-05 11:28:48 +00:00
|
|
|
.get_eap_msk = _get_eap_msk,
|
2010-01-25 11:21:57 +00:00
|
|
|
.destroy = _destroy,
|
|
|
|
},
|
2010-02-04 10:17:48 +00:00
|
|
|
.tls = tls,
|
2011-12-31 00:41:56 +00:00
|
|
|
.cache = cache,
|
2010-01-25 11:21:57 +00:00
|
|
|
);
|
|
|
|
|
2010-09-03 16:11:03 +00:00
|
|
|
enumerator = lib->creds->create_builder_enumerator(lib->creds);
|
|
|
|
while (enumerator->enumerate(enumerator, &type, &subtype))
|
|
|
|
{
|
|
|
|
if (type == CRED_PUBLIC_KEY)
|
|
|
|
{
|
|
|
|
switch (subtype)
|
|
|
|
{
|
|
|
|
case KEY_RSA:
|
|
|
|
this->rsa = TRUE;
|
|
|
|
break;
|
|
|
|
case KEY_ECDSA:
|
|
|
|
this->ecdsa = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
|
2020-05-21 07:37:38 +00:00
|
|
|
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
|
|
|
|
while (enumerator->enumerate(enumerator, &hash_algorithm, &plugin))
|
|
|
|
{
|
|
|
|
switch (hash_algorithm)
|
|
|
|
{
|
|
|
|
case TLS_HASH_MD5:
|
|
|
|
if (tls->get_version_max(tls) < TLS_1_3)
|
|
|
|
{
|
|
|
|
this->md5 = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->md5 = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TLS_HASH_SHA1:
|
|
|
|
this->sha1 = TRUE;
|
|
|
|
break;
|
|
|
|
case TLS_HASH_SHA224:
|
|
|
|
if (tls->get_version_max(tls) < TLS_1_3)
|
|
|
|
{
|
|
|
|
this->sha224 = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->sha224 = FALSE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TLS_HASH_SHA384:
|
|
|
|
this->sha384 = TRUE;
|
|
|
|
break;
|
|
|
|
case TLS_HASH_SHA256:
|
|
|
|
this->sha256 = TRUE;
|
|
|
|
break;
|
|
|
|
case TLS_HASH_SHA512:
|
|
|
|
this->sha512 = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
|
2010-08-20 13:02:25 +00:00
|
|
|
switch (tls->get_purpose(tls))
|
|
|
|
{
|
|
|
|
case TLS_PURPOSE_EAP_TLS:
|
|
|
|
/* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
|
|
|
|
this->msk_label = "client EAP encryption";
|
|
|
|
build_cipher_suite_list(this, FALSE);
|
2012-09-28 16:55:40 +00:00
|
|
|
break;
|
2012-08-30 09:13:02 +00:00
|
|
|
case TLS_PURPOSE_EAP_PEAP:
|
|
|
|
this->msk_label = "client EAP encryption";
|
|
|
|
build_cipher_suite_list(this, TRUE);
|
2010-08-20 13:02:25 +00:00
|
|
|
break;
|
|
|
|
case TLS_PURPOSE_EAP_TTLS:
|
|
|
|
/* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
|
|
|
|
this->msk_label = "ttls keying material";
|
|
|
|
build_cipher_suite_list(this, TRUE);
|
|
|
|
break;
|
2010-08-24 06:42:10 +00:00
|
|
|
case TLS_PURPOSE_GENERIC:
|
|
|
|
build_cipher_suite_list(this, TRUE);
|
|
|
|
break;
|
2014-03-25 08:49:04 +00:00
|
|
|
case TLS_PURPOSE_GENERIC_NULLOK:
|
|
|
|
build_cipher_suite_list(this, FALSE);
|
|
|
|
break;
|
2010-09-08 10:11:44 +00:00
|
|
|
default:
|
|
|
|
break;
|
2010-08-20 13:02:25 +00:00
|
|
|
}
|
2010-01-25 11:21:57 +00:00
|
|
|
return &this->public;
|
|
|
|
}
|
2014-03-24 13:28:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* See header.
|
|
|
|
*/
|
|
|
|
int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out)
|
|
|
|
{
|
|
|
|
suite_algs_t suites[countof(suite_algs)];
|
|
|
|
int count = countof(suite_algs), i;
|
|
|
|
|
|
|
|
/* initialize copy of suite list */
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
suites[i] = suite_algs[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
filter_unsupported_suites(suites, &count);
|
|
|
|
|
|
|
|
if (!null)
|
|
|
|
{
|
|
|
|
filter_null_suites(suites, &count);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (out)
|
|
|
|
{
|
|
|
|
*out = calloc(count, sizeof(tls_cipher_suite_t));
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
(*out)[i] = suites[i].suite;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|