if (cpk->chain)
{
- int j;
- rpk->chain = sk_X509_dup(cpk->chain);
+ rpk->chain = X509_chain_up_ref(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);
- }
}
rpk->valid_flags = 0;
- if (cert->pkeys[i].authz != NULL)
+#ifndef OPENSSL_NO_TLSEXT
+ if (cert->pkeys[i].serverinfo != NULL)
{
/* Just copy everything. */
- ret->pkeys[i].authz_length =
- cert->pkeys[i].authz_length;
- ret->pkeys[i].authz =
- OPENSSL_malloc(ret->pkeys[i].authz_length);
- if (ret->pkeys[i].authz == NULL)
+ ret->pkeys[i].serverinfo =
+ OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
+ if (ret->pkeys[i].serverinfo == NULL)
{
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
- return(NULL);
+ return NULL;
}
- memcpy(ret->pkeys[i].authz,
- cert->pkeys[i].authz,
- cert->pkeys[i].authz_length);
+ ret->pkeys[i].serverinfo_length =
+ cert->pkeys[i].serverinfo_length;
+ memcpy(ret->pkeys[i].serverinfo,
+ cert->pkeys[i].serverinfo,
+ cert->pkeys[i].serverinfo_length);
}
+#endif
}
ret->references=1;
ret->chain_store = cert->chain_store;
}
+ ret->ciphers_raw = NULL;
+
return(ret);
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
cpk->chain = NULL;
}
#ifndef OPENSSL_NO_TLSEXT
- if (cpk->authz != NULL)
- OPENSSL_free(cpk->authz);
+ if (cpk->serverinfo)
+ {
+ OPENSSL_free(cpk->serverinfo);
+ cpk->serverinfo = NULL;
+ cpk->serverinfo_length = 0;
+ }
#endif
- cpk->valid_flags = 0;
+ /* Clear all flags apart from explicit sign */
+ cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
}
}
X509_STORE_free(c->verify_store);
if (c->chain_store)
X509_STORE_free(c->chain_store);
+ if (c->ciphers_raw)
+ OPENSSL_free(c->ciphers_raw);
OPENSSL_free(c);
}
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);
+ dchain = X509_chain_up_ref(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 1;
}
+int ssl_cert_select_current(CERT *c, X509 *x)
+ {
+ int i;
+ if (x == NULL)
+ return 0;
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ {
+ if (c->pkeys[i].x509 == x)
+ {
+ c->key = &c->pkeys[i];
+ return 1;
+ }
+ }
+
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ {
+ if (c->pkeys[i].x509 && !X509_cmp(c->pkeys[i].x509, x))
+ {
+ c->key = &c->pkeys[i];
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+int ssl_cert_set_current(CERT *c, long op)
+ {
+ int 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)
+ return 0;
+ }
+ else
+ return 0;
+ for (i = idx; i < SSL_PKEY_NUM; i++)
+ {
+ if (c->pkeys[i].x509)
+ {
+ c->key = &c->pkeys[i];
+ return 1;
+ }
+ }
+ return 0;
+ }
+
void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg)
{
c->cert_cb = cb;
SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,ERR_R_X509_LIB);
return(0);
}
+ /* Set suite B flags if needed */
+ X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s));
#if 0
if (SSL_get_verify_depth(s) >= 0)
X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
X509_STORE_CTX xs_ctx;
STACK_OF(X509) *chain = NULL, *untrusted = NULL;
X509 *x;
- int i;
+ int i, rv = 0;
if (!cpk->x509)
{
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET);
- return 0;
+ goto err;
}
+ /* Rearranging and check the chain: add everything to a store */
+ if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
+ {
+ chain_store = X509_STORE_new();
+ if (!chain_store)
+ goto err;
+ for (i = 0; i < sk_X509_num(cpk->chain); i++)
+ {
+ x = sk_X509_value(cpk->chain, i);
+ if (!X509_STORE_add_cert(chain_store, x))
+ goto err;
+ }
+ /* Add EE cert too: it might be self signed */
+ if (!X509_STORE_add_cert(chain_store, cpk->x509))
+ goto err;
+ }
+ else
+ {
+ if (c->chain_store)
+ chain_store = c->chain_store;
- if (c->chain_store)
- chain_store = c->chain_store;
-
- if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
- untrusted = cpk->chain;
+ if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
+ untrusted = cpk->chain;
+ }
if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted))
{
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB);
- return 0;
+ goto err;
}
+ /* Set suite B flags if needed */
+ X509_STORE_CTX_set_flags(&xs_ctx, c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS);
i = X509_verify_cert(&xs_ctx);
+ if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR)
+ {
+ ERR_clear_error();
+ i = 1;
+ }
if (i > 0)
chain = X509_STORE_CTX_get1_chain(&xs_ctx);
- X509_STORE_CTX_cleanup(&xs_ctx);
if (i <= 0)
{
SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED);
- return 0;
+ i = X509_STORE_CTX_get_error(&xs_ctx);
+ ERR_add_error_data(2, "Verify error:",
+ X509_verify_cert_error_string(i));
+
+ X509_STORE_CTX_cleanup(&xs_ctx);
+ goto err;
}
+ X509_STORE_CTX_cleanup(&xs_ctx);
if (cpk->chain)
sk_X509_pop_free(cpk->chain, X509_free);
/* Remove EE certificate from chain */
X509_free(x);
if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT)
{
- x = sk_X509_pop(chain);
- X509_free(x);
+ if (sk_X509_num(chain) > 0)
+ {
+ /* See if last cert is self signed */
+ x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ {
+ x = sk_X509_pop(chain);
+ X509_free(x);
+ }
+ }
}
cpk->chain = chain;
+ rv = 1;
+ err:
+ if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
+ X509_STORE_free(chain_store);
- return 1;
+ return rv;
}
int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)