summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_ciph.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libssl/ssl_ciph.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libssl/ssl_ciph.c')
-rw-r--r--src/lib/libssl/ssl_ciph.c758
1 files changed, 758 insertions, 0 deletions
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
new file mode 100644
index 0000000000..820994408b
--- /dev/null
+++ b/src/lib/libssl/ssl_ciph.c
@@ -0,0 +1,758 @@
1/* ssl/ssl_ciph.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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>
60#include "objects.h"
61#include "ssl_locl.h"
62
63#define SSL_ENC_DES_IDX 0
64#define SSL_ENC_3DES_IDX 1
65#define SSL_ENC_RC4_IDX 2
66#define SSL_ENC_RC2_IDX 3
67#define SSL_ENC_IDEA_IDX 4
68#define SSL_ENC_eFZA_IDX 5
69#define SSL_ENC_NULL_IDX 6
70#define SSL_ENC_NUM_IDX 7
71
72static EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]={
73 NULL,NULL,NULL,NULL,NULL,NULL,
74 };
75
76#define SSL_MD_MD5_IDX 0
77#define SSL_MD_SHA1_IDX 1
78#define SSL_MD_NUM_IDX 2
79static EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={
80 NULL,NULL,
81 };
82
83typedef struct cipher_sort_st
84 {
85 SSL_CIPHER *cipher;
86 int pref;
87 } CIPHER_SORT;
88
89#define CIPHER_ADD 1
90#define CIPHER_KILL 2
91#define CIPHER_DEL 3
92#define CIPHER_ORD 4
93
94typedef struct cipher_choice_st
95 {
96 int type;
97 unsigned long algorithms;
98 unsigned long mask;
99 long top;
100 } CIPHER_CHOICE;
101
102typedef 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
110static SSL_CIPHER cipher_aliases[]={
111 {0,SSL_TXT_ALL, 0,SSL_ALL, 0,SSL_ALL}, /* must be first */
112 {0,SSL_TXT_kRSA,0,SSL_kRSA, 0,SSL_MKEY_MASK},
113 {0,SSL_TXT_kDHr,0,SSL_kDHr, 0,SSL_MKEY_MASK},
114 {0,SSL_TXT_kDHd,0,SSL_kDHd, 0,SSL_MKEY_MASK},
115 {0,SSL_TXT_kEDH,0,SSL_kEDH, 0,SSL_MKEY_MASK},
116 {0,SSL_TXT_kFZA,0,SSL_kFZA, 0,SSL_MKEY_MASK},
117 {0,SSL_TXT_DH, 0,SSL_DH, 0,SSL_MKEY_MASK},
118 {0,SSL_TXT_EDH, 0,SSL_EDH, 0,SSL_MKEY_MASK|SSL_AUTH_MASK},
119
120 {0,SSL_TXT_aRSA,0,SSL_aRSA, 0,SSL_AUTH_MASK},
121 {0,SSL_TXT_aDSS,0,SSL_aDSS, 0,SSL_AUTH_MASK},
122 {0,SSL_TXT_aFZA,0,SSL_aFZA, 0,SSL_AUTH_MASK},
123 {0,SSL_TXT_aNULL,0,SSL_aNULL,0,SSL_AUTH_MASK},
124 {0,SSL_TXT_aDH, 0,SSL_aDH, 0,SSL_AUTH_MASK},
125 {0,SSL_TXT_DSS, 0,SSL_DSS, 0,SSL_AUTH_MASK},
126
127 {0,SSL_TXT_DES, 0,SSL_DES, 0,SSL_ENC_MASK},
128 {0,SSL_TXT_3DES,0,SSL_3DES, 0,SSL_ENC_MASK},
129 {0,SSL_TXT_RC4, 0,SSL_RC4, 0,SSL_ENC_MASK},
130 {0,SSL_TXT_RC2, 0,SSL_RC2, 0,SSL_ENC_MASK},
131 {0,SSL_TXT_IDEA,0,SSL_IDEA, 0,SSL_ENC_MASK},
132 {0,SSL_TXT_eNULL,0,SSL_eNULL,0,SSL_ENC_MASK},
133 {0,SSL_TXT_eFZA,0,SSL_eFZA, 0,SSL_ENC_MASK},
134
135 {0,SSL_TXT_MD5, 0,SSL_MD5, 0,SSL_MAC_MASK},
136 {0,SSL_TXT_SHA1,0,SSL_SHA1, 0,SSL_MAC_MASK},
137 {0,SSL_TXT_SHA, 0,SSL_SHA, 0,SSL_MAC_MASK},
138
139 {0,SSL_TXT_NULL,0,SSL_NULL, 0,SSL_ENC_MASK},
140 {0,SSL_TXT_RSA, 0,SSL_RSA, 0,SSL_AUTH_MASK|SSL_MKEY_MASK},
141 {0,SSL_TXT_ADH, 0,SSL_ADH, 0,SSL_AUTH_MASK|SSL_MKEY_MASK},
142 {0,SSL_TXT_FZA, 0,SSL_FZA, 0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK},
143
144 {0,SSL_TXT_EXP, 0,SSL_EXP, 0,SSL_EXP_MASK},
145 {0,SSL_TXT_EXPORT,0,SSL_EXPORT,0,SSL_EXP_MASK},
146 {0,SSL_TXT_SSLV2,0,SSL_SSLV2,0,SSL_SSL_MASK},
147 {0,SSL_TXT_SSLV3,0,SSL_SSLV3,0,SSL_SSL_MASK},
148 {0,SSL_TXT_LOW, 0,SSL_LOW,0,SSL_STRONG_MASK},
149 {0,SSL_TXT_MEDIUM,0,SSL_MEDIUM,0,SSL_STRONG_MASK},
150 {0,SSL_TXT_HIGH, 0,SSL_HIGH,0,SSL_STRONG_MASK},
151 };
152
153static int init_ciphers=1;
154static void load_ciphers();
155
156static int cmp_by_name(a,b)
157SSL_CIPHER **a,**b;
158 {
159 return(strcmp((*a)->name,(*b)->name));
160 }
161
162static void load_ciphers()
163 {
164 init_ciphers=0;
165 ssl_cipher_methods[SSL_ENC_DES_IDX]=
166 EVP_get_cipherbyname(SN_des_cbc);
167 ssl_cipher_methods[SSL_ENC_3DES_IDX]=
168 EVP_get_cipherbyname(SN_des_ede3_cbc);
169 ssl_cipher_methods[SSL_ENC_RC4_IDX]=
170 EVP_get_cipherbyname(SN_rc4);
171 ssl_cipher_methods[SSL_ENC_RC2_IDX]=
172 EVP_get_cipherbyname(SN_rc2_cbc);
173 ssl_cipher_methods[SSL_ENC_IDEA_IDX]=
174 EVP_get_cipherbyname(SN_idea_cbc);
175
176 ssl_digest_methods[SSL_MD_MD5_IDX]=
177 EVP_get_digestbyname(SN_md5);
178 ssl_digest_methods[SSL_MD_SHA1_IDX]=
179 EVP_get_digestbyname(SN_sha1);
180 }
181
182int ssl_cipher_get_evp(c,enc,md)
183SSL_CIPHER *c;
184EVP_CIPHER **enc;
185EVP_MD **md;
186 {
187 int i;
188
189 if (c == NULL) return(0);
190
191 switch (c->algorithms & SSL_ENC_MASK)
192 {
193 case SSL_DES:
194 i=SSL_ENC_DES_IDX;
195 break;
196 case SSL_3DES:
197 i=SSL_ENC_3DES_IDX;
198 break;
199 case SSL_RC4:
200 i=SSL_ENC_RC4_IDX;
201 break;
202 case SSL_RC2:
203 i=SSL_ENC_RC2_IDX;
204 break;
205 case SSL_IDEA:
206 i=SSL_ENC_IDEA_IDX;
207 break;
208 case SSL_eNULL:
209 i=SSL_ENC_NULL_IDX;
210 break;
211 break;
212 default:
213 i= -1;
214 break;
215 }
216
217 if ((i < 0) || (i > SSL_ENC_NUM_IDX))
218 *enc=NULL;
219 else
220 {
221 if (i == SSL_ENC_NULL_IDX)
222 *enc=EVP_enc_null();
223 else
224 *enc=ssl_cipher_methods[i];
225 }
226
227 switch (c->algorithms & SSL_MAC_MASK)
228 {
229 case SSL_MD5:
230 i=SSL_MD_MD5_IDX;
231 break;
232 case SSL_SHA1:
233 i=SSL_MD_SHA1_IDX;
234 break;
235 default:
236 i= -1;
237 break;
238 }
239 if ((i < 0) || (i > SSL_MD_NUM_IDX))
240 *md=NULL;
241 else
242 *md=ssl_digest_methods[i];
243
244 if ((*enc != NULL) && (*md != NULL))
245 return(1);
246 else
247 return(0);
248 }
249
250#define ITEM_SEP(a) \
251 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
252
253static void ll_append_tail(head,curr,tail)
254CIPHER_ORDER **head,*curr,**tail;
255 {
256 if (curr == *tail) return;
257 if (curr == *head)
258 *head=curr->next;
259 if (curr->prev != NULL)
260 curr->prev->next=curr->next;
261 if (curr->next != NULL) /* should always be true */
262 curr->next->prev=curr->prev;
263 (*tail)->next=curr;
264 curr->prev= *tail;
265 curr->next=NULL;
266 *tail=curr;
267 }
268
269STACK *ssl_create_cipher_list(ssl_method,cipher_list,cipher_list_by_id,str)
270SSL_METHOD *ssl_method;
271STACK **cipher_list,**cipher_list_by_id;
272char *str;
273 {
274 SSL_CIPHER *c;
275 char *l;
276 STACK *ret=NULL,*ok=NULL;
277#define CL_BUF 40
278 char buf[CL_BUF];
279 char *tmp_str=NULL;
280 unsigned long mask,algorithms,ma;
281 char *start;
282 int i,j,k,num=0,ch,multi;
283 unsigned long al;
284 STACK *ca_list=NULL;
285 int current_x,num_x;
286 CIPHER_CHOICE *ops=NULL;
287 CIPHER_ORDER *list=NULL,*head=NULL,*tail=NULL,*curr,*tail2,*curr2;
288 int list_num;
289 int type;
290 SSL_CIPHER c_tmp,*cp;
291
292 if (str == NULL) return(NULL);
293
294 if (strncmp(str,"DEFAULT",7) == 0)
295 {
296 i=strlen(str)+2+strlen(SSL_DEFAULT_CIPHER_LIST);
297 if ((tmp_str=Malloc(i)) == NULL)
298 {
299 SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);
300 goto err;
301 }
302 strcpy(tmp_str,SSL_DEFAULT_CIPHER_LIST);
303 strcat(tmp_str,":");
304 strcat(tmp_str,&(str[7]));
305 str=tmp_str;
306 }
307 if (init_ciphers) load_ciphers();
308
309 num=ssl_method->num_ciphers();
310
311 if ((ret=(STACK *)sk_new(NULL)) == NULL) goto err;
312 if ((ca_list=(STACK *)sk_new(cmp_by_name)) == NULL) goto err;
313
314 mask =SSL_kFZA;
315#ifdef NO_RSA
316 mask|=SSL_aRSA|SSL_kRSA;
317#endif
318#ifdef NO_DSA
319 mask|=SSL_aDSS;
320#endif
321#ifdef NO_DH
322 mask|=SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
323#endif
324
325#ifndef SSL_ALLOW_ENULL
326 mask|=SSL_eNULL;
327#endif
328
329 mask|=(ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL)?SSL_DES :0;
330 mask|=(ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL)?SSL_3DES:0;
331 mask|=(ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL)?SSL_RC4 :0;
332 mask|=(ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL)?SSL_RC2 :0;
333 mask|=(ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL)?SSL_IDEA:0;
334 mask|=(ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL)?SSL_eFZA:0;
335
336 mask|=(ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL)?SSL_MD5 :0;
337 mask|=(ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL)?SSL_SHA1:0;
338
339 if ((list=(CIPHER_ORDER *)Malloc(sizeof(CIPHER_ORDER)*num)) == NULL)
340 goto err;
341
342 /* Get the initial list of ciphers */
343 list_num=0;
344 for (i=0; i<num; i++)
345 {
346 c=ssl_method->get_cipher((unsigned int)i);
347 /* drop those that use any of that is not available */
348 if ((c != NULL) && c->valid && !(c->algorithms & mask))
349 {
350 list[list_num].cipher=c;
351 list[list_num].next=NULL;
352 list[list_num].prev=NULL;
353 list[list_num].active=0;
354 list_num++;
355 if (!sk_push(ca_list,(char *)c)) goto err;
356 }
357 }
358
359 for (i=1; i<list_num-1; i++)
360 {
361 list[i].prev= &(list[i-1]);
362 list[i].next= &(list[i+1]);
363 }
364 if (list_num > 0)
365 {
366 head= &(list[0]);
367 head->prev=NULL;
368 head->next= &(list[1]);
369 tail= &(list[list_num-1]);
370 tail->prev= &(list[list_num-2]);
371 tail->next=NULL;
372 }
373
374 /* special case */
375 cipher_aliases[0].algorithms= ~mask;
376
377 /* get the aliases */
378 k=sizeof(cipher_aliases)/sizeof(SSL_CIPHER);
379 for (j=0; j<k; j++)
380 {
381 al=cipher_aliases[j].algorithms;
382 /* Drop those that are not relevent */
383 if ((al & mask) == al) continue;
384 if (!sk_push(ca_list,(char *)&(cipher_aliases[j]))) goto err;
385 }
386
387 /* ca_list now holds a 'stack' of SSL_CIPHERS, some real, some
388 * 'aliases' */
389
390 /* how many parameters are there? */
391 num=1;
392 for (l=str; *l; l++)
393 if (ITEM_SEP(*l))
394 num++;
395 ops=(CIPHER_CHOICE *)Malloc(sizeof(CIPHER_CHOICE)*num);
396 if (ops == NULL) goto err;
397 memset(ops,0,sizeof(CIPHER_CHOICE)*num);
398
399 /* we now parse the input string and create our operations */
400 l=str;
401 i=0;
402 current_x=0;
403
404 for (;;)
405 {
406 ch= *l;
407
408 if (ch == '\0') break;
409
410 if (ch == '-')
411 { j=CIPHER_DEL; l++; }
412 else if (ch == '+')
413 { j=CIPHER_ORD; l++; }
414 else if (ch == '!')
415 { j=CIPHER_KILL; l++; }
416 else
417 { j=CIPHER_ADD; }
418
419 if (ITEM_SEP(ch))
420 {
421 l++;
422 continue;
423 }
424 ops[current_x].type=j;
425 ops[current_x].algorithms=0;
426 ops[current_x].mask=0;
427
428 start=l;
429 for (;;)
430 {
431 ch= *l;
432 i=0;
433 while ( ((ch >= 'A') && (ch <= 'Z')) ||
434 ((ch >= '0') && (ch <= '9')) ||
435 ((ch >= 'a') && (ch <= 'z')) ||
436 (ch == '-'))
437 {
438 buf[i]=ch;
439 ch= *(++l);
440 i++;
441 if (i >= (CL_BUF-2)) break;
442 }
443 buf[i]='\0';
444
445 /* check for multi-part specification */
446 if (ch == '+')
447 {
448 multi=1;
449 l++;
450 }
451 else
452 multi=0;
453
454 c_tmp.name=buf;
455 j=sk_find(ca_list,(char *)&c_tmp);
456 if (j < 0)
457 goto end_loop;
458
459 cp=(SSL_CIPHER *)sk_value(ca_list,j);
460 ops[current_x].algorithms|=cp->algorithms;
461 /* We add the SSL_SSL_MASK so we can match the
462 * SSLv2 and SSLv3 versions of RC4-MD5 */
463 ops[current_x].mask|=cp->mask;
464 if (!multi) break;
465 }
466 current_x++;
467 if (ch == '\0') break;
468end_loop:
469 /* Make sure we scan until the next valid start point */
470 while ((*l != '\0') && ITEM_SEP(*l))
471 l++;
472 }
473
474 num_x=current_x;
475 current_x=0;
476
477 /* We will now process the list of ciphers, once for each category, to
478 * decide what we should do with it. */
479 for (j=0; j<num_x; j++)
480 {
481 algorithms=ops[j].algorithms;
482 type=ops[j].type;
483 mask=ops[j].mask;
484
485 curr=head;
486 curr2=head;
487 tail2=tail;
488 for (;;)
489 {
490 if ((curr == NULL) || (curr == tail2)) break;
491 curr=curr2;
492 curr2=curr->next;
493
494 cp=curr->cipher;
495 ma=mask & cp->algorithms;
496 if ((ma == 0) || ((ma & algorithms) != ma))
497 {
498 /* does not apply */
499 continue;
500 }
501
502 /* add the cipher if it has not been added yet. */
503 if (type == CIPHER_ADD)
504 {
505 if (!curr->active)
506 {
507 ll_append_tail(&head,curr,&tail);
508 curr->active=1;
509 }
510 }
511 /* Move the added cipher to this location */
512 else if (type == CIPHER_ORD)
513 {
514 if (curr->active)
515 {
516 ll_append_tail(&head,curr,&tail);
517 }
518 }
519 else if (type == CIPHER_DEL)
520 curr->active=0;
521 if (type == CIPHER_KILL)
522 {
523 if (head == curr)
524 head=curr->next;
525 else
526 curr->prev->next=curr->next;
527 if (tail == curr)
528 tail=curr->prev;
529 curr->active=0;
530 if (curr->next != NULL)
531 curr->next->prev=curr->prev;
532 if (curr->prev != NULL)
533 curr->prev->next=curr->next;
534 curr->next=NULL;
535 curr->prev=NULL;
536 }
537 }
538 }
539
540 for (curr=head; curr != NULL; curr=curr->next)
541 {
542 if (curr->active)
543 {
544 sk_push(ret,(char *)curr->cipher);
545#ifdef CIPHER_DEBUG
546 printf("<%s>\n",curr->cipher->name);
547#endif
548 }
549 }
550
551 if (cipher_list != NULL)
552 {
553 if (*cipher_list != NULL)
554 sk_free(*cipher_list);
555 *cipher_list=ret;
556 }
557
558 if (cipher_list_by_id != NULL)
559 {
560 if (*cipher_list_by_id != NULL)
561 sk_free(*cipher_list_by_id);
562 *cipher_list_by_id=sk_dup(ret);
563 }
564
565 if ( (cipher_list_by_id == NULL) ||
566 (*cipher_list_by_id == NULL) ||
567 (cipher_list == NULL) ||
568 (*cipher_list == NULL))
569 goto err;
570 sk_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
571
572 ok=ret;
573 ret=NULL;
574err:
575 if (tmp_str) Free(tmp_str);
576 if (ops != NULL) Free(ops);
577 if (ret != NULL) sk_free(ret);
578 if (ca_list != NULL) sk_free(ca_list);
579 if (list != NULL) Free(list);
580 return(ok);
581 }
582
583char *SSL_CIPHER_description(cipher,buf,len)
584SSL_CIPHER *cipher;
585char *buf;
586int len;
587 {
588 int export;
589 char *ver,*exp;
590 char *kx,*au,*enc,*mac;
591 unsigned long alg,alg2;
592 static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";
593
594 alg=cipher->algorithms;
595 alg2=cipher->algorithm2;
596
597 export=(alg&SSL_EXP)?1:0;
598 exp=(export)?" export":"";
599
600 if (alg & SSL_SSLV2)
601 ver="SSLv2";
602 else if (alg & SSL_SSLV3)
603 ver="SSLv3";
604 else
605 ver="unknown";
606
607 switch (alg&SSL_MKEY_MASK)
608 {
609 case SSL_kRSA:
610 kx=(export)?"RSA(512)":"RSA";
611 break;
612 case SSL_kDHr:
613 kx="DH/RSA";
614 break;
615 case SSL_kDHd:
616 kx="DH/DSS";
617 break;
618 case SSL_kFZA:
619 kx="Fortezza";
620 break;
621 case SSL_kEDH:
622 kx=(export)?"DH(512)":"DH";
623 break;
624 default:
625 kx="unknown";
626 }
627
628 switch (alg&SSL_AUTH_MASK)
629 {
630 case SSL_aRSA:
631 au="RSA";
632 break;
633 case SSL_aDSS:
634 au="DSS";
635 break;
636 case SSL_aDH:
637 au="DH";
638 break;
639 case SSL_aFZA:
640 case SSL_aNULL:
641 au="None";
642 break;
643 default:
644 au="unknown";
645 break;
646 }
647
648 switch (alg&SSL_ENC_MASK)
649 {
650 case SSL_DES:
651 enc=export?"DES(40)":"DES(56)";
652 break;
653 case SSL_3DES:
654 enc="3DES(168)";
655 break;
656 case SSL_RC4:
657 enc=export?"RC4(40)":((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");
658 break;
659 case SSL_RC2:
660 enc=export?"RC2(40)":"RC2(128)";
661 break;
662 case SSL_IDEA:
663 enc="IDEA(128)";
664 break;
665 case SSL_eFZA:
666 enc="Fortezza";
667 break;
668 case SSL_eNULL:
669 enc="None";
670 break;
671 default:
672 enc="unknown";
673 break;
674 }
675
676 switch (alg&SSL_MAC_MASK)
677 {
678 case SSL_MD5:
679 mac="MD5";
680 break;
681 case SSL_SHA1:
682 mac="SHA1";
683 break;
684 default:
685 mac="unknown";
686 break;
687 }
688
689 if (buf == NULL)
690 {
691 buf=Malloc(128);
692 if (buf == NULL) return("Malloc Error");
693 }
694 else if (len < 128)
695 return("Buffer too small");
696
697 sprintf(buf,format,cipher->name,ver,kx,au,enc,mac,exp);
698 return(buf);
699 }
700
701char *SSL_CIPHER_get_version(c)
702SSL_CIPHER *c;
703 {
704 int i;
705
706 if (c == NULL) return("(NONE)");
707 i=(int)(c->id>>24L);
708 if (i == 3)
709 return("TLSv1/SSLv3");
710 else if (i == 2)
711 return("SSLv2");
712 else
713 return("unknown");
714 }
715
716/* return the actual cipher being used */
717char *SSL_CIPHER_get_name(c)
718SSL_CIPHER *c;
719 {
720 if (c != NULL)
721 return(c->name);
722 return("(NONE)");
723 }
724
725/* number of bits for symetric cipher */
726int SSL_CIPHER_get_bits(c,alg_bits)
727SSL_CIPHER *c;
728int *alg_bits;
729 {
730 int ret=0,a=0;
731 EVP_CIPHER *enc;
732 EVP_MD *md;
733
734 if (c != NULL)
735 {
736 if (!ssl_cipher_get_evp(c,&enc,&md))
737 return(0);
738
739 a=EVP_CIPHER_key_length(enc)*8;
740
741 if (c->algorithms & SSL_EXP)
742 {
743 ret=40;
744 }
745 else
746 {
747 if (c->algorithm2 & SSL2_CF_8_BYTE_ENC)
748 ret=64;
749 else
750 ret=a;
751 }
752 }
753
754 if (alg_bits != NULL) *alg_bits=a;
755
756 return(ret);
757 }
758