return ssl_x509_store_ctx_idx;
}
-CERT *ssl_cert_new(void)
+CERT *ssl_cert_new(size_t ssl_pkey_num)
{
- CERT *ret = OPENSSL_zalloc(sizeof(*ret));
+ CERT *ret = NULL;
+
+ /* Should never happen */
+ if (!ossl_assert(ssl_pkey_num >= SSL_PKEY_NUM))
+ return NULL;
+ ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL)
return NULL;
+ ret->ssl_pkey_num = ssl_pkey_num;
+ ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY));
+ if (ret->pkeys == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
ret->references = 1;
ret->sec_cb = ssl_security_default_callback;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
+ OPENSSL_free(ret->pkeys);
OPENSSL_free(ret);
return NULL;
}
CERT *ssl_cert_dup(CERT *cert)
{
CERT *ret = OPENSSL_zalloc(sizeof(*ret));
- int i;
+ size_t i;
#ifndef OPENSSL_NO_COMP_ALG
int j;
#endif
if (ret == NULL)
return NULL;
+ ret->ssl_pkey_num = cert->ssl_pkey_num;
+ ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY));
+ if (ret->pkeys == NULL)
+ return NULL;
+
ret->references = 1;
ret->key = &ret->pkeys[cert->key - cert->pkeys];
ret->lock = CRYPTO_THREAD_lock_new();
ret->dh_tmp_cb = cert->dh_tmp_cb;
ret->dh_tmp_auto = cert->dh_tmp_auto;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < ret->ssl_pkey_num; i++) {
CERT_PKEY *cpk = cert->pkeys + i;
CERT_PKEY *rpk = ret->pkeys + i;
void ssl_cert_clear_certs(CERT *c)
{
- int i;
+ size_t i;
#ifndef OPENSSL_NO_COMP_ALG
int j;
#endif
if (c == NULL)
return;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
X509_free(cpk->x509);
cpk->x509 = NULL;
#ifndef OPENSSL_NO_PSK
OPENSSL_free(c->psk_identity_hint);
#endif
+ OPENSSL_free(c->pkeys);
CRYPTO_THREAD_lock_free(c->lock);
OPENSSL_free(c);
}
int ssl_cert_set1_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
{
STACK_OF(X509) *dchain;
+
if (!chain)
return ssl_cert_set0_chain(s, ctx, NULL);
dchain = X509_chain_up_ref(chain);
{
int r;
CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
+
if (!cpk)
return 0;
r = ssl_security_cert(s, ctx, x, 0, 0);
int ssl_cert_select_current(CERT *c, X509 *x)
{
- int i;
+ size_t i;
+
if (x == NULL)
return 0;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->x509 == x && cpk->privatekey) {
c->key = cpk;
}
}
- for (i = 0; i < SSL_PKEY_NUM; i++) {
+ for (i = 0; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) {
c->key = cpk;
int ssl_cert_set_current(CERT *c, long op)
{
- int i, idx;
+ size_t i, idx;
+
if (!c)
return 0;
if (op == SSL_CERT_SET_FIRST)
idx = 0;
else if (op == SSL_CERT_SET_NEXT) {
- idx = (int)(c->key - c->pkeys + 1);
- if (idx >= SSL_PKEY_NUM)
+ idx = (size_t)(c->key - c->pkeys + 1);
+ if (idx >= c->ssl_pkey_num)
return 0;
} else
return 0;
- for (i = idx; i < SSL_PKEY_NUM; i++) {
+ for (i = idx; i < c->ssl_pkey_num; i++) {
CERT_PKEY *cpk = c->pkeys + i;
if (cpk->x509 && cpk->privatekey) {
c->key = cpk;
ctx->cert->sec_ex);
}
-int ssl_cert_lookup_by_nid(int nid, size_t *pidx)
+int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx)
{
size_t i;
return 1;
}
}
-
+ for (i = 0; i < ctx->sigalg_list_len; i++) {
+ if (ctx->ssl_cert_info[i].nid == nid) {
+ *pidx = SSL_PKEY_NUM + i;
+ return 1;
+ }
+ }
return 0;
}
-const SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx)
+SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx)
{
size_t i;
+ /* check classic pk types */
for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) {
- const SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i];
+ SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i];
if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid))
|| EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) {
return tmp_lu;
}
}
+ /* check provider-loaded pk types */
+ for (i = 0; ctx->sigalg_list_len; i++) {
+ SSL_CERT_LOOKUP *tmp_lu = &(ctx->ssl_cert_info[i]);
+
+ if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid))
+ || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) {
+ if (pidx != NULL)
+ *pidx = SSL_PKEY_NUM + i;
+ return &ctx->ssl_cert_info[i];
+ }
+ }
return NULL;
}
-const SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx)
+SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx)
{
- if (idx >= OSSL_NELEM(ssl_cert_info))
+ if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len))
return NULL;
+ else if (idx >= (OSSL_NELEM(ssl_cert_info)))
+ return &(ctx->ssl_cert_info[idx - SSL_PKEY_NUM]);
return &ssl_cert_info[idx];
}