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