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