Annotation of embedaddon/strongswan/src/libtls/tls_crypto.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2010-2014 Martin Willi
! 3: * Copyright (C) 2010-2014 revosec AG
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "tls_crypto.h"
! 17:
! 18: #include <utils/debug.h>
! 19: #include <plugins/plugin_feature.h>
! 20:
! 21: ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL,
! 22: TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
! 23: "TLS_NULL_WITH_NULL_NULL",
! 24: "TLS_RSA_WITH_NULL_MD5",
! 25: "TLS_RSA_WITH_NULL_SHA",
! 26: "TLS_RSA_EXPORT_WITH_RC4_40_MD5",
! 27: "TLS_RSA_WITH_RC4_128_MD5",
! 28: "TLS_RSA_WITH_RC4_128_SHA",
! 29: "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5",
! 30: "TLS_RSA_WITH_IDEA_CBC_SHA",
! 31: "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA",
! 32: "TLS_RSA_WITH_DES_CBC_SHA",
! 33: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
! 34: "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA",
! 35: "TLS_DH_DSS_WITH_DES_CBC_SHA",
! 36: "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA",
! 37: "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA",
! 38: "TLS_DH_RSA_WITH_DES_CBC_SHA",
! 39: "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA",
! 40: "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
! 41: "TLS_DHE_DSS_WITH_DES_CBC_SHA",
! 42: "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
! 43: "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
! 44: "TLS_DHE_RSA_WITH_DES_CBC_SHA",
! 45: "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
! 46: "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5",
! 47: "TLS_DH_anon_WITH_RC4_128_MD5",
! 48: "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
! 49: "TLS_DH_anon_WITH_DES_CBC_SHA",
! 50: "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA");
! 51: ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA,
! 52: TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
! 53: TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
! 54: "TLS_KRB5_WITH_DES_CBC_SHA",
! 55: "TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
! 56: "TLS_KRB5_WITH_RC4_128_SHA",
! 57: "TLS_KRB5_WITH_IDEA_CBC_SHA",
! 58: "TLS_KRB5_WITH_DES_CBC_MD5",
! 59: "TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
! 60: "TLS_KRB5_WITH_RC4_128_MD5",
! 61: "TLS_KRB5_WITH_IDEA_CBC_MD5",
! 62: "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
! 63: "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA",
! 64: "TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
! 65: "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
! 66: "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5",
! 67: "TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
! 68: "TLS_PSK_WITH_NULL_SHA",
! 69: "TLS_DHE_PSK_WITH_NULL_SHA",
! 70: "TLS_RSA_PSK_WITH_NULL_SHA",
! 71: "TLS_RSA_WITH_AES_128_CBC_SHA",
! 72: "TLS_DH_DSS_WITH_AES_128_CBC_SHA",
! 73: "TLS_DH_RSA_WITH_AES_128_CBC_SHA",
! 74: "TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
! 75: "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
! 76: "TLS_DH_anon_WITH_AES_128_CBC_SHA",
! 77: "TLS_RSA_WITH_AES_256_CBC_SHA",
! 78: "TLS_DH_DSS_WITH_AES_256_CBC_SHA",
! 79: "TLS_DH_RSA_WITH_AES_256_CBC_SHA",
! 80: "TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
! 81: "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
! 82: "TLS_DH_anon_WITH_AES_256_CBC_SHA",
! 83: "TLS_RSA_WITH_NULL_SHA256",
! 84: "TLS_RSA_WITH_AES_128_CBC_SHA256",
! 85: "TLS_RSA_WITH_AES_256_CBC_SHA256",
! 86: "TLS_DH_DSS_WITH_AES_128_CBC_SHA256",
! 87: "TLS_DH_RSA_WITH_AES_128_CBC_SHA256",
! 88: "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
! 89: "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA",
! 90: "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA",
! 91: "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA",
! 92: "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA",
! 93: "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA",
! 94: "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA");
! 95: ENUM_NEXT(tls_cipher_suite_names, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
! 96: TLS_DH_anon_WITH_AES_256_CBC_SHA256,
! 97: TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
! 98: "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
! 99: "TLS_DH_DSS_WITH_AES_256_CBC_SHA256",
! 100: "TLS_DH_RSA_WITH_AES_256_CBC_SHA256",
! 101: "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
! 102: "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
! 103: "TLS_DH_anon_WITH_AES_128_CBC_SHA256",
! 104: "TLS_DH_anon_WITH_AES_256_CBC_SHA256");
! 105: ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
! 106: TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
! 107: TLS_DH_anon_WITH_AES_256_CBC_SHA256,
! 108: "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA",
! 109: "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA",
! 110: "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA",
! 111: "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA",
! 112: "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA",
! 113: "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA",
! 114: "TLS_PSK_WITH_RC4_128_SHA",
! 115: "TLS_PSK_WITH_3DES_EDE_CBC_SHA",
! 116: "TLS_PSK_WITH_AES_128_CBC_SHA",
! 117: "TLS_PSK_WITH_AES_256_CBC_SHA",
! 118: "TLS_DHE_PSK_WITH_RC4_128_SHA",
! 119: "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA",
! 120: "TLS_DHE_PSK_WITH_AES_128_CBC_SHA",
! 121: "TLS_DHE_PSK_WITH_AES_256_CBC_SHA",
! 122: "TLS_RSA_PSK_WITH_RC4_128_SHA",
! 123: "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA",
! 124: "TLS_RSA_PSK_WITH_AES_128_CBC_SHA",
! 125: "TLS_RSA_PSK_WITH_AES_256_CBC_SHA",
! 126: "TLS_RSA_WITH_SEED_CBC_SHA",
! 127: "TLS_DH_DSS_WITH_SEED_CBC_SHA",
! 128: "TLS_DH_RSA_WITH_SEED_CBC_SHA",
! 129: "TLS_DHE_DSS_WITH_SEED_CBC_SHA",
! 130: "TLS_DHE_RSA_WITH_SEED_CBC_SHA",
! 131: "TLS_DH_anon_WITH_SEED_CBC_SHA",
! 132: "TLS_RSA_WITH_AES_128_GCM_SHA256",
! 133: "TLS_RSA_WITH_AES_256_GCM_SHA384",
! 134: "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
! 135: "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
! 136: "TLS_DH_RSA_WITH_AES_128_GCM_SHA256",
! 137: "TLS_DH_RSA_WITH_AES_256_GCM_SHA384",
! 138: "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256",
! 139: "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384",
! 140: "TLS_DH_DSS_WITH_AES_128_GCM_SHA256",
! 141: "TLS_DH_DSS_WITH_AES_256_GCM_SHA384",
! 142: "TLS_DH_anon_WITH_AES_128_GCM_SHA256",
! 143: "TLS_DH_anon_WITH_AES_256_GCM_SHA384",
! 144: "TLS_PSK_WITH_AES_128_GCM_SHA256",
! 145: "TLS_PSK_WITH_AES_256_GCM_SHA384",
! 146: "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256",
! 147: "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384",
! 148: "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256",
! 149: "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384",
! 150: "TLS_PSK_WITH_AES_128_CBC_SHA256",
! 151: "TLS_PSK_WITH_AES_256_CBC_SHA384",
! 152: "TLS_PSK_WITH_NULL_SHA256",
! 153: "TLS_PSK_WITH_NULL_SHA384",
! 154: "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256",
! 155: "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384",
! 156: "TLS_DHE_PSK_WITH_NULL_SHA256",
! 157: "TLS_DHE_PSK_WITH_NULL_SHA384",
! 158: "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256",
! 159: "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384",
! 160: "TLS_RSA_PSK_WITH_NULL_SHA256",
! 161: "TLS_RSA_PSK_WITH_NULL_SHA384",
! 162: "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256",
! 163: "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256",
! 164: "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256",
! 165: "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256",
! 166: "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256",
! 167: "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256",
! 168: "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256",
! 169: "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256",
! 170: "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256",
! 171: "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256",
! 172: "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256",
! 173: "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256");
! 174: ENUM_NEXT(tls_cipher_suite_names, TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
! 175: TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
! 176: TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
! 177: "TLS_EMPTY_RENEGOTIATION_INFO_SCSV");
! 178: ENUM_NEXT(tls_cipher_suite_names, TLS_ECDH_ECDSA_WITH_NULL_SHA,
! 179: TLS_ECDHE_PSK_WITH_NULL_SHA384,
! 180: TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
! 181: "TLS_ECDH_ECDSA_WITH_NULL_SHA",
! 182: "TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
! 183: "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
! 184: "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
! 185: "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
! 186: "TLS_ECDHE_ECDSA_WITH_NULL_SHA",
! 187: "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
! 188: "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
! 189: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
! 190: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
! 191: "TLS_ECDH_RSA_WITH_NULL_SHA",
! 192: "TLS_ECDH_RSA_WITH_RC4_128_SHA",
! 193: "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
! 194: "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
! 195: "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
! 196: "TLS_ECDHE_RSA_WITH_NULL_SHA",
! 197: "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
! 198: "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
! 199: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
! 200: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
! 201: "TLS_ECDH_anon_WITH_NULL_SHA",
! 202: "TLS_ECDH_anon_WITH_RC4_128_SHA",
! 203: "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
! 204: "TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
! 205: "TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
! 206: "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA",
! 207: "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA",
! 208: "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA",
! 209: "TLS_SRP_SHA_WITH_AES_128_CBC_SHA",
! 210: "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA",
! 211: "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA",
! 212: "TLS_SRP_SHA_WITH_AES_256_CBC_SHA",
! 213: "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA",
! 214: "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA",
! 215: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
! 216: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
! 217: "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
! 218: "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
! 219: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
! 220: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
! 221: "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
! 222: "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
! 223: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
! 224: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
! 225: "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
! 226: "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
! 227: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
! 228: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
! 229: "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256",
! 230: "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384",
! 231: "TLS_ECDHE_PSK_WITH_RC4_128_SHA",
! 232: "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA",
! 233: "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
! 234: "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
! 235: "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256",
! 236: "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384",
! 237: "TLS_ECDHE_PSK_WITH_NULL_SHA",
! 238: "TLS_ECDHE_PSK_WITH_NULL_SHA256",
! 239: "TLS_ECDHE_PSK_WITH_NULL_SHA384");
! 240: ENUM_END(tls_cipher_suite_names, TLS_ECDHE_PSK_WITH_NULL_SHA384);
! 241:
! 242: ENUM(tls_hash_algorithm_names, TLS_HASH_NONE, TLS_HASH_SHA512,
! 243: "NONE",
! 244: "MD5",
! 245: "SHA1",
! 246: "SHA224",
! 247: "SHA256",
! 248: "SHA384",
! 249: "SHA512",
! 250: );
! 251:
! 252: ENUM(tls_signature_algorithm_names, TLS_SIG_RSA, TLS_SIG_ECDSA,
! 253: "RSA",
! 254: "DSA",
! 255: "ECDSA",
! 256: );
! 257:
! 258: ENUM_BEGIN(tls_client_certificate_type_names,
! 259: TLS_RSA_SIGN, TLS_DSS_EPHEMERAL_DH,
! 260: "RSA_SIGN",
! 261: "DSA_SIGN",
! 262: "RSA_FIXED_DH",
! 263: "DSS_FIXED_DH",
! 264: "RSA_EPHEMERAL_DH",
! 265: "DSS_EPHEMERAL_DH");
! 266: ENUM_NEXT(tls_client_certificate_type_names,
! 267: TLS_FORTEZZA_DMS, TLS_FORTEZZA_DMS, TLS_DSS_EPHEMERAL_DH,
! 268: "FORTEZZA_DMS");
! 269: ENUM_NEXT(tls_client_certificate_type_names,
! 270: TLS_ECDSA_SIGN, TLS_ECDSA_FIXED_ECDH, TLS_FORTEZZA_DMS,
! 271: "ECDSA_SIGN",
! 272: "RSA_FIXED_ECDH",
! 273: "ECDSA_FIXED_ECDH");
! 274: ENUM_END(tls_client_certificate_type_names, TLS_ECDSA_FIXED_ECDH);
! 275:
! 276: ENUM(tls_ecc_curve_type_names, TLS_ECC_EXPLICIT_PRIME, TLS_ECC_NAMED_CURVE,
! 277: "EXPLICIT_PRIME",
! 278: "EXPLICIT_CHAR2",
! 279: "NAMED_CURVE",
! 280: );
! 281:
! 282: ENUM(tls_named_curve_names, TLS_SECT163K1, TLS_SECP521R1,
! 283: "SECT163K1",
! 284: "SECT163R1",
! 285: "SECT163R2",
! 286: "SECT193R1",
! 287: "SECT193R2",
! 288: "SECT233K1",
! 289: "SECT233R1",
! 290: "SECT239K1",
! 291: "SECT283K1",
! 292: "SECT283R1",
! 293: "SECT409K1",
! 294: "SECT409R1",
! 295: "SECT571K1",
! 296: "SECT571R1",
! 297: "SECP160K1",
! 298: "SECP160R1",
! 299: "SECP160R2",
! 300: "SECP192K1",
! 301: "SECP192R1",
! 302: "SECP224K1",
! 303: "SECP224R1",
! 304: "SECP256K1",
! 305: "SECP256R1",
! 306: "SECP384R1",
! 307: "SECP521R1",
! 308: );
! 309:
! 310: ENUM(tls_ansi_point_format_names, TLS_ANSI_COMPRESSED, TLS_ANSI_HYBRID_Y,
! 311: "compressed",
! 312: "compressed y",
! 313: "uncompressed",
! 314: "uncompressed y",
! 315: "hybrid",
! 316: "hybrid y",
! 317: );
! 318:
! 319: ENUM(tls_ec_point_format_names,
! 320: TLS_EC_POINT_UNCOMPRESSED, TLS_EC_POINT_ANSIX962_COMPRESSED_CHAR2,
! 321: "uncompressed",
! 322: "ansiX962 compressed prime",
! 323: "ansiX962 compressed char2",
! 324: );
! 325:
! 326: typedef struct private_tls_crypto_t private_tls_crypto_t;
! 327:
! 328: /**
! 329: * Private data of an tls_crypto_t object.
! 330: */
! 331: struct private_tls_crypto_t {
! 332:
! 333: /**
! 334: * Public tls_crypto_t interface.
! 335: */
! 336: tls_crypto_t public;
! 337:
! 338: /**
! 339: * Protection layer
! 340: */
! 341: tls_protection_t *protection;
! 342:
! 343: /**
! 344: * List of supported/acceptable cipher suites
! 345: */
! 346: tls_cipher_suite_t *suites;
! 347:
! 348: /**
! 349: * Number of supported suites
! 350: */
! 351: int suite_count;
! 352:
! 353: /**
! 354: * Selected cipher suite
! 355: */
! 356: tls_cipher_suite_t suite;
! 357:
! 358: /**
! 359: * RSA supported?
! 360: */
! 361: bool rsa;
! 362:
! 363: /**
! 364: * ECDSA supported?
! 365: */
! 366: bool ecdsa;
! 367:
! 368: /**
! 369: * TLS context
! 370: */
! 371: tls_t *tls;
! 372:
! 373: /**
! 374: * TLS session cache
! 375: */
! 376: tls_cache_t *cache;
! 377:
! 378: /**
! 379: * All handshake data concatenated
! 380: */
! 381: chunk_t handshake;
! 382:
! 383: /**
! 384: * Connection state TLS PRF
! 385: */
! 386: tls_prf_t *prf;
! 387:
! 388: /**
! 389: * AEAD transform for inbound traffic
! 390: */
! 391: tls_aead_t *aead_in;
! 392:
! 393: /**
! 394: * AEAD transform for outbound traffic
! 395: */
! 396: tls_aead_t *aead_out;
! 397:
! 398: /**
! 399: * EAP-[T]TLS MSK
! 400: */
! 401: chunk_t msk;
! 402:
! 403: /**
! 404: * ASCII string constant used as seed for EAP-[T]TLS MSK PRF
! 405: */
! 406: char *msk_label;
! 407: };
! 408:
! 409: typedef struct {
! 410: tls_cipher_suite_t suite;
! 411: key_type_t key;
! 412: diffie_hellman_group_t dh;
! 413: hash_algorithm_t hash;
! 414: pseudo_random_function_t prf;
! 415: integrity_algorithm_t mac;
! 416: encryption_algorithm_t encr;
! 417: size_t encr_size;
! 418: } suite_algs_t;
! 419:
! 420: /**
! 421: * Mapping suites to a set of algorithms
! 422: */
! 423: static suite_algs_t suite_algs[] = {
! 424: { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
! 425: KEY_ECDSA, ECP_256_BIT,
! 426: HASH_SHA256, PRF_HMAC_SHA2_256,
! 427: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
! 428: },
! 429: { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
! 430: KEY_ECDSA, ECP_256_BIT,
! 431: HASH_SHA256, PRF_HMAC_SHA2_256,
! 432: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
! 433: },
! 434: { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
! 435: KEY_ECDSA, ECP_384_BIT,
! 436: HASH_SHA256, PRF_HMAC_SHA2_256,
! 437: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
! 438: },
! 439: { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
! 440: KEY_ECDSA, ECP_384_BIT,
! 441: HASH_SHA384, PRF_HMAC_SHA2_384,
! 442: AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
! 443: },
! 444: { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
! 445: KEY_ECDSA, ECP_256_BIT,
! 446: HASH_SHA256, PRF_HMAC_SHA2_256,
! 447: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
! 448: },
! 449: { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
! 450: KEY_ECDSA, ECP_384_BIT,
! 451: HASH_SHA384, PRF_HMAC_SHA2_384,
! 452: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
! 453: },
! 454: { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
! 455: KEY_RSA, ECP_256_BIT,
! 456: HASH_SHA256, PRF_HMAC_SHA2_256,
! 457: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
! 458: },
! 459: { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
! 460: KEY_RSA, ECP_256_BIT,
! 461: HASH_SHA256, PRF_HMAC_SHA2_256,
! 462: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
! 463: },
! 464: { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
! 465: KEY_RSA, ECP_384_BIT,
! 466: HASH_SHA256, PRF_HMAC_SHA2_256,
! 467: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
! 468: },
! 469: { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
! 470: KEY_RSA, ECP_384_BIT,
! 471: HASH_SHA384, PRF_HMAC_SHA2_384,
! 472: AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32
! 473: },
! 474: { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
! 475: KEY_RSA, ECP_256_BIT,
! 476: HASH_SHA256, PRF_HMAC_SHA2_256,
! 477: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
! 478: },
! 479: { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
! 480: KEY_RSA, ECP_384_BIT,
! 481: HASH_SHA384, PRF_HMAC_SHA2_384,
! 482: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
! 483: },
! 484: { TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
! 485: KEY_RSA, MODP_2048_BIT,
! 486: HASH_SHA256,PRF_HMAC_SHA2_256,
! 487: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
! 488: },
! 489: { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
! 490: KEY_RSA, MODP_3072_BIT,
! 491: HASH_SHA256, PRF_HMAC_SHA2_256,
! 492: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
! 493: },
! 494: { TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
! 495: KEY_RSA, MODP_3072_BIT,
! 496: HASH_SHA256, PRF_HMAC_SHA2_256,
! 497: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
! 498: },
! 499: { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
! 500: KEY_RSA, MODP_4096_BIT,
! 501: HASH_SHA256, PRF_HMAC_SHA2_256,
! 502: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
! 503: },
! 504: { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
! 505: KEY_RSA, MODP_3072_BIT,
! 506: HASH_SHA256, PRF_HMAC_SHA2_256,
! 507: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
! 508: },
! 509: { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
! 510: KEY_RSA, MODP_4096_BIT,
! 511: HASH_SHA384, PRF_HMAC_SHA2_384,
! 512: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
! 513: },
! 514: { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
! 515: KEY_RSA, MODP_2048_BIT,
! 516: HASH_SHA256, PRF_HMAC_SHA2_256,
! 517: AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
! 518: },
! 519: { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
! 520: KEY_RSA, MODP_3072_BIT,
! 521: HASH_SHA256, PRF_HMAC_SHA2_256,
! 522: AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16
! 523: },
! 524: { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
! 525: KEY_RSA, MODP_3072_BIT,
! 526: HASH_SHA256, PRF_HMAC_SHA2_256,
! 527: AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
! 528: },
! 529: { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
! 530: KEY_RSA, MODP_4096_BIT,
! 531: HASH_SHA256, PRF_HMAC_SHA2_256,
! 532: AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32
! 533: },
! 534: { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
! 535: KEY_RSA, MODP_2048_BIT,
! 536: HASH_SHA256, PRF_HMAC_SHA2_256,
! 537: AUTH_HMAC_SHA1_160, ENCR_3DES, 0
! 538: },
! 539: { TLS_RSA_WITH_AES_128_CBC_SHA,
! 540: KEY_RSA, MODP_NONE,
! 541: HASH_SHA256, PRF_HMAC_SHA2_256,
! 542: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
! 543: },
! 544: { TLS_RSA_WITH_AES_128_CBC_SHA256,
! 545: KEY_RSA, MODP_NONE,
! 546: HASH_SHA256, PRF_HMAC_SHA2_256,
! 547: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16
! 548: },
! 549: { TLS_RSA_WITH_AES_256_CBC_SHA,
! 550: KEY_RSA, MODP_NONE,
! 551: HASH_SHA256, PRF_HMAC_SHA2_256,
! 552: AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
! 553: },
! 554: { TLS_RSA_WITH_AES_256_CBC_SHA256,
! 555: KEY_RSA, MODP_NONE,
! 556: HASH_SHA256, PRF_HMAC_SHA2_256,
! 557: AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32
! 558: },
! 559: { TLS_RSA_WITH_AES_128_GCM_SHA256,
! 560: KEY_RSA, MODP_NONE,
! 561: HASH_SHA256, PRF_HMAC_SHA2_256,
! 562: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16
! 563: },
! 564: { TLS_RSA_WITH_AES_256_GCM_SHA384,
! 565: KEY_RSA, MODP_NONE,
! 566: HASH_SHA384, PRF_HMAC_SHA2_384,
! 567: AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32
! 568: },
! 569: { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
! 570: KEY_RSA, MODP_NONE,
! 571: HASH_SHA256, PRF_HMAC_SHA2_256,
! 572: AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
! 573: },
! 574: { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
! 575: KEY_RSA, MODP_NONE,
! 576: HASH_SHA256, PRF_HMAC_SHA2_256,
! 577: AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16
! 578: },
! 579: { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
! 580: KEY_RSA, MODP_NONE,
! 581: HASH_SHA256, PRF_HMAC_SHA2_256,
! 582: AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
! 583: },
! 584: { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
! 585: KEY_RSA, MODP_NONE,
! 586: HASH_SHA256, PRF_HMAC_SHA2_256,
! 587: AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32
! 588: },
! 589: { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
! 590: KEY_ECDSA, ECP_256_BIT,
! 591: HASH_SHA256, PRF_HMAC_SHA2_256,
! 592: AUTH_HMAC_SHA1_160, ENCR_3DES, 0
! 593: },
! 594: { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
! 595: KEY_RSA, ECP_256_BIT,
! 596: HASH_SHA256, PRF_HMAC_SHA2_256,
! 597: AUTH_HMAC_SHA1_160, ENCR_3DES, 0
! 598: },
! 599: { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
! 600: KEY_RSA, MODP_NONE,
! 601: HASH_SHA256, PRF_HMAC_SHA2_256,
! 602: AUTH_HMAC_SHA1_160, ENCR_3DES, 0
! 603: },
! 604: { TLS_ECDHE_ECDSA_WITH_NULL_SHA,
! 605: KEY_ECDSA, ECP_256_BIT,
! 606: HASH_SHA256, PRF_HMAC_SHA2_256,
! 607: AUTH_HMAC_SHA1_160, ENCR_NULL, 0
! 608: },
! 609: { TLS_ECDHE_RSA_WITH_NULL_SHA,
! 610: KEY_ECDSA, ECP_256_BIT,
! 611: HASH_SHA256, PRF_HMAC_SHA2_256,
! 612: AUTH_HMAC_SHA1_160, ENCR_NULL, 0
! 613: },
! 614: { TLS_RSA_WITH_NULL_SHA,
! 615: KEY_RSA, MODP_NONE,
! 616: HASH_SHA256, PRF_HMAC_SHA2_256,
! 617: AUTH_HMAC_SHA1_160, ENCR_NULL, 0
! 618: },
! 619: { TLS_RSA_WITH_NULL_SHA256,
! 620: KEY_RSA, MODP_NONE,
! 621: HASH_SHA256, PRF_HMAC_SHA2_256,
! 622: AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0
! 623: },
! 624: { TLS_RSA_WITH_NULL_MD5,
! 625: KEY_RSA, MODP_NONE,
! 626: HASH_SHA256, PRF_HMAC_SHA2_256,
! 627: AUTH_HMAC_MD5_128, ENCR_NULL, 0
! 628: },
! 629: };
! 630:
! 631: /**
! 632: * Look up algorithms by a suite
! 633: */
! 634: static suite_algs_t *find_suite(tls_cipher_suite_t suite)
! 635: {
! 636: int i;
! 637:
! 638: for (i = 0; i < countof(suite_algs); i++)
! 639: {
! 640: if (suite_algs[i].suite == suite)
! 641: {
! 642: return &suite_algs[i];
! 643: }
! 644: }
! 645: return NULL;
! 646: }
! 647:
! 648: /**
! 649: * Filter a suite list using a transform enumerator
! 650: */
! 651: static void filter_suite(suite_algs_t suites[], int *count, int offset,
! 652: enumerator_t*(*create_enumerator)(crypto_factory_t*))
! 653: {
! 654: const char *plugin_name;
! 655: suite_algs_t current;
! 656: int *current_alg, i, remaining = 0;
! 657: enumerator_t *enumerator;
! 658:
! 659: memset(¤t, 0, sizeof(current));
! 660: current_alg = (int*)((char*)¤t + offset);
! 661:
! 662: for (i = 0; i < *count; i++)
! 663: {
! 664: if (create_enumerator == lib->crypto->create_crypter_enumerator &&
! 665: encryption_algorithm_is_aead(suites[i].encr))
! 666: { /* filtering crypters, but current suite uses an AEAD, apply */
! 667: suites[remaining] = suites[i];
! 668: remaining++;
! 669: continue;
! 670: }
! 671: if (create_enumerator == lib->crypto->create_aead_enumerator &&
! 672: !encryption_algorithm_is_aead(suites[i].encr))
! 673: { /* filtering AEADs, but current suite doesn't use one, apply */
! 674: suites[remaining] = suites[i];
! 675: remaining++;
! 676: continue;
! 677: }
! 678: enumerator = create_enumerator(lib->crypto);
! 679: while (enumerator->enumerate(enumerator, current_alg, &plugin_name))
! 680: {
! 681: if (current.encr && current.encr != suites[i].encr)
! 682: {
! 683: if (suites[i].encr != ENCR_NULL)
! 684: { /* skip, ENCR does not match nor is NULL */
! 685: continue;
! 686: }
! 687: }
! 688: if (current.mac && current.mac != suites[i].mac)
! 689: {
! 690: if (suites[i].mac != AUTH_UNDEFINED)
! 691: { /* skip, MAC does not match nor is it undefined */
! 692: continue;
! 693: }
! 694: }
! 695: if (current.prf && current.prf != suites[i].prf)
! 696: { /* skip, PRF does not match */
! 697: continue;
! 698: }
! 699: if (current.hash && current.hash != suites[i].hash)
! 700: { /* skip, hash does not match */
! 701: continue;
! 702: }
! 703: if (current.dh && current.dh != suites[i].dh)
! 704: {
! 705: if (suites[i].dh != MODP_NONE)
! 706: { /* skip DH group, does not match nor NONE */
! 707: continue;
! 708: }
! 709: }
! 710: /* suite supported, apply */
! 711: suites[remaining] = suites[i];
! 712: remaining++;
! 713: break;
! 714: }
! 715: enumerator->destroy(enumerator);
! 716: }
! 717: *count = remaining;
! 718: }
! 719:
! 720: /**
! 721: * Purge NULL encryption cipher suites from list
! 722: */
! 723: static void filter_null_suites(suite_algs_t suites[], int *count)
! 724: {
! 725: int i, remaining = 0;
! 726:
! 727: for (i = 0; i < *count; i++)
! 728: {
! 729: if (suites[i].encr != ENCR_NULL)
! 730: {
! 731: suites[remaining] = suites[i];
! 732: remaining++;
! 733: }
! 734: }
! 735: *count = remaining;
! 736: }
! 737:
! 738: /**
! 739: * Purge suites using a given key type
! 740: */
! 741: static void filter_key_suites(private_tls_crypto_t *this,
! 742: suite_algs_t suites[], int *count, key_type_t key)
! 743: {
! 744: int i, remaining = 0;
! 745:
! 746: DBG2(DBG_TLS, "disabling %N suites, no backend found", key_type_names, key);
! 747: for (i = 0; i < *count; i++)
! 748: {
! 749: if (suites[i].key != key)
! 750: {
! 751: suites[remaining] = suites[i];
! 752: remaining++;
! 753: }
! 754: }
! 755: *count = remaining;
! 756: }
! 757:
! 758: /**
! 759: * Filter suites by key exchange user config
! 760: */
! 761: static void filter_key_exchange_config_suites(private_tls_crypto_t *this,
! 762: suite_algs_t suites[], int *count)
! 763: {
! 764: enumerator_t *enumerator;
! 765: int i, remaining = 0;
! 766: char *token, *config;
! 767:
! 768: config = lib->settings->get_str(lib->settings, "%s.tls.key_exchange", NULL,
! 769: lib->ns);
! 770: if (config)
! 771: {
! 772: for (i = 0; i < *count; i++)
! 773: {
! 774: enumerator = enumerator_create_token(config, ",", " ");
! 775: while (enumerator->enumerate(enumerator, &token))
! 776: {
! 777: if (strcaseeq(token, "ecdhe-ecdsa") &&
! 778: diffie_hellman_group_is_ec(suites[i].dh) &&
! 779: suites[i].key == KEY_ECDSA)
! 780: {
! 781: suites[remaining++] = suites[i];
! 782: break;
! 783: }
! 784: if (strcaseeq(token, "ecdhe-rsa") &&
! 785: diffie_hellman_group_is_ec(suites[i].dh) &&
! 786: suites[i].key == KEY_RSA)
! 787: {
! 788: suites[remaining++] = suites[i];
! 789: break;
! 790: }
! 791: if (strcaseeq(token, "dhe-rsa") &&
! 792: !diffie_hellman_group_is_ec(suites[i].dh) &&
! 793: suites[i].dh != MODP_NONE &&
! 794: suites[i].key == KEY_RSA)
! 795: {
! 796: suites[remaining++] = suites[i];
! 797: break;
! 798: }
! 799: if (strcaseeq(token, "rsa") &&
! 800: suites[i].dh == MODP_NONE &&
! 801: suites[i].key == KEY_RSA)
! 802: {
! 803: suites[remaining++] = suites[i];
! 804: break;
! 805: }
! 806: }
! 807: enumerator->destroy(enumerator);
! 808: }
! 809: *count = remaining;
! 810: }
! 811: }
! 812:
! 813: /**
! 814: * Filter suites by cipher user config
! 815: */
! 816: static void filter_cipher_config_suites(private_tls_crypto_t *this,
! 817: suite_algs_t suites[], int *count)
! 818: {
! 819: enumerator_t *enumerator;
! 820: int i, remaining = 0;
! 821: char *token, *config;
! 822:
! 823: config = lib->settings->get_str(lib->settings, "%s.tls.cipher", NULL,
! 824: lib->ns);
! 825: if (config)
! 826: {
! 827: for (i = 0; i < *count; i++)
! 828: {
! 829: enumerator = enumerator_create_token(config, ",", " ");
! 830: while (enumerator->enumerate(enumerator, &token))
! 831: {
! 832: if (strcaseeq(token, "aes128") &&
! 833: suites[i].encr == ENCR_AES_CBC &&
! 834: suites[i].encr_size == 16)
! 835: {
! 836: suites[remaining++] = suites[i];
! 837: break;
! 838: }
! 839: if (strcaseeq(token, "aes256") &&
! 840: suites[i].encr == ENCR_AES_CBC &&
! 841: suites[i].encr_size == 32)
! 842: {
! 843: suites[remaining++] = suites[i];
! 844: break;
! 845: }
! 846: if (strcaseeq(token, "aes128gcm") &&
! 847: suites[i].encr == ENCR_AES_GCM_ICV16 &&
! 848: suites[i].encr_size == 16)
! 849: {
! 850: suites[remaining++] = suites[i];
! 851: break;
! 852: }
! 853: if (strcaseeq(token, "aes256gcm") &&
! 854: suites[i].encr == ENCR_AES_GCM_ICV16 &&
! 855: suites[i].encr_size == 32)
! 856: {
! 857: suites[remaining++] = suites[i];
! 858: break;
! 859: }
! 860: if (strcaseeq(token, "camellia128") &&
! 861: suites[i].encr == ENCR_CAMELLIA_CBC &&
! 862: suites[i].encr_size == 16)
! 863: {
! 864: suites[remaining++] = suites[i];
! 865: break;
! 866: }
! 867: if (strcaseeq(token, "camellia256") &&
! 868: suites[i].encr == ENCR_CAMELLIA_CBC &&
! 869: suites[i].encr_size == 32)
! 870: {
! 871: suites[remaining++] = suites[i];
! 872: break;
! 873: }
! 874: if (strcaseeq(token, "3des") &&
! 875: suites[i].encr == ENCR_3DES)
! 876: {
! 877: suites[remaining++] = suites[i];
! 878: break;
! 879: }
! 880: if (strcaseeq(token, "null") &&
! 881: suites[i].encr == ENCR_NULL)
! 882: {
! 883: suites[remaining++] = suites[i];
! 884: break;
! 885: }
! 886: }
! 887: enumerator->destroy(enumerator);
! 888: }
! 889: *count = remaining;
! 890: }
! 891: }
! 892:
! 893: /**
! 894: * Filter suites by mac user config
! 895: */
! 896: static void filter_mac_config_suites(private_tls_crypto_t *this,
! 897: suite_algs_t suites[], int *count)
! 898: {
! 899: enumerator_t *enumerator;
! 900: int i, remaining = 0;
! 901: char *token, *config;
! 902:
! 903: config = lib->settings->get_str(lib->settings, "%s.tls.mac", NULL,
! 904: lib->ns);
! 905: if (config)
! 906: {
! 907: for (i = 0; i < *count; i++)
! 908: {
! 909: enumerator = enumerator_create_token(config, ",", " ");
! 910: while (enumerator->enumerate(enumerator, &token))
! 911: {
! 912: if (strcaseeq(token, "md5") &&
! 913: suites[i].mac == AUTH_HMAC_MD5_128)
! 914: {
! 915: suites[remaining++] = suites[i];
! 916: break;
! 917: }
! 918: if (strcaseeq(token, "sha1") &&
! 919: suites[i].mac == AUTH_HMAC_SHA1_160)
! 920: {
! 921: suites[remaining++] = suites[i];
! 922: break;
! 923: }
! 924: if (strcaseeq(token, "sha256") &&
! 925: suites[i].mac == AUTH_HMAC_SHA2_256_256)
! 926: {
! 927: suites[remaining++] = suites[i];
! 928: break;
! 929: }
! 930: if (strcaseeq(token, "sha384") &&
! 931: suites[i].mac == AUTH_HMAC_SHA2_384_384)
! 932: {
! 933: suites[remaining++] = suites[i];
! 934: break;
! 935: }
! 936: }
! 937: enumerator->destroy(enumerator);
! 938: }
! 939: *count = remaining;
! 940: }
! 941: }
! 942:
! 943: /**
! 944: * Filter for specific suites specified in strongswan.conf
! 945: */
! 946: static void filter_specific_config_suites(private_tls_crypto_t *this,
! 947: suite_algs_t suites[], int *count)
! 948: {
! 949: enumerator_t *enumerator;
! 950: int i, remaining = 0, suite;
! 951: char *token, *config;
! 952:
! 953: config = lib->settings->get_str(lib->settings, "%s.tls.suites", NULL,
! 954: lib->ns);
! 955: if (config)
! 956: {
! 957: for (i = 0; i < *count; i++)
! 958: {
! 959: enumerator = enumerator_create_token(config, ",", " ");
! 960: while (enumerator->enumerate(enumerator, &token))
! 961: {
! 962: if (enum_from_name(tls_cipher_suite_names, token, &suite) &&
! 963: suite == suites[i].suite)
! 964: {
! 965: suites[remaining++] = suites[i];
! 966: break;
! 967: }
! 968: }
! 969: enumerator->destroy(enumerator);
! 970: }
! 971: *count = remaining;
! 972: }
! 973: }
! 974:
! 975: /**
! 976: * Filter out unsupported suites on given suite array
! 977: */
! 978: static void filter_unsupported_suites(suite_algs_t suites[], int *count)
! 979: {
! 980: /* filter suite list by each algorithm */
! 981: filter_suite(suites, count, offsetof(suite_algs_t, encr),
! 982: lib->crypto->create_crypter_enumerator);
! 983: filter_suite(suites, count, offsetof(suite_algs_t, encr),
! 984: lib->crypto->create_aead_enumerator);
! 985: filter_suite(suites, count, offsetof(suite_algs_t, mac),
! 986: lib->crypto->create_signer_enumerator);
! 987: filter_suite(suites, count, offsetof(suite_algs_t, prf),
! 988: lib->crypto->create_prf_enumerator);
! 989: filter_suite(suites, count, offsetof(suite_algs_t, hash),
! 990: lib->crypto->create_hasher_enumerator);
! 991: filter_suite(suites, count, offsetof(suite_algs_t, dh),
! 992: lib->crypto->create_dh_enumerator);
! 993: }
! 994:
! 995: /**
! 996: * Initialize the cipher suite list
! 997: */
! 998: static void build_cipher_suite_list(private_tls_crypto_t *this,
! 999: bool require_encryption)
! 1000: {
! 1001: suite_algs_t suites[countof(suite_algs)];
! 1002: int count = countof(suite_algs), i;
! 1003:
! 1004: /* copy all suites */
! 1005: for (i = 0; i < count; i++)
! 1006: {
! 1007: suites[i] = suite_algs[i];
! 1008: }
! 1009:
! 1010: if (require_encryption)
! 1011: {
! 1012: filter_null_suites(suites, &count);
! 1013: }
! 1014: if (!this->rsa)
! 1015: {
! 1016: filter_key_suites(this, suites, &count, KEY_RSA);
! 1017: }
! 1018: if (!this->ecdsa)
! 1019: {
! 1020: filter_key_suites(this, suites, &count, KEY_ECDSA);
! 1021: }
! 1022:
! 1023: filter_unsupported_suites(suites, &count);
! 1024:
! 1025: /* filter suites with strongswan.conf options */
! 1026: filter_key_exchange_config_suites(this, suites, &count);
! 1027: filter_cipher_config_suites(this, suites, &count);
! 1028: filter_mac_config_suites(this, suites, &count);
! 1029: filter_specific_config_suites(this, suites, &count);
! 1030:
! 1031: free(this->suites);
! 1032: this->suite_count = count;
! 1033: this->suites = malloc(sizeof(tls_cipher_suite_t) * count);
! 1034:
! 1035: DBG2(DBG_TLS, "%d supported TLS cipher suites:", count);
! 1036: for (i = 0; i < count; i++)
! 1037: {
! 1038: DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i].suite);
! 1039: this->suites[i] = suites[i].suite;
! 1040: }
! 1041: }
! 1042:
! 1043: METHOD(tls_crypto_t, get_cipher_suites, int,
! 1044: private_tls_crypto_t *this, tls_cipher_suite_t **suites)
! 1045: {
! 1046: *suites = this->suites;
! 1047: return this->suite_count;
! 1048: }
! 1049:
! 1050: /**
! 1051: * Create NULL encryption transforms
! 1052: */
! 1053: static bool create_null(private_tls_crypto_t *this, suite_algs_t *algs)
! 1054: {
! 1055: this->aead_in = tls_aead_create_null(algs->mac);
! 1056: this->aead_out = tls_aead_create_null(algs->mac);
! 1057: if (!this->aead_in || !this->aead_out)
! 1058: {
! 1059: DBG1(DBG_TLS, "selected TLS MAC %N not supported",
! 1060: integrity_algorithm_names, algs->mac);
! 1061: return FALSE;
! 1062: }
! 1063: return TRUE;
! 1064: }
! 1065:
! 1066: /**
! 1067: * Create traditional transforms
! 1068: */
! 1069: static bool create_traditional(private_tls_crypto_t *this, suite_algs_t *algs)
! 1070: {
! 1071: if (this->tls->get_version(this->tls) < TLS_1_1)
! 1072: {
! 1073: this->aead_in = tls_aead_create_implicit(algs->mac,
! 1074: algs->encr, algs->encr_size);
! 1075: this->aead_out = tls_aead_create_implicit(algs->mac,
! 1076: algs->encr, algs->encr_size);
! 1077: }
! 1078: else
! 1079: {
! 1080: this->aead_in = tls_aead_create_explicit(algs->mac,
! 1081: algs->encr, algs->encr_size);
! 1082: this->aead_out = tls_aead_create_explicit(algs->mac,
! 1083: algs->encr, algs->encr_size);
! 1084: }
! 1085: if (!this->aead_in || !this->aead_out)
! 1086: {
! 1087: DBG1(DBG_TLS, "selected TLS transforms %N-%u-%N not supported",
! 1088: encryption_algorithm_names, algs->encr, algs->encr_size * 8,
! 1089: integrity_algorithm_names, algs->mac);
! 1090: return FALSE;
! 1091: }
! 1092: return TRUE;
! 1093: }
! 1094:
! 1095: /**
! 1096: * Create AEAD transforms
! 1097: */
! 1098: static bool create_aead(private_tls_crypto_t *this, suite_algs_t *algs)
! 1099: {
! 1100: this->aead_in = tls_aead_create_aead(algs->encr, algs->encr_size);
! 1101: this->aead_out = tls_aead_create_aead(algs->encr, algs->encr_size);
! 1102: if (!this->aead_in || !this->aead_out)
! 1103: {
! 1104: DBG1(DBG_TLS, "selected TLS transforms %N-%u not supported",
! 1105: encryption_algorithm_names, algs->encr, algs->encr_size * 8);
! 1106: return FALSE;
! 1107: }
! 1108: return TRUE;
! 1109: }
! 1110:
! 1111: /**
! 1112: * Clean up and unset AEAD transforms
! 1113: */
! 1114: static void destroy_aeads(private_tls_crypto_t *this)
! 1115: {
! 1116: DESTROY_IF(this->aead_in);
! 1117: DESTROY_IF(this->aead_out);
! 1118: this->aead_in = this->aead_out = NULL;
! 1119: }
! 1120:
! 1121: /**
! 1122: * Create crypto primitives
! 1123: */
! 1124: static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs)
! 1125: {
! 1126: destroy_aeads(this);
! 1127: DESTROY_IF(this->prf);
! 1128: if (this->tls->get_version(this->tls) < TLS_1_2)
! 1129: {
! 1130: this->prf = tls_prf_create_10();
! 1131: }
! 1132: else
! 1133: {
! 1134: this->prf = tls_prf_create_12(algs->prf);
! 1135: }
! 1136: if (!this->prf)
! 1137: {
! 1138: DBG1(DBG_TLS, "selected TLS PRF not supported");
! 1139: return FALSE;
! 1140: }
! 1141: if (algs->encr == ENCR_NULL)
! 1142: {
! 1143: if (create_null(this, algs))
! 1144: {
! 1145: return TRUE;
! 1146: }
! 1147: }
! 1148: else if (encryption_algorithm_is_aead(algs->encr))
! 1149: {
! 1150: if (create_aead(this, algs))
! 1151: {
! 1152: return TRUE;
! 1153: }
! 1154: }
! 1155: else
! 1156: {
! 1157: if (create_traditional(this, algs))
! 1158: {
! 1159: return TRUE;
! 1160: }
! 1161: }
! 1162: destroy_aeads(this);
! 1163: return FALSE;
! 1164: }
! 1165:
! 1166: METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
! 1167: private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count,
! 1168: key_type_t key)
! 1169: {
! 1170: suite_algs_t *algs;
! 1171: int i, j;
! 1172:
! 1173: for (i = 0; i < this->suite_count; i++)
! 1174: {
! 1175: for (j = 0; j < count; j++)
! 1176: {
! 1177: if (this->suites[i] == suites[j])
! 1178: {
! 1179: algs = find_suite(this->suites[i]);
! 1180: if (algs)
! 1181: {
! 1182: if (key == KEY_ANY || key == algs->key)
! 1183: {
! 1184: if (create_ciphers(this, algs))
! 1185: {
! 1186: this->suite = this->suites[i];
! 1187: return this->suite;
! 1188: }
! 1189: }
! 1190: }
! 1191: }
! 1192: }
! 1193: }
! 1194: return 0;
! 1195: }
! 1196:
! 1197: METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t,
! 1198: private_tls_crypto_t *this)
! 1199: {
! 1200: suite_algs_t *algs;
! 1201:
! 1202: algs = find_suite(this->suite);
! 1203: if (algs)
! 1204: {
! 1205: return algs->dh;
! 1206: }
! 1207: return MODP_NONE;
! 1208: }
! 1209:
! 1210: /**
! 1211: * Map signature schemes to TLS key types and hashes, ordered by preference
! 1212: */
! 1213: static struct {
! 1214: tls_signature_algorithm_t sig;
! 1215: tls_hash_algorithm_t hash;
! 1216: signature_scheme_t scheme;
! 1217: } schemes[] = {
! 1218: { TLS_SIG_ECDSA, TLS_HASH_SHA256, SIGN_ECDSA_WITH_SHA256_DER },
! 1219: { TLS_SIG_ECDSA, TLS_HASH_SHA384, SIGN_ECDSA_WITH_SHA384_DER },
! 1220: { TLS_SIG_ECDSA, TLS_HASH_SHA512, SIGN_ECDSA_WITH_SHA512_DER },
! 1221: { TLS_SIG_ECDSA, TLS_HASH_SHA1, SIGN_ECDSA_WITH_SHA1_DER },
! 1222: { TLS_SIG_RSA, TLS_HASH_SHA256, SIGN_RSA_EMSA_PKCS1_SHA2_256 },
! 1223: { TLS_SIG_RSA, TLS_HASH_SHA384, SIGN_RSA_EMSA_PKCS1_SHA2_384 },
! 1224: { TLS_SIG_RSA, TLS_HASH_SHA512, SIGN_RSA_EMSA_PKCS1_SHA2_512 },
! 1225: { TLS_SIG_RSA, TLS_HASH_SHA224, SIGN_RSA_EMSA_PKCS1_SHA2_224 },
! 1226: { TLS_SIG_RSA, TLS_HASH_SHA1, SIGN_RSA_EMSA_PKCS1_SHA1 },
! 1227: { TLS_SIG_RSA, TLS_HASH_MD5, SIGN_RSA_EMSA_PKCS1_MD5 },
! 1228: };
! 1229:
! 1230: METHOD(tls_crypto_t, get_signature_algorithms, void,
! 1231: private_tls_crypto_t *this, bio_writer_t *writer)
! 1232: {
! 1233: bio_writer_t *supported;
! 1234: int i;
! 1235:
! 1236: supported = bio_writer_create(32);
! 1237:
! 1238: for (i = 0; i < countof(schemes); i++)
! 1239: {
! 1240: if (schemes[i].sig == TLS_SIG_RSA && !this->rsa)
! 1241: {
! 1242: continue;
! 1243: }
! 1244: if (schemes[i].sig == TLS_SIG_ECDSA && !this->ecdsa)
! 1245: {
! 1246: continue;
! 1247: }
! 1248: if (!lib->plugins->has_feature(lib->plugins,
! 1249: PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].scheme)))
! 1250: {
! 1251: continue;
! 1252: }
! 1253: supported->write_uint8(supported, schemes[i].hash);
! 1254: supported->write_uint8(supported, schemes[i].sig);
! 1255: }
! 1256:
! 1257: supported->wrap16(supported);
! 1258: writer->write_data16(writer, supported->get_buf(supported));
! 1259: supported->destroy(supported);
! 1260: }
! 1261:
! 1262: /**
! 1263: * Get the signature scheme from a TLS 1.2 hash/sig algorithm pair
! 1264: */
! 1265: static signature_scheme_t hashsig_to_scheme(key_type_t type,
! 1266: tls_hash_algorithm_t hash,
! 1267: tls_signature_algorithm_t sig)
! 1268: {
! 1269: int i;
! 1270:
! 1271: if ((sig == TLS_SIG_RSA && type == KEY_RSA) ||
! 1272: (sig == TLS_SIG_ECDSA && type == KEY_ECDSA))
! 1273: {
! 1274: for (i = 0; i < countof(schemes); i++)
! 1275: {
! 1276: if (schemes[i].sig == sig && schemes[i].hash == hash)
! 1277: {
! 1278: return schemes[i].scheme;
! 1279: }
! 1280: }
! 1281: }
! 1282: return SIGN_UNKNOWN;
! 1283: }
! 1284:
! 1285: /**
! 1286: * Mapping groups to TLS named curves
! 1287: */
! 1288: static struct {
! 1289: diffie_hellman_group_t group;
! 1290: tls_named_curve_t curve;
! 1291: } curves[] = {
! 1292: { ECP_256_BIT, TLS_SECP256R1},
! 1293: { ECP_384_BIT, TLS_SECP384R1},
! 1294: { ECP_521_BIT, TLS_SECP521R1},
! 1295: { ECP_224_BIT, TLS_SECP224R1},
! 1296: { ECP_192_BIT, TLS_SECP192R1},
! 1297: };
! 1298:
! 1299: CALLBACK(group_filter, bool,
! 1300: void *null, enumerator_t *orig, va_list args)
! 1301: {
! 1302: diffie_hellman_group_t group, *out;
! 1303: tls_named_curve_t *curve;
! 1304: char *plugin;
! 1305: int i;
! 1306:
! 1307: VA_ARGS_VGET(args, out, curve);
! 1308:
! 1309: while (orig->enumerate(orig, &group, &plugin))
! 1310: {
! 1311: for (i = 0; i < countof(curves); i++)
! 1312: {
! 1313: if (curves[i].group == group)
! 1314: {
! 1315: if (out)
! 1316: {
! 1317: *out = curves[i].group;
! 1318: }
! 1319: if (curve)
! 1320: {
! 1321: *curve = curves[i].curve;
! 1322: }
! 1323: return TRUE;
! 1324: }
! 1325: }
! 1326: }
! 1327: return FALSE;
! 1328: }
! 1329:
! 1330: METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*,
! 1331: private_tls_crypto_t *this)
! 1332: {
! 1333: return enumerator_create_filter(
! 1334: lib->crypto->create_dh_enumerator(lib->crypto),
! 1335: group_filter, NULL, NULL);
! 1336: }
! 1337:
! 1338: METHOD(tls_crypto_t, set_protection, void,
! 1339: private_tls_crypto_t *this, tls_protection_t *protection)
! 1340: {
! 1341: this->protection = protection;
! 1342: }
! 1343:
! 1344: METHOD(tls_crypto_t, append_handshake, void,
! 1345: private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
! 1346: {
! 1347: uint32_t header;
! 1348:
! 1349: /* reconstruct handshake header */
! 1350: header = htonl(data.len | (type << 24));
! 1351: this->handshake = chunk_cat("mcc", this->handshake,
! 1352: chunk_from_thing(header), data);
! 1353: }
! 1354:
! 1355: /**
! 1356: * Create a hash using the suites HASH algorithm
! 1357: */
! 1358: static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash)
! 1359: {
! 1360: if (this->tls->get_version(this->tls) >= TLS_1_2)
! 1361: {
! 1362: hasher_t *hasher;
! 1363: suite_algs_t *alg;
! 1364:
! 1365: alg = find_suite(this->suite);
! 1366: if (!alg)
! 1367: {
! 1368: return FALSE;
! 1369: }
! 1370: hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
! 1371: if (!hasher || !hasher->allocate_hash(hasher, data, hash))
! 1372: {
! 1373: DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash);
! 1374: DESTROY_IF(hasher);
! 1375: return FALSE;
! 1376: }
! 1377: hasher->destroy(hasher);
! 1378: }
! 1379: else
! 1380: {
! 1381: hasher_t *md5, *sha1;
! 1382: char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
! 1383:
! 1384: md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
! 1385: if (!md5 || !md5->get_hash(md5, data, buf))
! 1386: {
! 1387: DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5);
! 1388: DESTROY_IF(md5);
! 1389: return FALSE;
! 1390: }
! 1391: md5->destroy(md5);
! 1392: sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
! 1393: if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5))
! 1394: {
! 1395: DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1);
! 1396: DESTROY_IF(sha1);
! 1397: return FALSE;
! 1398: }
! 1399: sha1->destroy(sha1);
! 1400:
! 1401: *hash = chunk_clone(chunk_from_thing(buf));
! 1402: }
! 1403: return TRUE;
! 1404: }
! 1405:
! 1406: METHOD(tls_crypto_t, sign, bool,
! 1407: private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
! 1408: chunk_t data, chunk_t hashsig)
! 1409: {
! 1410: if (this->tls->get_version(this->tls) >= TLS_1_2)
! 1411: {
! 1412: const chunk_t hashsig_def = chunk_from_chars(
! 1413: TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA);
! 1414: signature_scheme_t scheme;
! 1415: bio_reader_t *reader;
! 1416: uint8_t hash, alg;
! 1417: chunk_t sig;
! 1418: bool done = FALSE;
! 1419:
! 1420: if (!hashsig.len)
! 1421: { /* fallback if none given */
! 1422: hashsig = hashsig_def;
! 1423: }
! 1424: reader = bio_reader_create(hashsig);
! 1425: while (reader->remaining(reader) >= 2)
! 1426: {
! 1427: if (reader->read_uint8(reader, &hash) &&
! 1428: reader->read_uint8(reader, &alg))
! 1429: {
! 1430: scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
! 1431: if (scheme != SIGN_UNKNOWN &&
! 1432: key->sign(key, scheme, NULL, data, &sig))
! 1433: {
! 1434: done = TRUE;
! 1435: break;
! 1436: }
! 1437: }
! 1438: }
! 1439: reader->destroy(reader);
! 1440: if (!done)
! 1441: {
! 1442: DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported");
! 1443: return FALSE;
! 1444: }
! 1445: DBG2(DBG_TLS, "created signature with %N/%N",
! 1446: tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
! 1447: writer->write_uint8(writer, hash);
! 1448: writer->write_uint8(writer, alg);
! 1449: writer->write_data16(writer, sig);
! 1450: free(sig.ptr);
! 1451: }
! 1452: else
! 1453: {
! 1454: chunk_t sig, hash;
! 1455: bool done;
! 1456:
! 1457: switch (key->get_type(key))
! 1458: {
! 1459: case KEY_RSA:
! 1460: if (!hash_data(this, data, &hash))
! 1461: {
! 1462: return FALSE;
! 1463: }
! 1464: done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
! 1465: &sig);
! 1466: free(hash.ptr);
! 1467: if (!done)
! 1468: {
! 1469: return FALSE;
! 1470: }
! 1471: DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA");
! 1472: break;
! 1473: case KEY_ECDSA:
! 1474: if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, &sig))
! 1475: {
! 1476: return FALSE;
! 1477: }
! 1478: DBG2(DBG_TLS, "created signature with SHA1/ECDSA");
! 1479: break;
! 1480: default:
! 1481: return FALSE;
! 1482: }
! 1483: writer->write_data16(writer, sig);
! 1484: free(sig.ptr);
! 1485: }
! 1486: return TRUE;
! 1487: }
! 1488:
! 1489: METHOD(tls_crypto_t, verify, bool,
! 1490: private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader,
! 1491: chunk_t data)
! 1492: {
! 1493: if (this->tls->get_version(this->tls) >= TLS_1_2)
! 1494: {
! 1495: signature_scheme_t scheme = SIGN_UNKNOWN;
! 1496: uint8_t hash, alg;
! 1497: chunk_t sig;
! 1498:
! 1499: if (!reader->read_uint8(reader, &hash) ||
! 1500: !reader->read_uint8(reader, &alg) ||
! 1501: !reader->read_data16(reader, &sig))
! 1502: {
! 1503: DBG1(DBG_TLS, "received invalid signature");
! 1504: return FALSE;
! 1505: }
! 1506: scheme = hashsig_to_scheme(key->get_type(key), hash, alg);
! 1507: if (scheme == SIGN_UNKNOWN)
! 1508: {
! 1509: DBG1(DBG_TLS, "signature algorithms %N/%N not supported",
! 1510: tls_hash_algorithm_names, hash,
! 1511: tls_signature_algorithm_names, alg);
! 1512: return FALSE;
! 1513: }
! 1514: if (!key->verify(key, scheme, NULL, data, sig))
! 1515: {
! 1516: return FALSE;
! 1517: }
! 1518: DBG2(DBG_TLS, "verified signature with %N/%N",
! 1519: tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg);
! 1520: }
! 1521: else
! 1522: {
! 1523: chunk_t sig, hash;
! 1524: bool done;
! 1525:
! 1526: if (!reader->read_data16(reader, &sig))
! 1527: {
! 1528: DBG1(DBG_TLS, "received invalid signature");
! 1529: return FALSE;
! 1530: }
! 1531: switch (key->get_type(key))
! 1532: {
! 1533: case KEY_RSA:
! 1534: if (!hash_data(this, data, &hash))
! 1535: {
! 1536: return FALSE;
! 1537: }
! 1538: done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash,
! 1539: sig);
! 1540: free(hash.ptr);
! 1541: if (!done)
! 1542: {
! 1543: return FALSE;
! 1544: }
! 1545: DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA");
! 1546: break;
! 1547: case KEY_ECDSA:
! 1548: if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data,
! 1549: sig))
! 1550: {
! 1551: return FALSE;
! 1552: }
! 1553: DBG2(DBG_TLS, "verified signature with SHA1/ECDSA");
! 1554: break;
! 1555: default:
! 1556: return FALSE;
! 1557: }
! 1558: }
! 1559: return TRUE;
! 1560: }
! 1561:
! 1562: METHOD(tls_crypto_t, sign_handshake, bool,
! 1563: private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
! 1564: chunk_t hashsig)
! 1565: {
! 1566: return sign(this, key, writer, this->handshake, hashsig);
! 1567: }
! 1568:
! 1569: METHOD(tls_crypto_t, verify_handshake, bool,
! 1570: private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader)
! 1571: {
! 1572: return verify(this, key, reader, this->handshake);
! 1573: }
! 1574:
! 1575: METHOD(tls_crypto_t, calculate_finished, bool,
! 1576: private_tls_crypto_t *this, char *label, char out[12])
! 1577: {
! 1578: chunk_t seed;
! 1579:
! 1580: if (!this->prf)
! 1581: {
! 1582: return FALSE;
! 1583: }
! 1584: if (!hash_data(this, this->handshake, &seed))
! 1585: {
! 1586: return FALSE;
! 1587: }
! 1588: if (!this->prf->get_bytes(this->prf, label, seed, 12, out))
! 1589: {
! 1590: free(seed.ptr);
! 1591: return FALSE;
! 1592: }
! 1593: free(seed.ptr);
! 1594: return TRUE;
! 1595: }
! 1596:
! 1597: /**
! 1598: * Derive master secret from premaster, optionally save session
! 1599: */
! 1600: static bool derive_master(private_tls_crypto_t *this, chunk_t premaster,
! 1601: chunk_t session, identification_t *id,
! 1602: chunk_t client_random, chunk_t server_random)
! 1603: {
! 1604: char master[48];
! 1605: chunk_t seed;
! 1606:
! 1607: /* derive master secret */
! 1608: seed = chunk_cata("cc", client_random, server_random);
! 1609:
! 1610: if (!this->prf->set_key(this->prf, premaster) ||
! 1611: !this->prf->get_bytes(this->prf, "master secret", seed,
! 1612: sizeof(master), master) ||
! 1613: !this->prf->set_key(this->prf, chunk_from_thing(master)))
! 1614: {
! 1615: return FALSE;
! 1616: }
! 1617:
! 1618: if (this->cache && session.len)
! 1619: {
! 1620: this->cache->create(this->cache, session, id, chunk_from_thing(master),
! 1621: this->suite);
! 1622: }
! 1623: memwipe(master, sizeof(master));
! 1624: return TRUE;
! 1625: }
! 1626:
! 1627: /**
! 1628: * Expand key material from master secret
! 1629: */
! 1630: static bool expand_keys(private_tls_crypto_t *this,
! 1631: chunk_t client_random, chunk_t server_random)
! 1632: {
! 1633: chunk_t seed, block;
! 1634: chunk_t cw_mac, cw, cw_iv;
! 1635: chunk_t sw_mac, sw, sw_iv;
! 1636: int mklen, eklen, ivlen;
! 1637:
! 1638: if (!this->aead_in || !this->aead_out)
! 1639: {
! 1640: return FALSE;
! 1641: }
! 1642:
! 1643: /* derive key block for key expansion */
! 1644: mklen = this->aead_in->get_mac_key_size(this->aead_in);
! 1645: eklen = this->aead_in->get_encr_key_size(this->aead_in);
! 1646: ivlen = this->aead_in->get_iv_size(this->aead_in);
! 1647: seed = chunk_cata("cc", server_random, client_random);
! 1648: block = chunk_alloca((mklen + eklen + ivlen) * 2);
! 1649: if (!this->prf->get_bytes(this->prf, "key expansion", seed,
! 1650: block.len, block.ptr))
! 1651: {
! 1652: return FALSE;
! 1653: }
! 1654:
! 1655: /* client/server write signer keys */
! 1656: cw_mac = chunk_create(block.ptr, mklen);
! 1657: block = chunk_skip(block, mklen);
! 1658: sw_mac = chunk_create(block.ptr, mklen);
! 1659: block = chunk_skip(block, mklen);
! 1660:
! 1661: /* client/server write encryption keys */
! 1662: cw = chunk_create(block.ptr, eklen);
! 1663: block = chunk_skip(block, eklen);
! 1664: sw = chunk_create(block.ptr, eklen);
! 1665: block = chunk_skip(block, eklen);
! 1666:
! 1667: /* client/server write IV; TLS 1.0 implicit IVs or AEAD salt, if any */
! 1668: cw_iv = chunk_create(block.ptr, ivlen);
! 1669: block = chunk_skip(block, ivlen);
! 1670: sw_iv = chunk_create(block.ptr, ivlen);
! 1671: block = chunk_skip(block, ivlen);
! 1672:
! 1673: if (this->tls->is_server(this->tls))
! 1674: {
! 1675: if (!this->aead_in->set_keys(this->aead_in, cw_mac, cw, cw_iv) ||
! 1676: !this->aead_out->set_keys(this->aead_out, sw_mac, sw, sw_iv))
! 1677: {
! 1678: return FALSE;
! 1679: }
! 1680: }
! 1681: else
! 1682: {
! 1683: if (!this->aead_out->set_keys(this->aead_out, cw_mac, cw, cw_iv) ||
! 1684: !this->aead_in->set_keys(this->aead_in, sw_mac, sw, sw_iv))
! 1685: {
! 1686: return FALSE;
! 1687: }
! 1688: }
! 1689:
! 1690: /* EAP-MSK */
! 1691: if (this->msk_label)
! 1692: {
! 1693: seed = chunk_cata("cc", client_random, server_random);
! 1694: this->msk = chunk_alloc(64);
! 1695: if (!this->prf->get_bytes(this->prf, this->msk_label, seed,
! 1696: this->msk.len, this->msk.ptr))
! 1697: {
! 1698: return FALSE;
! 1699: }
! 1700: }
! 1701: return TRUE;
! 1702: }
! 1703:
! 1704: METHOD(tls_crypto_t, derive_secrets, bool,
! 1705: private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
! 1706: identification_t *id, chunk_t client_random, chunk_t server_random)
! 1707: {
! 1708: return derive_master(this, premaster, session, id,
! 1709: client_random, server_random) &&
! 1710: expand_keys(this, client_random, server_random);
! 1711: }
! 1712:
! 1713: METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
! 1714: private_tls_crypto_t *this, chunk_t session, identification_t *id,
! 1715: chunk_t client_random, chunk_t server_random)
! 1716: {
! 1717: chunk_t master;
! 1718:
! 1719: if (this->cache && session.len)
! 1720: {
! 1721: this->suite = this->cache->lookup(this->cache, session, id, &master);
! 1722: if (this->suite)
! 1723: {
! 1724: this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY);
! 1725: if (this->suite)
! 1726: {
! 1727: if (!this->prf->set_key(this->prf, master) ||
! 1728: !expand_keys(this, client_random, server_random))
! 1729: {
! 1730: this->suite = 0;
! 1731: }
! 1732: }
! 1733: chunk_clear(&master);
! 1734: }
! 1735: return this->suite;
! 1736: }
! 1737: return 0;
! 1738: }
! 1739:
! 1740: METHOD(tls_crypto_t, get_session, chunk_t,
! 1741: private_tls_crypto_t *this, identification_t *server)
! 1742: {
! 1743: if (this->cache)
! 1744: {
! 1745: return this->cache->check(this->cache, server);
! 1746: }
! 1747: return chunk_empty;
! 1748: }
! 1749:
! 1750: METHOD(tls_crypto_t, change_cipher, void,
! 1751: private_tls_crypto_t *this, bool inbound)
! 1752: {
! 1753: if (this->protection)
! 1754: {
! 1755: if (inbound)
! 1756: {
! 1757: this->protection->set_cipher(this->protection, TRUE, this->aead_in);
! 1758: }
! 1759: else
! 1760: {
! 1761: this->protection->set_cipher(this->protection, FALSE, this->aead_out);
! 1762: }
! 1763: }
! 1764: }
! 1765:
! 1766: METHOD(tls_crypto_t, get_eap_msk, chunk_t,
! 1767: private_tls_crypto_t *this)
! 1768: {
! 1769: return this->msk;
! 1770: }
! 1771:
! 1772: METHOD(tls_crypto_t, destroy, void,
! 1773: private_tls_crypto_t *this)
! 1774: {
! 1775: destroy_aeads(this);
! 1776: free(this->handshake.ptr);
! 1777: free(this->msk.ptr);
! 1778: DESTROY_IF(this->prf);
! 1779: free(this->suites);
! 1780: free(this);
! 1781: }
! 1782:
! 1783: /**
! 1784: * See header
! 1785: */
! 1786: tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
! 1787: {
! 1788: private_tls_crypto_t *this;
! 1789: enumerator_t *enumerator;
! 1790: credential_type_t type;
! 1791: int subtype;
! 1792:
! 1793: INIT(this,
! 1794: .public = {
! 1795: .get_cipher_suites = _get_cipher_suites,
! 1796: .select_cipher_suite = _select_cipher_suite,
! 1797: .get_dh_group = _get_dh_group,
! 1798: .get_signature_algorithms = _get_signature_algorithms,
! 1799: .create_ec_enumerator = _create_ec_enumerator,
! 1800: .set_protection = _set_protection,
! 1801: .append_handshake = _append_handshake,
! 1802: .sign = _sign,
! 1803: .verify = _verify,
! 1804: .sign_handshake = _sign_handshake,
! 1805: .verify_handshake = _verify_handshake,
! 1806: .calculate_finished = _calculate_finished,
! 1807: .derive_secrets = _derive_secrets,
! 1808: .resume_session = _resume_session,
! 1809: .get_session = _get_session,
! 1810: .change_cipher = _change_cipher,
! 1811: .get_eap_msk = _get_eap_msk,
! 1812: .destroy = _destroy,
! 1813: },
! 1814: .tls = tls,
! 1815: .cache = cache,
! 1816: );
! 1817:
! 1818: enumerator = lib->creds->create_builder_enumerator(lib->creds);
! 1819: while (enumerator->enumerate(enumerator, &type, &subtype))
! 1820: {
! 1821: if (type == CRED_PUBLIC_KEY)
! 1822: {
! 1823: switch (subtype)
! 1824: {
! 1825: case KEY_RSA:
! 1826: this->rsa = TRUE;
! 1827: break;
! 1828: case KEY_ECDSA:
! 1829: this->ecdsa = TRUE;
! 1830: break;
! 1831: default:
! 1832: break;
! 1833: }
! 1834: }
! 1835: }
! 1836: enumerator->destroy(enumerator);
! 1837:
! 1838: switch (tls->get_purpose(tls))
! 1839: {
! 1840: case TLS_PURPOSE_EAP_TLS:
! 1841: /* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */
! 1842: this->msk_label = "client EAP encryption";
! 1843: build_cipher_suite_list(this, FALSE);
! 1844: break;
! 1845: case TLS_PURPOSE_EAP_PEAP:
! 1846: this->msk_label = "client EAP encryption";
! 1847: build_cipher_suite_list(this, TRUE);
! 1848: break;
! 1849: case TLS_PURPOSE_EAP_TTLS:
! 1850: /* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */
! 1851: this->msk_label = "ttls keying material";
! 1852: build_cipher_suite_list(this, TRUE);
! 1853: break;
! 1854: case TLS_PURPOSE_GENERIC:
! 1855: build_cipher_suite_list(this, TRUE);
! 1856: break;
! 1857: case TLS_PURPOSE_GENERIC_NULLOK:
! 1858: build_cipher_suite_list(this, FALSE);
! 1859: break;
! 1860: default:
! 1861: break;
! 1862: }
! 1863: return &this->public;
! 1864: }
! 1865:
! 1866: /**
! 1867: * See header.
! 1868: */
! 1869: int tls_crypto_get_supported_suites(bool null, tls_cipher_suite_t **out)
! 1870: {
! 1871: suite_algs_t suites[countof(suite_algs)];
! 1872: int count = countof(suite_algs), i;
! 1873:
! 1874: /* initialize copy of suite list */
! 1875: for (i = 0; i < count; i++)
! 1876: {
! 1877: suites[i] = suite_algs[i];
! 1878: }
! 1879:
! 1880: filter_unsupported_suites(suites, &count);
! 1881:
! 1882: if (!null)
! 1883: {
! 1884: filter_null_suites(suites, &count);
! 1885: }
! 1886:
! 1887: if (out)
! 1888: {
! 1889: *out = calloc(count, sizeof(tls_cipher_suite_t));
! 1890: for (i = 0; i < count; i++)
! 1891: {
! 1892: (*out)[i] = suites[i].suite;
! 1893: }
! 1894: }
! 1895: return count;
! 1896: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>