📄 ssl_ciph.c
字号:
co_list_num = 0; /* actual count of ciphers */ for (i = 0; i < num_of_ciphers; i++) { c = ssl_method->get_cipher(i); /* drop those that use any of that is not available */ if ((c != NULL) && c->valid && !(c->algorithms & mask)) { co_list[co_list_num].cipher = c; co_list[co_list_num].next = NULL; co_list[co_list_num].prev = NULL; co_list[co_list_num].active = 0; co_list_num++;#ifdef KSSL_DEBUG printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);#endif /* KSSL_DEBUG */ /* if (!sk_push(ca_list,(char *)c)) goto err; */ } } /* * Prepare linked list from list entries */ for (i = 1; i < co_list_num - 1; i++) { co_list[i].prev = &(co_list[i-1]); co_list[i].next = &(co_list[i+1]); } if (co_list_num > 0) { (*head_p) = &(co_list[0]); (*head_p)->prev = NULL; (*head_p)->next = &(co_list[1]); (*tail_p) = &(co_list[co_list_num - 1]); (*tail_p)->prev = &(co_list[co_list_num - 2]); (*tail_p)->next = NULL; } }static void ssl_cipher_collect_aliases(SSL_CIPHER **ca_list, int num_of_group_aliases, unsigned long mask, CIPHER_ORDER *head) { CIPHER_ORDER *ciph_curr; SSL_CIPHER **ca_curr; int i; /* * First, add the real ciphers as already collected */ ciph_curr = head; ca_curr = ca_list; while (ciph_curr != NULL) { *ca_curr = ciph_curr->cipher; ca_curr++; ciph_curr = ciph_curr->next; } /* * Now we add the available ones from the cipher_aliases[] table. * They represent either an algorithm, that must be fully * supported (not match any bit in mask) or represent a cipher * strength value (will be added in any case because algorithms=0). */ for (i = 0; i < num_of_group_aliases; i++) { if ((i == 0) || /* always fetch "ALL" */ !(cipher_aliases[i].algorithms & mask)) { *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); ca_curr++; } } *ca_curr = NULL; /* end of list */ }static void ssl_cipher_apply_rule(unsigned long algorithms, unsigned long mask, unsigned long algo_strength, unsigned long mask_strength, int rule, int strength_bits, CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { CIPHER_ORDER *head, *tail, *curr, *curr2, *tail2; SSL_CIPHER *cp; unsigned long ma, ma_s;#ifdef CIPHER_DEBUG printf("Applying rule %d with %08lx %08lx %08lx %08lx (%d)\n", rule, algorithms, mask, algo_strength, mask_strength, strength_bits);#endif curr = head = *head_p; curr2 = head; tail2 = tail = *tail_p; for (;;) { if ((curr == NULL) || (curr == tail2)) break; curr = curr2; curr2 = curr->next; cp = curr->cipher; /* * Selection criteria is either the number of strength_bits * or the algorithm used. */ if (strength_bits == -1) { ma = mask & cp->algorithms; ma_s = mask_strength & cp->algo_strength;#ifdef CIPHER_DEBUG printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength); printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength);#endif /* * Select: if none of the mask bit was met from the * cipher or not all of the bits were met, the * selection does not apply. */ if (((ma == 0) && (ma_s == 0)) || ((ma & algorithms) != ma) || ((ma_s & algo_strength) != ma_s)) continue; /* does not apply */ } else if (strength_bits != cp->strength_bits) continue; /* does not apply */#ifdef CIPHER_DEBUG printf("Action = %d\n", rule);#endif /* add the cipher if it has not been added yet. */ if (rule == CIPHER_ADD) { if (!curr->active) { ll_append_tail(&head, curr, &tail); curr->active = 1; } } /* Move the added cipher to this location */ else if (rule == CIPHER_ORD) { if (curr->active) { ll_append_tail(&head, curr, &tail); } } else if (rule == CIPHER_DEL) curr->active = 0; else if (rule == CIPHER_KILL) { if (head == curr) head = curr->next; else curr->prev->next = curr->next; if (tail == curr) tail = curr->prev; curr->active = 0; if (curr->next != NULL) curr->next->prev = curr->prev; if (curr->prev != NULL) curr->prev->next = curr->next; curr->next = NULL; curr->prev = NULL; } } *head_p = head; *tail_p = tail; }static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) { int max_strength_bits, i, *number_uses; CIPHER_ORDER *curr; /* * This routine sorts the ciphers with descending strength. The sorting * must keep the pre-sorted sequence, so we apply the normal sorting * routine as '+' movement to the end of the list. */ max_strength_bits = 0; curr = *head_p; while (curr != NULL) { if (curr->active && (curr->cipher->strength_bits > max_strength_bits)) max_strength_bits = curr->cipher->strength_bits; curr = curr->next; } number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); if (!number_uses) { SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT,ERR_R_MALLOC_FAILURE); return(0); } memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); /* * Now find the strength_bits values actually used */ curr = *head_p; while (curr != NULL) { if (curr->active) number_uses[curr->cipher->strength_bits]++; curr = curr->next; } /* * Go through the list of used strength_bits values in descending * order. */ for (i = max_strength_bits; i >= 0; i--) if (number_uses[i] > 0) ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i, co_list, head_p, tail_p); OPENSSL_free(number_uses); return(1); }static int ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER *co_list, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list) { unsigned long algorithms, mask, algo_strength, mask_strength; const char *l, *start, *buf; int j, multi, found, rule, retval, ok, buflen; char ch; retval = 1; l = rule_str; for (;;) { ch = *l; if (ch == '\0') break; /* done */ if (ch == '-') { rule = CIPHER_DEL; l++; } else if (ch == '+') { rule = CIPHER_ORD; l++; } else if (ch == '!') { rule = CIPHER_KILL; l++; } else if (ch == '@') { rule = CIPHER_SPECIAL; l++; } else { rule = CIPHER_ADD; } if (ITEM_SEP(ch)) { l++; continue; } algorithms = mask = algo_strength = mask_strength = 0; start=l; for (;;) { ch = *l; buf = l; buflen = 0;#ifndef CHARSET_EBCDIC while ( ((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '-'))#else while ( isalnum(ch) || (ch == '-'))#endif { ch = *(++l); buflen++; } if (buflen == 0) { /* * We hit something we cannot deal with, * it is no command or separator nor * alphanumeric, so we call this an error. */ SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); retval = found = 0; l++; break; } if (rule == CIPHER_SPECIAL) { found = 0; /* unused -- avoid compiler warning */ break; /* special treatment */ } /* check for multi-part specification */ if (ch == '+') { multi=1; l++; } else multi=0; /* * Now search for the cipher alias in the ca_list. Be careful * with the strncmp, because the "buflen" limitation * will make the rule "ADH:SOME" and the cipher * "ADH-MY-CIPHER" look like a match for buflen=3. * So additionally check whether the cipher name found * has the correct length. We can save a strlen() call: * just checking for the '\0' at the right place is * sufficient, we have to strncmp() anyway. (We cannot * use strcmp(), because buf is not '\0' terminated.) */ j = found = 0; while (ca_list[j]) { if (!strncmp(buf, ca_list[j]->name, buflen) && (ca_list[j]->name[buflen] == '\0')) { found = 1; break; } else j++; } if (!found) break; /* ignore this entry */ /* New algorithms: * 1 - any old restrictions apply outside new mask * 2 - any new restrictions apply outside old mask * 3 - enforce old & new where masks intersect */ algorithms = (algorithms & ~ca_list[j]->mask) | /* 1 */ (ca_list[j]->algorithms & ~mask) | /* 2 */ (algorithms & ca_list[j]->algorithms); /* 3 */ mask |= ca_list[j]->mask; algo_strength = (algo_strength & ~ca_list[j]->mask_strength) | (ca_list[j]->algo_strength & ~mask_strength) | (algo_strength & ca_list[j]->algo_strength); mask_strength |= ca_list[j]->mask_strength; if (!multi) break; } /* * Ok, we have the rule, now apply it */ if (rule == CIPHER_SPECIAL) { /* special command */ ok = 0; if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) ok = ssl_cipher_strength_sort(co_list, head_p, tail_p); else SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND); if (ok == 0) retval = 0; /* * We do not support any "multi" options * together with "@", so throw away the * rest of the command, if any left, until * end or ':' is found. */ while ((*l != '\0') && ITEM_SEP(*l)) l++; } else if (found) { ssl_cipher_apply_rule(algorithms, mask, algo_strength, mask_strength, rule, -1, co_list, head_p, tail_p); } else { while ((*l != '\0') && ITEM_SEP(*l)) l++; } if (*l == '\0') break; /* done */ } return(retval); }STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) **cipher_list, STACK_OF(SSL_CIPHER) **cipher_list_by_id, const char *rule_str) { int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; unsigned long disabled_mask; STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -