在openssl的1.0.2版本中对外提供了一个SSL_get0_raw_cipherlist(s, plst)。这个接口有两个参数,第一个是SSL*, 第二个是字符数组。如果第二个参数传入的参数是NULL的时候返回的是对应的cipher占用字节的大小,如果不为NULL,则会将相应数据拷贝至该数组中。但是如果client发送的是无版本号的错误ssl握手信息,会造成设置ssl的method为ssl23相应的函数集。此时在SSL_get0_raw_cipherlist(s,NULL)中调用了ssl_put_cipher_by_char(s, NULL,NULL), ssl_put_cipher_by_char中调用了(ssl)->method->put_cipher_by_char(NULL, NULL)。该函数现在是ssl23_put_cipher_by_char(NULL, NULL)。但是在ssl23_put_cipher_by_char中的逻辑是这样的:
int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
{
long l;
/* We can write SSLv2 and SSLv3 ciphers */
/* but no ECC ciphers */
if (c->algorithm_mkey == SSL_kECDHr ||
c->algorithm_mkey == SSL_kECDHe ||
c->algorithm_mkey == SSL_kEECDH ||
c->algorithm_auth == SSL_aECDH || c->algorithm_auth == SSL_aECDSA)
return 0;
if (p != NULL) {
l = c->id;
p[0] = ((unsigned char)(l >> 16L)) & 0xFF;
p[1] = ((unsigned char)(l >> 8L)) & 0xFF;
p[2] = ((unsigned char)(l)) & 0xFF;
}
return (3);
}
因为c为NULL,所以会引起core。