Added TLS crypto helper, currently supports cipher suite selection
[strongswan.git] / src / charon / plugins / eap_tls / tls / tls_crypto.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 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 typedef struct private_tls_crypto_t private_tls_crypto_t;
19
20 /**
21 * Private data of an tls_crypto_t object.
22 */
23 struct private_tls_crypto_t {
24
25 /**
26 * Public tls_crypto_t interface.
27 */
28 tls_crypto_t public;
29 };
30
31 METHOD(tls_crypto_t, get_cipher_suites, int,
32 private_tls_crypto_t *this, tls_cipher_suite_t **suites)
33 {
34 encryption_algorithm_t encr;
35 integrity_algorithm_t mac;
36 enumerator_t *encrs, *macs;
37 tls_cipher_suite_t buf[64];
38 int count = 0, i, j, res = 0;
39
40 /* we assume that we support RSA, but no DHE yet */
41 macs = lib->crypto->create_signer_enumerator(lib->crypto);
42 while (macs->enumerate(macs, &mac))
43 {
44 switch (mac)
45 {
46 case AUTH_HMAC_SHA1_160:
47 buf[count++] = TLS_RSA_WITH_NULL_SHA;
48 break;
49 case AUTH_HMAC_SHA2_256_256:
50 buf[count++] = TLS_RSA_WITH_NULL_SHA256;
51 break;
52 case AUTH_HMAC_MD5_128:
53 buf[count++] = TLS_RSA_WITH_NULL_MD5;
54 break;
55 default:
56 break;
57 }
58 encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
59 while (encrs->enumerate(encrs, &encr))
60 {
61 switch (encr)
62 {
63 case ENCR_AES_CBC:
64 switch (mac)
65 {
66 case AUTH_HMAC_SHA1_160:
67 buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
68 buf[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
69 break;
70 case AUTH_HMAC_SHA2_256_256:
71 buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
72 buf[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
73 break;
74 default:
75 break;
76 }
77 break;
78 case ENCR_3DES:
79 switch (mac)
80 {
81 case AUTH_HMAC_SHA1_160:
82 buf[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
83 break;
84 default:
85 break;
86 }
87 break;
88 default:
89 break;
90 }
91 }
92 encrs->destroy(encrs);
93 }
94 macs->destroy(macs);
95
96 /* remove duplicates */
97 *suites = malloc(sizeof(tls_cipher_suite_t) * count);
98 for (i = 0; i < count; i++)
99 {
100 bool match = FALSE;
101
102 for (j = 0; j < res; j++)
103 {
104 if (buf[i] == (*suites)[j])
105 {
106 match = TRUE;
107 break;
108 }
109 }
110 if (!match)
111 {
112 (*suites)[res++] = buf[i];
113 }
114 }
115 return res;
116 }
117
118
119 METHOD(tls_crypto_t, destroy, void,
120 private_tls_crypto_t *this)
121 {
122 free(this);
123 }
124
125 /**
126 * See header
127 */
128 tls_crypto_t *tls_crypto_create()
129 {
130 private_tls_crypto_t *this;
131
132 INIT(this,
133 .public = {
134 .get_cipher_suites = _get_cipher_suites,
135 .destroy = _destroy,
136 },
137 );
138
139 return &this->public;
140 }