}
}
ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
+ ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;
#endif
for (i = 0; i < SSL_PKEY_NUM; i++)
{
- if (cert->pkeys[i].x509 != NULL)
+ CERT_PKEY *cpk = cert->pkeys + i;
+ CERT_PKEY *rpk = ret->pkeys + i;
+ if (cpk->x509 != NULL)
{
- ret->pkeys[i].x509 = cert->pkeys[i].x509;
- CRYPTO_add(&ret->pkeys[i].x509->references, 1,
- CRYPTO_LOCK_X509);
+ rpk->x509 = cpk->x509;
+ CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
}
- if (cert->pkeys[i].privatekey != NULL)
+ if (cpk->privatekey != NULL)
{
- ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
- CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
+ rpk->privatekey = cpk->privatekey;
+ CRYPTO_add(&cpk->privatekey->references, 1,
CRYPTO_LOCK_EVP_PKEY);
switch(i)
SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
}
}
+
+ if (cpk->chain)
+ {
+ int j;
+ rpk->chain = sk_X509_dup(cpk->chain);
+ if (!rpk->chain)
+ {
+ SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ for (j = 0; j < sk_X509_num(rpk->chain); j++)
+ {
+ X509 *x = sk_X509_value(rpk->chain, j);
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ }
+ }
}
- /* ret->extra_certs *should* exist, but currently the own certificate
- * chain is held inside SSL_CTX */
-
ret->references=1;
/* Set digests to defaults. NB: we don't copy existing values as they
* will be set during handshake.
*/
ssl_cert_set_default_md(ret);
+ /* Sigalgs set to NULL as we get these from handshake too */
+ ret->sigalgs = NULL;
+ ret->sigalgslen = 0;
return(ret);
for (i = 0; i < SSL_PKEY_NUM; i++)
{
- if (ret->pkeys[i].x509 != NULL)
- X509_free(ret->pkeys[i].x509);
- if (ret->pkeys[i].privatekey != NULL)
- EVP_PKEY_free(ret->pkeys[i].privatekey);
+ CERT_PKEY *rpk = ret->pkeys + i;
+ if (rpk->x509 != NULL)
+ X509_free(rpk->x509);
+ if (rpk->privatekey != NULL)
+ EVP_PKEY_free(rpk->privatekey);
+ if (rpk->chain)
+ sk_X509_pop_free(rpk->chain, X509_free);
}
+
return NULL;
}
for (i=0; i<SSL_PKEY_NUM; i++)
{
- if (c->pkeys[i].x509 != NULL)
- X509_free(c->pkeys[i].x509);
- if (c->pkeys[i].privatekey != NULL)
- EVP_PKEY_free(c->pkeys[i].privatekey);
+ CERT_PKEY *cpk = c->pkeys + i;
+ if (cpk->x509 != NULL)
+ X509_free(cpk->x509);
+ if (cpk->privatekey != NULL)
+ EVP_PKEY_free(cpk->privatekey);
+ if (cpk->chain)
+ sk_X509_pop_free(cpk->chain, X509_free);
#if 0
if (c->pkeys[i].publickey != NULL)
EVP_PKEY_free(c->pkeys[i].publickey);
#endif
}
+ if (c->sigalgs)
+ OPENSSL_free(c->sigalgs);
OPENSSL_free(c);
}
return(1);
}
+int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
+ {
+ CERT_PKEY *cpk = c->key;
+ if (!cpk)
+ return 0;
+ if (cpk->chain)
+ sk_X509_pop_free(cpk->chain, X509_free);
+ cpk->chain = chain;
+ return 1;
+ }
+
+int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
+ {
+ STACK_OF(X509) *dchain;
+ X509 *x;
+ int i;
+ if (!chain)
+ return ssl_cert_set0_chain(c, NULL);
+ dchain = sk_X509_dup(chain);
+ if (!dchain)
+ return 0;
+ for (i = 0; i < sk_X509_num(dchain); i++)
+ {
+ x = sk_X509_value(dchain, i);
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ }
+ if (!ssl_cert_set0_chain(c, dchain))
+ {
+ sk_X509_pop_free(dchain, X509_free);
+ return 0;
+ }
+ return 1;
+ }
+
+int ssl_cert_add0_chain_cert(CERT *c, X509 *x)
+ {
+ CERT_PKEY *cpk = c->key;
+ if (!cpk)
+ return 0;
+ if (!cpk->chain)
+ cpk->chain = sk_X509_new_null();
+ if (!cpk->chain || !sk_X509_push(cpk->chain, x))
+ return 0;
+ return 1;
+ }
+
+int ssl_cert_add1_chain_cert(CERT *c, X509 *x)
+ {
+ if (!ssl_cert_add0_chain_cert(c, x))
+ return 0;
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ return 1;
+ }
SESS_CERT *ssl_sess_cert_new(void)
{
int i;
X509 *x;
+ STACK_OF(X509) *extra_certs;
if (cpk)
x = cpk->x509;
else
x = NULL;
- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
+ /* If we have a certificate specific chain use it, else use
+ * parent ctx.
+ */
+ if (cpk && cpk->chain)
+ extra_certs = cpk->chain;
+ else
+ extra_certs = s->ctx->extra_certs;
+
+ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs)
no_chain = 1;
else
no_chain = 0;
{
x = sk_X509_value(xs_ctx.chain, i);
- if (ssl_add_cert_to_buf(buf, l, x))
+ if (!ssl_add_cert_to_buf(buf, l, x))
{
X509_STORE_CTX_cleanup(&xs_ctx);
return 0;
X509_STORE_CTX_cleanup(&xs_ctx);
}
}
- /* Thawte special :-) */
- for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
+ for (i=0; i<sk_X509_num(extra_certs); i++)
{
- x=sk_X509_value(s->ctx->extra_certs,i);
+ x=sk_X509_value(extra_certs,i);
if (!ssl_add_cert_to_buf(buf, l, x))
return 0;
}