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 72 static 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 79 static EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX]={ 80 NULL,NULL, 81 }; 82 83 typedef 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 94 typedef struct cipher_choice_st 95 { 96 int type; 97 unsigned long algorithms; 98 unsigned long mask; 99 long top; 100 } CIPHER_CHOICE; 101 102 typedef struct cipher_order_st 103 { 104 SSL_CIPHER *cipher; 105 int active; 106 int dead; 107 struct cipher_order_st *next,*prev; 108 } CIPHER_ORDER; 109 110 static 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 153 static int init_ciphers=1; 154 static void load_ciphers(); 155 156 static int cmp_by_name(a,b) 157 SSL_CIPHER **a,**b; 158 { 159 return(strcmp((*a)->name,(*b)->name)); 160 } 161 162 static 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 182 int ssl_cipher_get_evp(c,enc,md) 183 SSL_CIPHER *c; 184 EVP_CIPHER **enc; 185 EVP_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 253 static void ll_append_tail(head,curr,tail) 254 CIPHER_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 269 STACK *ssl_create_cipher_list(ssl_method,cipher_list,cipher_list_by_id,str) 270 SSL_METHOD *ssl_method; 271 STACK **cipher_list,**cipher_list_by_id; 272 char *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; 468 end_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; 574 err: 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 583 char *SSL_CIPHER_description(cipher,buf,len) 584 SSL_CIPHER *cipher; 585 char *buf; 586 int 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 701 char *SSL_CIPHER_get_version(c) 702 SSL_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 */ 717 char *SSL_CIPHER_get_name(c) 718 SSL_CIPHER *c; 719 { 720 if (c != NULL) 721 return(c->name); 722 return("(NONE)"); 723 } 724 725 /* number of bits for symetric cipher */ 726 int SSL_CIPHER_get_bits(c,alg_bits) 727 SSL_CIPHER *c; 728 int *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 759