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