]>
Commit | Line | Data |
---|---|---|
d02b48c6 | 1 | /* ssl/ssl_ciph.c */ |
58964a49 | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
d02b48c6 RE |
3 | * All rights reserved. |
4 | * | |
5 | * This package is an SSL implementation written | |
6 | * by Eric Young (eay@cryptsoft.com). | |
7 | * The implementation was written so as to conform with Netscapes SSL. | |
8 | * | |
9 | * This library is free for commercial and non-commercial use as long as | |
10 | * the following conditions are aheared to. The following conditions | |
11 | * apply to all code found in this distribution, be it the RC4, RSA, | |
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | |
13 | * included with this distribution is covered by the same copyright terms | |
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | |
15 | * | |
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | |
17 | * the code are not to be removed. | |
18 | * If this package is used in a product, Eric Young should be given attribution | |
19 | * as the author of the parts of the library used. | |
20 | * This can be in the form of a textual message at program startup or | |
21 | * in documentation (online or textual) provided with the package. | |
22 | * | |
23 | * Redistribution and use in source and binary forms, with or without | |
24 | * modification, are permitted provided that the following conditions | |
25 | * are met: | |
26 | * 1. Redistributions of source code must retain the copyright | |
27 | * notice, this list of conditions and the following disclaimer. | |
28 | * 2. Redistributions in binary form must reproduce the above copyright | |
29 | * notice, this list of conditions and the following disclaimer in the | |
30 | * documentation and/or other materials provided with the distribution. | |
31 | * 3. All advertising materials mentioning features or use of this software | |
32 | * must display the following acknowledgement: | |
33 | * "This product includes cryptographic software written by | |
34 | * Eric Young (eay@cryptsoft.com)" | |
35 | * The word 'cryptographic' can be left out if the rouines from the library | |
36 | * being used are not cryptographic related :-). | |
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | |
38 | * the apps directory (application code) you must include an acknowledgement: | |
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | |
40 | * | |
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | |
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
51 | * SUCH DAMAGE. | |
52 | * | |
53 | * The licence and distribution terms for any publically available version or | |
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | |
55 | * copied and put under another distribution licence | |
56 | * [including the GNU Public Licence.] | |
57 | */ | |
ea262260 BM |
58 | /* ==================================================================== |
59 | * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. | |
60 | * ECC cipher suite support in OpenSSL originally developed by | |
61 | * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. | |
62 | */ | |
d02b48c6 | 63 | #include <stdio.h> |
ec577822 BM |
64 | #include <openssl/objects.h> |
65 | #include <openssl/comp.h> | |
d02b48c6 RE |
66 | #include "ssl_locl.h" |
67 | ||
68 | #define SSL_ENC_DES_IDX 0 | |
69 | #define SSL_ENC_3DES_IDX 1 | |
70 | #define SSL_ENC_RC4_IDX 2 | |
71 | #define SSL_ENC_RC2_IDX 3 | |
72 | #define SSL_ENC_IDEA_IDX 4 | |
73 | #define SSL_ENC_eFZA_IDX 5 | |
74 | #define SSL_ENC_NULL_IDX 6 | |
deb2c1a1 DSH |
75 | #define SSL_ENC_AES128_IDX 7 |
76 | #define SSL_ENC_AES256_IDX 8 | |
77 | #define SSL_ENC_NUM_IDX 9 | |
d02b48c6 | 78 | |
e778802f | 79 | static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={ |
d02b48c6 RE |
80 | NULL,NULL,NULL,NULL,NULL,NULL, |
81 | }; | |
82 | ||
7ba666fa RL |
83 | #define SSL_COMP_NULL_IDX 0 |
84 | #define SSL_COMP_ZLIB_IDX 1 | |
85 | #define SSL_COMP_NUM_IDX 2 | |
86 | ||
f73e07cf | 87 | static STACK_OF(SSL_COMP) *ssl_comp_methods=NULL; |
413c4f45 | 88 | |
d02b48c6 | 89 | #define SSL_MD_MD5_IDX 0 |
58964a49 RE |
90 | #define SSL_MD_SHA1_IDX 1 |
91 | #define SSL_MD_NUM_IDX 2 | |
e778802f | 92 | static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ |
58964a49 | 93 | NULL,NULL, |
d02b48c6 RE |
94 | }; |
95 | ||
d02b48c6 RE |
96 | #define CIPHER_ADD 1 |
97 | #define CIPHER_KILL 2 | |
98 | #define CIPHER_DEL 3 | |
58964a49 | 99 | #define CIPHER_ORD 4 |
018e57c7 | 100 | #define CIPHER_SPECIAL 5 |
d02b48c6 | 101 | |
58964a49 RE |
102 | typedef struct cipher_order_st |
103 | { | |
104 | SSL_CIPHER *cipher; | |
105 | int active; | |
106 | int dead; | |
107 | struct cipher_order_st *next,*prev; | |
108 | } CIPHER_ORDER; | |
109 | ||
018e57c7 | 110 | static const SSL_CIPHER cipher_aliases[]={ |
ea4f109c | 111 | /* Don't include eNULL unless specifically enabled. */ |
ea262260 BM |
112 | /* Don't include ECC in ALL because these ciphers are not yet official. */ |
113 | {0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */ | |
114 | /* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */ | |
115 | {0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, /* COMPLEMENT OF ALL */ | |
c6ccf055 | 116 | {0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0}, |
ea262260 | 117 | {0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0}, /* VRS Kerberos5 */ |
018e57c7 DSH |
118 | {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0}, |
119 | {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0}, | |
120 | {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0}, | |
121 | {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0}, | |
122 | {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0}, | |
123 | {0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0}, | |
ea262260 | 124 | {0,SSL_TXT_ECC, 0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0}, |
018e57c7 | 125 | {0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0}, |
f9b3bff6 | 126 | {0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0}, /* VRS Kerberos5 */ |
018e57c7 DSH |
127 | {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0}, |
128 | {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0}, | |
129 | {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0}, | |
130 | {0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0}, | |
131 | {0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0}, | |
132 | {0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0}, | |
133 | ||
134 | {0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0}, | |
135 | {0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0}, | |
136 | {0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0}, | |
137 | {0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0}, | |
138 | {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0}, | |
139 | {0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0}, | |
140 | {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0}, | |
deb2c1a1 | 141 | {0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0}, |
018e57c7 DSH |
142 | |
143 | {0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0}, | |
144 | {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0}, | |
145 | {0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0}, | |
146 | ||
147 | {0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0}, | |
f9b3bff6 | 148 | {0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, |
018e57c7 DSH |
149 | {0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, |
150 | {0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0}, | |
151 | {0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0}, | |
152 | ||
153 | {0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0}, | |
154 | {0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0}, | |
155 | {0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0}, | |
156 | ||
157 | {0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, | |
158 | {0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK}, | |
159 | {0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK}, | |
160 | {0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK}, | |
161 | {0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK}, | |
162 | {0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK}, | |
163 | {0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK}, | |
d02b48c6 RE |
164 | }; |
165 | ||
166 | static int init_ciphers=1; | |
d02b48c6 | 167 | |
6b691a5c | 168 | static void load_ciphers(void) |
d02b48c6 RE |
169 | { |
170 | init_ciphers=0; | |
171 | ssl_cipher_methods[SSL_ENC_DES_IDX]= | |
172 | EVP_get_cipherbyname(SN_des_cbc); | |
173 | ssl_cipher_methods[SSL_ENC_3DES_IDX]= | |
174 | EVP_get_cipherbyname(SN_des_ede3_cbc); | |
175 | ssl_cipher_methods[SSL_ENC_RC4_IDX]= | |
176 | EVP_get_cipherbyname(SN_rc4); | |
177 | ssl_cipher_methods[SSL_ENC_RC2_IDX]= | |
178 | EVP_get_cipherbyname(SN_rc2_cbc); | |
179 | ssl_cipher_methods[SSL_ENC_IDEA_IDX]= | |
180 | EVP_get_cipherbyname(SN_idea_cbc); | |
deb2c1a1 DSH |
181 | ssl_cipher_methods[SSL_ENC_AES128_IDX]= |
182 | EVP_get_cipherbyname(SN_aes_128_cbc); | |
183 | ssl_cipher_methods[SSL_ENC_AES256_IDX]= | |
184 | EVP_get_cipherbyname(SN_aes_256_cbc); | |
d02b48c6 RE |
185 | |
186 | ssl_digest_methods[SSL_MD_MD5_IDX]= | |
187 | EVP_get_digestbyname(SN_md5); | |
d02b48c6 RE |
188 | ssl_digest_methods[SSL_MD_SHA1_IDX]= |
189 | EVP_get_digestbyname(SN_sha1); | |
190 | } | |
191 | ||
7ba666fa RL |
192 | static int sk_comp_cmp(const SSL_COMP * const *a, |
193 | const SSL_COMP * const *b) | |
194 | { | |
195 | return((*a)->id-(*b)->id); | |
196 | } | |
197 | ||
198 | static void load_builtin_compressions(void) | |
199 | { | |
f70ddce7 RL |
200 | if (ssl_comp_methods != NULL) |
201 | return; | |
202 | ||
203 | CRYPTO_w_lock(CRYPTO_LOCK_SSL); | |
7ba666fa RL |
204 | if (ssl_comp_methods == NULL) |
205 | { | |
206 | SSL_COMP *comp = NULL; | |
207 | ||
208 | MemCheck_off(); | |
209 | ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp); | |
210 | if (ssl_comp_methods != NULL) | |
211 | { | |
212 | comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); | |
213 | if (comp != NULL) | |
214 | { | |
215 | comp->method=COMP_zlib(); | |
216 | if (comp->method | |
217 | && comp->method->type == NID_undef) | |
218 | OPENSSL_free(comp); | |
219 | else | |
220 | { | |
221 | comp->id=SSL_COMP_ZLIB_IDX; | |
222 | comp->name=comp->method->name; | |
223 | sk_SSL_COMP_push(ssl_comp_methods,comp); | |
224 | } | |
225 | } | |
226 | } | |
227 | MemCheck_on(); | |
228 | } | |
f70ddce7 | 229 | CRYPTO_w_unlock(CRYPTO_LOCK_SSL); |
7ba666fa RL |
230 | } |
231 | ||
6b691a5c UM |
232 | int ssl_cipher_get_evp(SSL_SESSION *s, const EVP_CIPHER **enc, |
233 | const EVP_MD **md, SSL_COMP **comp) | |
d02b48c6 RE |
234 | { |
235 | int i; | |
413c4f45 | 236 | SSL_CIPHER *c; |
d02b48c6 | 237 | |
413c4f45 | 238 | c=s->cipher; |
d02b48c6 | 239 | if (c == NULL) return(0); |
413c4f45 MC |
240 | if (comp != NULL) |
241 | { | |
242 | SSL_COMP ctmp; | |
243 | ||
7ba666fa | 244 | load_builtin_compressions(); |
413c4f45 | 245 | |
7ba666fa RL |
246 | *comp=NULL; |
247 | ctmp.id=s->compress_meth; | |
248 | if (ssl_comp_methods != NULL) | |
249 | { | |
f73e07cf | 250 | i=sk_SSL_COMP_find(ssl_comp_methods,&ctmp); |
413c4f45 | 251 | if (i >= 0) |
f73e07cf | 252 | *comp=sk_SSL_COMP_value(ssl_comp_methods,i); |
413c4f45 MC |
253 | else |
254 | *comp=NULL; | |
255 | } | |
256 | } | |
257 | ||
258 | if ((enc == NULL) || (md == NULL)) return(0); | |
d02b48c6 RE |
259 | |
260 | switch (c->algorithms & SSL_ENC_MASK) | |
261 | { | |
262 | case SSL_DES: | |
263 | i=SSL_ENC_DES_IDX; | |
264 | break; | |
265 | case SSL_3DES: | |
266 | i=SSL_ENC_3DES_IDX; | |
267 | break; | |
268 | case SSL_RC4: | |
269 | i=SSL_ENC_RC4_IDX; | |
270 | break; | |
271 | case SSL_RC2: | |
272 | i=SSL_ENC_RC2_IDX; | |
273 | break; | |
274 | case SSL_IDEA: | |
275 | i=SSL_ENC_IDEA_IDX; | |
276 | break; | |
277 | case SSL_eNULL: | |
278 | i=SSL_ENC_NULL_IDX; | |
279 | break; | |
deb2c1a1 | 280 | case SSL_AES: |
259810e0 BL |
281 | switch(c->alg_bits) |
282 | { | |
deb2c1a1 DSH |
283 | case 128: i=SSL_ENC_AES128_IDX; break; |
284 | case 256: i=SSL_ENC_AES256_IDX; break; | |
259810e0 BL |
285 | default: i=-1; break; |
286 | } | |
287 | break; | |
d02b48c6 RE |
288 | default: |
289 | i= -1; | |
290 | break; | |
291 | } | |
292 | ||
293 | if ((i < 0) || (i > SSL_ENC_NUM_IDX)) | |
294 | *enc=NULL; | |
295 | else | |
296 | { | |
297 | if (i == SSL_ENC_NULL_IDX) | |
298 | *enc=EVP_enc_null(); | |
299 | else | |
300 | *enc=ssl_cipher_methods[i]; | |
301 | } | |
302 | ||
303 | switch (c->algorithms & SSL_MAC_MASK) | |
304 | { | |
305 | case SSL_MD5: | |
306 | i=SSL_MD_MD5_IDX; | |
307 | break; | |
d02b48c6 RE |
308 | case SSL_SHA1: |
309 | i=SSL_MD_SHA1_IDX; | |
310 | break; | |
311 | default: | |
312 | i= -1; | |
313 | break; | |
314 | } | |
315 | if ((i < 0) || (i > SSL_MD_NUM_IDX)) | |
316 | *md=NULL; | |
317 | else | |
318 | *md=ssl_digest_methods[i]; | |
319 | ||
320 | if ((*enc != NULL) && (*md != NULL)) | |
321 | return(1); | |
322 | else | |
323 | return(0); | |
324 | } | |
325 | ||
58964a49 RE |
326 | #define ITEM_SEP(a) \ |
327 | (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) | |
328 | ||
6b691a5c UM |
329 | static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, |
330 | CIPHER_ORDER **tail) | |
58964a49 RE |
331 | { |
332 | if (curr == *tail) return; | |
333 | if (curr == *head) | |
334 | *head=curr->next; | |
335 | if (curr->prev != NULL) | |
336 | curr->prev->next=curr->next; | |
337 | if (curr->next != NULL) /* should always be true */ | |
338 | curr->next->prev=curr->prev; | |
339 | (*tail)->next=curr; | |
340 | curr->prev= *tail; | |
341 | curr->next=NULL; | |
342 | *tail=curr; | |
343 | } | |
344 | ||
018e57c7 | 345 | static unsigned long ssl_cipher_get_disabled(void) |
d02b48c6 | 346 | { |
018e57c7 | 347 | unsigned long mask; |
d02b48c6 | 348 | |
018e57c7 | 349 | mask = SSL_kFZA; |
bc36ee62 | 350 | #ifdef OPENSSL_NO_RSA |
018e57c7 | 351 | mask |= SSL_aRSA|SSL_kRSA; |
d02b48c6 | 352 | #endif |
bc36ee62 | 353 | #ifdef OPENSSL_NO_DSA |
018e57c7 | 354 | mask |= SSL_aDSS; |
d02b48c6 | 355 | #endif |
bc36ee62 | 356 | #ifdef OPENSSL_NO_DH |
018e57c7 | 357 | mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH; |
d02b48c6 | 358 | #endif |
bc36ee62 | 359 | #ifdef OPENSSL_NO_KRB5 |
f9b3bff6 RL |
360 | mask |= SSL_kKRB5|SSL_aKRB5; |
361 | #endif | |
ea262260 BM |
362 | #ifdef OPENSSL_NO_ECDH |
363 | mask |= SSL_kECDH|SSL_kECDHE; | |
364 | #endif | |
988788f6 | 365 | #ifdef SSL_FORBID_ENULL |
018e57c7 | 366 | mask |= SSL_eNULL; |
d02b48c6 RE |
367 | #endif |
368 | ||
018e57c7 DSH |
369 | mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0; |
370 | mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0; | |
371 | mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0; | |
372 | mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0; | |
373 | mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0; | |
374 | mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0; | |
deb2c1a1 | 375 | mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0; |
d02b48c6 | 376 | |
018e57c7 DSH |
377 | mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0; |
378 | mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0; | |
d02b48c6 | 379 | |
018e57c7 DSH |
380 | return(mask); |
381 | } | |
382 | ||
383 | static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, | |
384 | int num_of_ciphers, unsigned long mask, CIPHER_ORDER *list, | |
385 | CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) | |
386 | { | |
82fc1d9c | 387 | int i, list_num; |
018e57c7 DSH |
388 | SSL_CIPHER *c; |
389 | ||
390 | /* | |
391 | * We have num_of_ciphers descriptions compiled in, depending on the | |
392 | * method selected (SSLv2 and/or SSLv3, TLSv1 etc). | |
393 | * These will later be sorted in a linked list with at most num | |
394 | * entries. | |
395 | */ | |
58964a49 | 396 | |
d02b48c6 | 397 | /* Get the initial list of ciphers */ |
018e57c7 DSH |
398 | list_num = 0; /* actual count of ciphers */ |
399 | for (i = 0; i < num_of_ciphers; i++) | |
d02b48c6 | 400 | { |
018e57c7 | 401 | c = ssl_method->get_cipher(i); |
d02b48c6 RE |
402 | /* drop those that use any of that is not available */ |
403 | if ((c != NULL) && c->valid && !(c->algorithms & mask)) | |
404 | { | |
018e57c7 DSH |
405 | list[list_num].cipher = c; |
406 | list[list_num].next = NULL; | |
407 | list[list_num].prev = NULL; | |
408 | list[list_num].active = 0; | |
58964a49 | 409 | list_num++; |
f9b3bff6 RL |
410 | #ifdef KSSL_DEBUG |
411 | printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms); | |
412 | #endif /* KSSL_DEBUG */ | |
018e57c7 | 413 | /* |
d02b48c6 | 414 | if (!sk_push(ca_list,(char *)c)) goto err; |
018e57c7 | 415 | */ |
d02b48c6 RE |
416 | } |
417 | } | |
018e57c7 DSH |
418 | |
419 | /* | |
420 | * Prepare linked list from list entries | |
421 | */ | |
422 | for (i = 1; i < list_num - 1; i++) | |
58964a49 | 423 | { |
018e57c7 DSH |
424 | list[i].prev = &(list[i-1]); |
425 | list[i].next = &(list[i+1]); | |
58964a49 RE |
426 | } |
427 | if (list_num > 0) | |
428 | { | |
018e57c7 DSH |
429 | (*head_p) = &(list[0]); |
430 | (*head_p)->prev = NULL; | |
431 | (*head_p)->next = &(list[1]); | |
432 | (*tail_p) = &(list[list_num - 1]); | |
433 | (*tail_p)->prev = &(list[list_num - 2]); | |
434 | (*tail_p)->next = NULL; | |
58964a49 | 435 | } |
018e57c7 | 436 | } |
d02b48c6 | 437 | |
018e57c7 DSH |
438 | static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, |
439 | int num_of_group_aliases, unsigned long mask, | |
440 | CIPHER_ORDER *head) | |
441 | { | |
442 | CIPHER_ORDER *ciph_curr; | |
443 | SSL_CIPHER **ca_curr; | |
444 | int i; | |
d02b48c6 | 445 | |
018e57c7 DSH |
446 | /* |
447 | * First, add the real ciphers as already collected | |
448 | */ | |
449 | ciph_curr = head; | |
450 | ca_curr = ca_list; | |
451 | while (ciph_curr != NULL) | |
d02b48c6 | 452 | { |
018e57c7 DSH |
453 | *ca_curr = ciph_curr->cipher; |
454 | ca_curr++; | |
455 | ciph_curr = ciph_curr->next; | |
d02b48c6 RE |
456 | } |
457 | ||
018e57c7 DSH |
458 | /* |
459 | * Now we add the available ones from the cipher_aliases[] table. | |
460 | * They represent either an algorithm, that must be fully | |
461 | * supported (not match any bit in mask) or represent a cipher | |
462 | * strength value (will be added in any case because algorithms=0). | |
463 | */ | |
464 | for (i = 0; i < num_of_group_aliases; i++) | |
465 | { | |
466 | if ((i == 0) || /* always fetch "ALL" */ | |
467 | !(cipher_aliases[i].algorithms & mask)) | |
468 | { | |
469 | *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); | |
470 | ca_curr++; | |
471 | } | |
472 | } | |
d02b48c6 | 473 | |
018e57c7 DSH |
474 | *ca_curr = NULL; /* end of list */ |
475 | } | |
d02b48c6 | 476 | |
018e57c7 DSH |
477 | static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask, |
478 | unsigned long algo_strength, unsigned long mask_strength, | |
479 | int rule, int strength_bits, CIPHER_ORDER *list, | |
480 | CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) | |
481 | { | |
482 | CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; | |
483 | SSL_CIPHER *cp; | |
484 | unsigned long ma, ma_s; | |
485 | ||
486 | #ifdef CIPHER_DEBUG | |
487 | printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", | |
488 | rule, algorithms, mask, algo_strength, mask_strength, | |
489 | strength_bits); | |
490 | #endif | |
d02b48c6 | 491 | |
018e57c7 DSH |
492 | curr = head = *head_p; |
493 | curr2 = head; | |
494 | tail2 = tail = *tail_p; | |
d02b48c6 RE |
495 | for (;;) |
496 | { | |
018e57c7 DSH |
497 | if ((curr == NULL) || (curr == tail2)) break; |
498 | curr = curr2; | |
499 | curr2 = curr->next; | |
500 | ||
501 | cp = curr->cipher; | |
502 | ||
503 | /* | |
504 | * Selection criteria is either the number of strength_bits | |
505 | * or the algorithm used. | |
506 | */ | |
507 | if (strength_bits == -1) | |
508 | { | |
509 | ma = mask & cp->algorithms; | |
510 | ma_s = mask_strength & cp->algo_strength; | |
511 | ||
512 | #ifdef CIPHER_DEBUG | |
513 | printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength); | |
514 | printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength); | |
515 | #endif | |
516 | /* | |
517 | * Select: if none of the mask bit was met from the | |
518 | * cipher or not all of the bits were met, the | |
519 | * selection does not apply. | |
520 | */ | |
521 | if (((ma == 0) && (ma_s == 0)) || | |
522 | ((ma & algorithms) != ma) || | |
523 | ((ma_s & algo_strength) != ma_s)) | |
524 | continue; /* does not apply */ | |
525 | } | |
526 | else if (strength_bits != cp->strength_bits) | |
527 | continue; /* does not apply */ | |
528 | ||
529 | #ifdef CIPHER_DEBUG | |
530 | printf("Action = %d\n", rule); | |
531 | #endif | |
532 | ||
533 | /* add the cipher if it has not been added yet. */ | |
534 | if (rule == CIPHER_ADD) | |
535 | { | |
536 | if (!curr->active) | |
537 | { | |
538 | ll_append_tail(&head, curr, &tail); | |
539 | curr->active = 1; | |
540 | } | |
541 | } | |
542 | /* Move the added cipher to this location */ | |
543 | else if (rule == CIPHER_ORD) | |
544 | { | |
545 | if (curr->active) | |
546 | { | |
547 | ll_append_tail(&head, curr, &tail); | |
548 | } | |
549 | } | |
550 | else if (rule == CIPHER_DEL) | |
551 | curr->active = 0; | |
552 | else if (rule == CIPHER_KILL) | |
553 | { | |
554 | if (head == curr) | |
555 | head = curr->next; | |
556 | else | |
557 | curr->prev->next = curr->next; | |
558 | if (tail == curr) | |
559 | tail = curr->prev; | |
560 | curr->active = 0; | |
561 | if (curr->next != NULL) | |
562 | curr->next->prev = curr->prev; | |
563 | if (curr->prev != NULL) | |
564 | curr->prev->next = curr->next; | |
565 | curr->next = NULL; | |
566 | curr->prev = NULL; | |
567 | } | |
568 | } | |
569 | ||
570 | *head_p = head; | |
571 | *tail_p = tail; | |
572 | } | |
573 | ||
574 | static int ssl_cipher_strength_sort(CIPHER_ORDER *list, CIPHER_ORDER **head_p, | |
575 | CIPHER_ORDER **tail_p) | |
576 | { | |
577 | int max_strength_bits, i, *number_uses; | |
578 | CIPHER_ORDER *curr; | |
579 | ||
580 | /* | |
581 | * This routine sorts the ciphers with descending strength. The sorting | |
582 | * must keep the pre-sorted sequence, so we apply the normal sorting | |
583 | * routine as '+' movement to the end of the list. | |
584 | */ | |
585 | max_strength_bits = 0; | |
586 | curr = *head_p; | |
587 | while (curr != NULL) | |
588 | { | |
589 | if (curr->active && | |
590 | (curr->cipher->strength_bits > max_strength_bits)) | |
591 | max_strength_bits = curr->cipher->strength_bits; | |
592 | curr = curr->next; | |
593 | } | |
594 | ||
26a3a48d | 595 | number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); |
018e57c7 DSH |
596 | if (!number_uses) |
597 | { | |
598 | SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); | |
599 | return(0); | |
600 | } | |
601 | memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); | |
602 | ||
603 | /* | |
604 | * Now find the strength_bits values actually used | |
605 | */ | |
606 | curr = *head_p; | |
607 | while (curr != NULL) | |
608 | { | |
609 | if (curr->active) | |
610 | number_uses[curr->cipher->strength_bits]++; | |
611 | curr = curr->next; | |
612 | } | |
018e57c7 DSH |
613 | /* |
614 | * Go through the list of used strength_bits values in descending | |
64287002 | 615 | * order. |
018e57c7 | 616 | */ |
018e57c7 | 617 | for (i = max_strength_bits; i >= 0; i--) |
018e57c7 DSH |
618 | if (number_uses[i] > 0) |
619 | ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i, | |
620 | list, head_p, tail_p); | |
621 | ||
26a3a48d | 622 | OPENSSL_free(number_uses); |
018e57c7 DSH |
623 | return(1); |
624 | } | |
625 | ||
626 | static int ssl_cipher_process_rulestr(const char *rule_str, | |
627 | CIPHER_ORDER *list, CIPHER_ORDER **head_p, | |
628 | CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) | |
629 | { | |
630 | unsigned long algorithms, mask, algo_strength, mask_strength; | |
631 | const char *l, *start, *buf; | |
632 | int j, multi, found, rule, retval, ok, buflen; | |
633 | char ch; | |
58964a49 | 634 | |
018e57c7 DSH |
635 | retval = 1; |
636 | l = rule_str; | |
637 | for (;;) | |
638 | { | |
639 | ch = *l; | |
58964a49 | 640 | |
018e57c7 DSH |
641 | if (ch == '\0') |
642 | break; /* done */ | |
d02b48c6 | 643 | if (ch == '-') |
018e57c7 | 644 | { rule = CIPHER_DEL; l++; } |
d02b48c6 | 645 | else if (ch == '+') |
018e57c7 | 646 | { rule = CIPHER_ORD; l++; } |
d02b48c6 | 647 | else if (ch == '!') |
018e57c7 DSH |
648 | { rule = CIPHER_KILL; l++; } |
649 | else if (ch == '@') | |
650 | { rule = CIPHER_SPECIAL; l++; } | |
651 | else | |
652 | { rule = CIPHER_ADD; } | |
d02b48c6 | 653 | |
58964a49 | 654 | if (ITEM_SEP(ch)) |
d02b48c6 RE |
655 | { |
656 | l++; | |
657 | continue; | |
658 | } | |
018e57c7 DSH |
659 | |
660 | algorithms = mask = algo_strength = mask_strength = 0; | |
d02b48c6 RE |
661 | |
662 | start=l; | |
663 | for (;;) | |
664 | { | |
018e57c7 DSH |
665 | ch = *l; |
666 | buf = l; | |
667 | buflen = 0; | |
ca570cfd | 668 | #ifndef CHARSET_EBCDIC |
d02b48c6 RE |
669 | while ( ((ch >= 'A') && (ch <= 'Z')) || |
670 | ((ch >= '0') && (ch <= '9')) || | |
671 | ((ch >= 'a') && (ch <= 'z')) || | |
672 | (ch == '-')) | |
ca570cfd UM |
673 | #else |
674 | while ( isalnum(ch) || (ch == '-')) | |
675 | #endif | |
d02b48c6 | 676 | { |
018e57c7 DSH |
677 | ch = *(++l); |
678 | buflen++; | |
d02b48c6 | 679 | } |
018e57c7 DSH |
680 | |
681 | if (buflen == 0) | |
682 | { | |
683 | /* | |
4013f3bf | 684 | * We hit something we cannot deal with, |
657e60fa | 685 | * it is no command or separator nor |
018e57c7 DSH |
686 | * alphanumeric, so we call this an error. |
687 | */ | |
688 | SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, | |
689 | SSL_R_INVALID_COMMAND); | |
690 | retval = found = 0; | |
691 | l++; | |
692 | break; | |
693 | } | |
694 | ||
695 | if (rule == CIPHER_SPECIAL) | |
696 | { | |
4013f3bf | 697 | found = 0; /* unused -- avoid compiler warning */ |
018e57c7 DSH |
698 | break; /* special treatment */ |
699 | } | |
d02b48c6 RE |
700 | |
701 | /* check for multi-part specification */ | |
58964a49 RE |
702 | if (ch == '+') |
703 | { | |
704 | multi=1; | |
705 | l++; | |
706 | } | |
707 | else | |
708 | multi=0; | |
d02b48c6 | 709 | |
018e57c7 | 710 | /* |
4013f3bf | 711 | * Now search for the cipher alias in the ca_list. Be careful |
018e57c7 DSH |
712 | * with the strncmp, because the "buflen" limitation |
713 | * will make the rule "ADH:SOME" and the cipher | |
714 | * "ADH-MY-CIPHER" look like a match for buflen=3. | |
4013f3bf BM |
715 | * So additionally check whether the cipher name found |
716 | * has the correct length. We can save a strlen() call: | |
018e57c7 | 717 | * just checking for the '\0' at the right place is |
f65a7578 LJ |
718 | * sufficient, we have to strncmp() anyway. (We cannot |
719 | * use strcmp(), because buf is not '\0' terminated.) | |
018e57c7 DSH |
720 | */ |
721 | j = found = 0; | |
722 | while (ca_list[j]) | |
723 | { | |
f65a7578 LJ |
724 | if (!strncmp(buf, ca_list[j]->name, buflen) && |
725 | (ca_list[j]->name[buflen] == '\0')) | |
018e57c7 DSH |
726 | { |
727 | found = 1; | |
728 | break; | |
729 | } | |
730 | else | |
731 | j++; | |
732 | } | |
733 | if (!found) | |
734 | break; /* ignore this entry */ | |
735 | ||
736 | algorithms |= ca_list[j]->algorithms; | |
737 | mask |= ca_list[j]->mask; | |
738 | algo_strength |= ca_list[j]->algo_strength; | |
739 | mask_strength |= ca_list[j]->mask_strength; | |
d02b48c6 | 740 | |
d02b48c6 RE |
741 | if (!multi) break; |
742 | } | |
018e57c7 | 743 | |
4013f3bf BM |
744 | /* |
745 | * Ok, we have the rule, now apply it | |
746 | */ | |
747 | if (rule == CIPHER_SPECIAL) | |
748 | { /* special command */ | |
749 | ok = 0; | |
750 | if ((buflen == 8) && | |
751 | !strncmp(buf, "STRENGTH", 8)) | |
752 | ok = ssl_cipher_strength_sort(list, | |
753 | head_p, tail_p); | |
754 | else | |
755 | SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, | |
756 | SSL_R_INVALID_COMMAND); | |
757 | if (ok == 0) | |
758 | retval = 0; | |
018e57c7 | 759 | /* |
4013f3bf BM |
760 | * We do not support any "multi" options |
761 | * together with "@", so throw away the | |
762 | * rest of the command, if any left, until | |
763 | * end or ':' is found. | |
018e57c7 | 764 | */ |
4013f3bf BM |
765 | while ((*l != '\0') && ITEM_SEP(*l)) |
766 | l++; | |
767 | } | |
768 | else if (found) | |
769 | { | |
770 | ssl_cipher_apply_rule(algorithms, mask, | |
771 | algo_strength, mask_strength, rule, -1, | |
772 | list, head_p, tail_p); | |
773 | } | |
774 | else | |
775 | { | |
776 | while ((*l != '\0') && ITEM_SEP(*l)) | |
777 | l++; | |
778 | } | |
779 | if (*l == '\0') break; /* done */ | |
d02b48c6 RE |
780 | } |
781 | ||
018e57c7 DSH |
782 | return(retval); |
783 | } | |
784 | ||
785 | STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, | |
786 | STACK_OF(SSL_CIPHER) **cipher_list, | |
787 | STACK_OF(SSL_CIPHER) **cipher_list_by_id, | |
788 | const char *rule_str) | |
789 | { | |
790 | int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; | |
791 | unsigned long disabled_mask; | |
792 | STACK_OF(SSL_CIPHER) *cipherstack; | |
793 | const char *rule_p; | |
794 | CIPHER_ORDER *list = NULL, *head = NULL, *tail = NULL, *curr; | |
795 | SSL_CIPHER **ca_list = NULL; | |
796 | ||
797 | /* | |
798 | * Return with error if nothing to do. | |
799 | */ | |
800 | if (rule_str == NULL) return(NULL); | |
801 | ||
f70ddce7 RL |
802 | if (init_ciphers) |
803 | { | |
804 | CRYPTO_w_lock(CRYPTO_LOCK_SSL); | |
805 | if (init_ciphers) load_ciphers(); | |
806 | CRYPTO_w_unlock(CRYPTO_LOCK_SSL); | |
807 | } | |
d02b48c6 | 808 | |
018e57c7 DSH |
809 | /* |
810 | * To reduce the work to do we only want to process the compiled | |
811 | * in algorithms, so we first get the mask of disabled ciphers. | |
812 | */ | |
813 | disabled_mask = ssl_cipher_get_disabled(); | |
814 | ||
815 | /* | |
816 | * Now we have to collect the available ciphers from the compiled | |
817 | * in ciphers. We cannot get more than the number compiled in, so | |
818 | * it is used for allocation. | |
819 | */ | |
820 | num_of_ciphers = ssl_method->num_ciphers(); | |
f9b3bff6 RL |
821 | #ifdef KSSL_DEBUG |
822 | printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers); | |
823 | #endif /* KSSL_DEBUG */ | |
26a3a48d | 824 | list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); |
018e57c7 | 825 | if (list == NULL) |
d02b48c6 | 826 | { |
018e57c7 DSH |
827 | SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); |
828 | return(NULL); /* Failure */ | |
829 | } | |
58964a49 | 830 | |
018e57c7 DSH |
831 | ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask, |
832 | list, &head, &tail); | |
833 | ||
834 | /* | |
835 | * We also need cipher aliases for selecting based on the rule_str. | |
836 | * There might be two types of entries in the rule_str: 1) names | |
837 | * of ciphers themselves 2) aliases for groups of ciphers. | |
838 | * For 1) we need the available ciphers and for 2) the cipher | |
657e60fa | 839 | * groups of cipher_aliases added together in one list (otherwise |
018e57c7 DSH |
840 | * we would be happy with just the cipher_aliases table). |
841 | */ | |
842 | num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); | |
843 | num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; | |
844 | ca_list = | |
26a3a48d | 845 | (SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); |
018e57c7 DSH |
846 | if (ca_list == NULL) |
847 | { | |
26a3a48d | 848 | OPENSSL_free(list); |
018e57c7 DSH |
849 | SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE); |
850 | return(NULL); /* Failure */ | |
851 | } | |
852 | ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask, | |
853 | head); | |
854 | ||
855 | /* | |
856 | * If the rule_string begins with DEFAULT, apply the default rule | |
857 | * before using the (possibly available) additional rules. | |
858 | */ | |
859 | ok = 1; | |
860 | rule_p = rule_str; | |
861 | if (strncmp(rule_str,"DEFAULT",7) == 0) | |
862 | { | |
863 | ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, | |
864 | list, &head, &tail, ca_list); | |
865 | rule_p += 7; | |
866 | if (*rule_p == ':') | |
867 | rule_p++; | |
868 | } | |
58964a49 | 869 | |
018e57c7 DSH |
870 | if (ok && (strlen(rule_p) > 0)) |
871 | ok = ssl_cipher_process_rulestr(rule_p, list, &head, &tail, | |
872 | ca_list); | |
d02b48c6 | 873 | |
26a3a48d | 874 | OPENSSL_free(ca_list); /* Not needed anymore */ |
018e57c7 DSH |
875 | |
876 | if (!ok) | |
877 | { /* Rule processing failure */ | |
26a3a48d | 878 | OPENSSL_free(list); |
018e57c7 DSH |
879 | return(NULL); |
880 | } | |
881 | /* | |
882 | * Allocate new "cipherstack" for the result, return with error | |
883 | * if we cannot get one. | |
884 | */ | |
62324627 | 885 | if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) |
018e57c7 | 886 | { |
26a3a48d | 887 | OPENSSL_free(list); |
018e57c7 | 888 | return(NULL); |
d02b48c6 RE |
889 | } |
890 | ||
018e57c7 DSH |
891 | /* |
892 | * The cipher selection for the list is done. The ciphers are added | |
893 | * to the resulting precedence to the STACK_OF(SSL_CIPHER). | |
894 | */ | |
895 | for (curr = head; curr != NULL; curr = curr->next) | |
d02b48c6 | 896 | { |
58964a49 | 897 | if (curr->active) |
d02b48c6 | 898 | { |
018e57c7 | 899 | sk_SSL_CIPHER_push(cipherstack, curr->cipher); |
d02b48c6 | 900 | #ifdef CIPHER_DEBUG |
58964a49 | 901 | printf("<%s>\n",curr->cipher->name); |
d02b48c6 | 902 | #endif |
d02b48c6 RE |
903 | } |
904 | } | |
26a3a48d | 905 | OPENSSL_free(list); /* Not needed any longer */ |
018e57c7 DSH |
906 | |
907 | /* | |
908 | * The following passage is a little bit odd. If pointer variables | |
909 | * were supplied to hold STACK_OF(SSL_CIPHER) return information, | |
910 | * the old memory pointed to is free()ed. Then, however, the | |
911 | * cipher_list entry will be assigned just a copy of the returned | |
912 | * cipher stack. For cipher_list_by_id a copy of the cipher stack | |
913 | * will be created. See next comment... | |
914 | */ | |
d02b48c6 RE |
915 | if (cipher_list != NULL) |
916 | { | |
917 | if (*cipher_list != NULL) | |
f73e07cf | 918 | sk_SSL_CIPHER_free(*cipher_list); |
018e57c7 | 919 | *cipher_list = cipherstack; |
d02b48c6 RE |
920 | } |
921 | ||
922 | if (cipher_list_by_id != NULL) | |
923 | { | |
924 | if (*cipher_list_by_id != NULL) | |
f73e07cf | 925 | sk_SSL_CIPHER_free(*cipher_list_by_id); |
018e57c7 | 926 | *cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack); |
d02b48c6 RE |
927 | } |
928 | ||
018e57c7 DSH |
929 | /* |
930 | * Now it is getting really strange. If something failed during | |
657e60fa | 931 | * the previous pointer assignment or if one of the pointers was |
018e57c7 DSH |
932 | * not requested, the error condition is met. That might be |
933 | * discussable. The strange thing is however that in this case | |
934 | * the memory "ret" pointed to is "free()ed" and hence the pointer | |
935 | * cipher_list becomes wild. The memory reserved for | |
936 | * cipher_list_by_id however is not "free()ed" and stays intact. | |
937 | */ | |
d02b48c6 RE |
938 | if ( (cipher_list_by_id == NULL) || |
939 | (*cipher_list_by_id == NULL) || | |
940 | (cipher_list == NULL) || | |
941 | (*cipher_list == NULL)) | |
018e57c7 DSH |
942 | { |
943 | sk_SSL_CIPHER_free(cipherstack); | |
944 | return(NULL); | |
945 | } | |
946 | ||
f73e07cf | 947 | sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp); |
d02b48c6 | 948 | |
018e57c7 | 949 | return(cipherstack); |
d02b48c6 RE |
950 | } |
951 | ||
6b691a5c | 952 | char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len) |
d02b48c6 | 953 | { |
b1c4fe36 | 954 | int is_export,pkl,kl; |
d02b48c6 RE |
955 | char *ver,*exp; |
956 | char *kx,*au,*enc,*mac; | |
018e57c7 | 957 | unsigned long alg,alg2,alg_s; |
f9b3bff6 RL |
958 | #ifdef KSSL_DEBUG |
959 | static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n"; | |
960 | #else | |
d02b48c6 | 961 | static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; |
f9b3bff6 RL |
962 | #endif /* KSSL_DEBUG */ |
963 | ||
d02b48c6 | 964 | alg=cipher->algorithms; |
018e57c7 | 965 | alg_s=cipher->algo_strength; |
d02b48c6 RE |
966 | alg2=cipher->algorithm2; |
967 | ||
018e57c7 DSH |
968 | is_export=SSL_C_IS_EXPORT(cipher); |
969 | pkl=SSL_C_EXPORT_PKEYLENGTH(cipher); | |
970 | kl=SSL_C_EXPORT_KEYLENGTH(cipher); | |
b1c4fe36 | 971 | exp=is_export?" export":""; |
ea262260 | 972 | |
d02b48c6 RE |
973 | if (alg & SSL_SSLV2) |
974 | ver="SSLv2"; | |
975 | else if (alg & SSL_SSLV3) | |
976 | ver="SSLv3"; | |
977 | else | |
978 | ver="unknown"; | |
979 | ||
980 | switch (alg&SSL_MKEY_MASK) | |
981 | { | |
982 | case SSL_kRSA: | |
b1c4fe36 | 983 | kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA"; |
d02b48c6 RE |
984 | break; |
985 | case SSL_kDHr: | |
986 | kx="DH/RSA"; | |
987 | break; | |
988 | case SSL_kDHd: | |
989 | kx="DH/DSS"; | |
990 | break; | |
f9b3bff6 RL |
991 | case SSL_kKRB5: /* VRS */ |
992 | case SSL_KRB5: /* VRS */ | |
993 | kx="KRB5"; | |
994 | break; | |
d02b48c6 RE |
995 | case SSL_kFZA: |
996 | kx="Fortezza"; | |
997 | break; | |
998 | case SSL_kEDH: | |
b1c4fe36 | 999 | kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH"; |
d02b48c6 | 1000 | break; |
ea262260 BM |
1001 | case SSL_kECDH: |
1002 | case SSL_kECDHE: | |
1003 | kx=is_export?"ECDH(<=163)":"ECDH"; | |
1004 | break; | |
d02b48c6 RE |
1005 | default: |
1006 | kx="unknown"; | |
1007 | } | |
1008 | ||
1009 | switch (alg&SSL_AUTH_MASK) | |
1010 | { | |
1011 | case SSL_aRSA: | |
1012 | au="RSA"; | |
1013 | break; | |
1014 | case SSL_aDSS: | |
1015 | au="DSS"; | |
1016 | break; | |
1017 | case SSL_aDH: | |
1018 | au="DH"; | |
1019 | break; | |
f9b3bff6 RL |
1020 | case SSL_aKRB5: /* VRS */ |
1021 | case SSL_KRB5: /* VRS */ | |
1022 | au="KRB5"; | |
1023 | break; | |
d02b48c6 RE |
1024 | case SSL_aFZA: |
1025 | case SSL_aNULL: | |
1026 | au="None"; | |
1027 | break; | |
ea262260 BM |
1028 | case SSL_aECDSA: |
1029 | au="ECDSA"; | |
1030 | break; | |
d02b48c6 RE |
1031 | default: |
1032 | au="unknown"; | |
1033 | break; | |
1034 | } | |
1035 | ||
1036 | switch (alg&SSL_ENC_MASK) | |
1037 | { | |
1038 | case SSL_DES: | |
b1c4fe36 | 1039 | enc=(is_export && kl == 5)?"DES(40)":"DES(56)"; |
d02b48c6 RE |
1040 | break; |
1041 | case SSL_3DES: | |
1042 | enc="3DES(168)"; | |
1043 | break; | |
1044 | case SSL_RC4: | |
b1c4fe36 | 1045 | enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)") |
06ab81f9 | 1046 | :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)"); |
d02b48c6 RE |
1047 | break; |
1048 | case SSL_RC2: | |
b1c4fe36 | 1049 | enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)"; |
d02b48c6 RE |
1050 | break; |
1051 | case SSL_IDEA: | |
1052 | enc="IDEA(128)"; | |
1053 | break; | |
1054 | case SSL_eFZA: | |
1055 | enc="Fortezza"; | |
1056 | break; | |
1057 | case SSL_eNULL: | |
1058 | enc="None"; | |
1059 | break; | |
deb2c1a1 DSH |
1060 | case SSL_AES: |
1061 | switch(cipher->strength_bits) | |
259810e0 | 1062 | { |
ea4f109c BM |
1063 | case 128: enc="AES(128)"; break; |
1064 | case 192: enc="AES(192)"; break; | |
1065 | case 256: enc="AES(256)"; break; | |
1066 | default: enc="AES(?""?""?)"; break; | |
259810e0 BL |
1067 | } |
1068 | break; | |
d02b48c6 RE |
1069 | default: |
1070 | enc="unknown"; | |
1071 | break; | |
1072 | } | |
1073 | ||
1074 | switch (alg&SSL_MAC_MASK) | |
1075 | { | |
1076 | case SSL_MD5: | |
1077 | mac="MD5"; | |
1078 | break; | |
d02b48c6 RE |
1079 | case SSL_SHA1: |
1080 | mac="SHA1"; | |
1081 | break; | |
1082 | default: | |
1083 | mac="unknown"; | |
1084 | break; | |
1085 | } | |
1086 | ||
1087 | if (buf == NULL) | |
1088 | { | |
063c0502 | 1089 | len=128; |
26a3a48d RL |
1090 | buf=OPENSSL_malloc(len); |
1091 | if (buf == NULL) return("OPENSSL_malloc Error"); | |
d02b48c6 RE |
1092 | } |
1093 | else if (len < 128) | |
1094 | return("Buffer too small"); | |
1095 | ||
f9b3bff6 RL |
1096 | #ifdef KSSL_DEBUG |
1097 | BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp,alg); | |
1098 | #else | |
063c0502 | 1099 | BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp); |
f9b3bff6 | 1100 | #endif /* KSSL_DEBUG */ |
d02b48c6 RE |
1101 | return(buf); |
1102 | } | |
1103 | ||
6b691a5c | 1104 | char *SSL_CIPHER_get_version(SSL_CIPHER *c) |
d02b48c6 RE |
1105 | { |
1106 | int i; | |
1107 | ||
58964a49 | 1108 | if (c == NULL) return("(NONE)"); |
d02b48c6 RE |
1109 | i=(int)(c->id>>24L); |
1110 | if (i == 3) | |
58964a49 | 1111 | return("TLSv1/SSLv3"); |
d02b48c6 RE |
1112 | else if (i == 2) |
1113 | return("SSLv2"); | |
1114 | else | |
1115 | return("unknown"); | |
1116 | } | |
1117 | ||
1118 | /* return the actual cipher being used */ | |
6b691a5c | 1119 | const char *SSL_CIPHER_get_name(SSL_CIPHER *c) |
d02b48c6 RE |
1120 | { |
1121 | if (c != NULL) | |
1122 | return(c->name); | |
1123 | return("(NONE)"); | |
1124 | } | |
1125 | ||
657e60fa | 1126 | /* number of bits for symmetric cipher */ |
6b691a5c | 1127 | int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits) |
d02b48c6 | 1128 | { |
018e57c7 | 1129 | int ret=0; |
d02b48c6 RE |
1130 | |
1131 | if (c != NULL) | |
1132 | { | |
018e57c7 DSH |
1133 | if (alg_bits != NULL) *alg_bits = c->alg_bits; |
1134 | ret = c->strength_bits; | |
d02b48c6 | 1135 | } |
d02b48c6 RE |
1136 | return(ret); |
1137 | } | |
1138 | ||
6b691a5c | 1139 | SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) |
413c4f45 MC |
1140 | { |
1141 | SSL_COMP *ctmp; | |
1142 | int i,nn; | |
1143 | ||
1144 | if ((n == 0) || (sk == NULL)) return(NULL); | |
f73e07cf | 1145 | nn=sk_SSL_COMP_num(sk); |
413c4f45 MC |
1146 | for (i=0; i<nn; i++) |
1147 | { | |
f73e07cf | 1148 | ctmp=sk_SSL_COMP_value(sk,i); |
413c4f45 MC |
1149 | if (ctmp->id == n) |
1150 | return(ctmp); | |
1151 | } | |
1152 | return(NULL); | |
1153 | } | |
1154 | ||
6b691a5c | 1155 | STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) |
413c4f45 | 1156 | { |
7ba666fa | 1157 | load_builtin_compressions(); |
413c4f45 MC |
1158 | return(ssl_comp_methods); |
1159 | } | |
1160 | ||
6b691a5c | 1161 | int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) |
413c4f45 MC |
1162 | { |
1163 | SSL_COMP *comp; | |
413c4f45 | 1164 | |
9f495243 RL |
1165 | if (cm == NULL || cm->type == NID_undef) |
1166 | return 1; | |
1167 | ||
7ba666fa RL |
1168 | /* According to draft-ietf-tls-compression-04.txt, the |
1169 | compression number ranges should be the following: | |
1170 | ||
1171 | 0 to 63: methods defined by the IETF | |
1172 | 64 to 192: external party methods assigned by IANA | |
1173 | 193 to 255: reserved for private use */ | |
1174 | if (id < 193 || id > 255) | |
1175 | { | |
1176 | SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); | |
1177 | return 0; | |
1178 | } | |
1179 | ||
058123af | 1180 | MemCheck_off(); |
26a3a48d | 1181 | comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); |
413c4f45 MC |
1182 | comp->id=id; |
1183 | comp->method=cm; | |
7ba666fa | 1184 | load_builtin_compressions(); |
82423549 RL |
1185 | if (ssl_comp_methods |
1186 | && !sk_SSL_COMP_find(ssl_comp_methods,comp)) | |
1187 | { | |
1188 | OPENSSL_free(comp); | |
1189 | MemCheck_on(); | |
1190 | SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,SSL_R_DUPLICATE_COMPRESSION_ID); | |
1191 | return(1); | |
1192 | } | |
1193 | else if ((ssl_comp_methods == NULL) | |
7ba666fa | 1194 | || !sk_SSL_COMP_push(ssl_comp_methods,comp)) |
413c4f45 | 1195 | { |
7ba666fa | 1196 | OPENSSL_free(comp); |
058123af | 1197 | MemCheck_on(); |
413c4f45 | 1198 | SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE); |
f6e8c19e | 1199 | return(1); |
413c4f45 MC |
1200 | } |
1201 | else | |
058123af RL |
1202 | { |
1203 | MemCheck_on(); | |
f6e8c19e | 1204 | return(0); |
058123af | 1205 | } |
413c4f45 | 1206 | } |
377dcdba RL |
1207 | |
1208 | const char *SSL_COMP_get_name(const COMP_METHOD *comp) | |
1209 | { | |
1210 | if (comp) | |
1211 | return comp->name; | |
1212 | return NULL; | |
1213 | } | |
1214 |