- OPENSSL_free(sc);
- }
-
-int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
- {
- sc->peer_cert_type = type;
- return(1);
- }
-
-int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
- {
- X509 *x;
- int i;
- X509_STORE *verify_store;
- X509_STORE_CTX ctx;
-
- if (s->cert->verify_store)
- verify_store = s->cert->verify_store;
- else
- verify_store = s->ctx->cert_store;
-
- if ((sk == NULL) || (sk_X509_num(sk) == 0))
- return(0);
-
- x=sk_X509_value(sk,0);
- if(!X509_STORE_CTX_init(&ctx,verify_store,x,sk))
- {
- 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));
-#endif
- X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
-
- /* We need to inherit the verify parameters. These can be determined by
- * the context: if its a server it will verify SSL client certificates
- * or vice versa.
- */
-
- X509_STORE_CTX_set_default(&ctx,
- s->server ? "ssl_client" : "ssl_server");
- /* Anything non-default in "param" should overwrite anything in the
- * ctx.
- */
- X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
-
- if (s->verify_callback)
- X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
-
- if (s->ctx->app_verify_callback != NULL)
-#if 1 /* new with OpenSSL 0.9.7 */
- i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
-#else
- i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
-#endif
- else
- {
-#ifndef OPENSSL_NO_X509_VERIFY
- i=X509_verify_cert(&ctx);
-#else
- i=0;
- ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
- SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN,SSL_R_NO_VERIFY_CALLBACK);
-#endif
- }
-
- s->verify_result=ctx.error;
- X509_STORE_CTX_cleanup(&ctx);
-
- return(i);
- }
-
-static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
- {
- if (*ca_list != NULL)
- sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
-
- *ca_list=name_list;
- }
+ ssl_cert_clear_certs(c);
+ OPENSSL_free(c->conf_sigalgs);
+ OPENSSL_free(c->client_sigalgs);
+ OPENSSL_free(c->shared_sigalgs);
+ OPENSSL_free(c->ctypes);
+ X509_STORE_free(c->verify_store);
+ X509_STORE_free(c->chain_store);
+ custom_exts_free(&c->cli_ext);
+ custom_exts_free(&c->srv_ext);
+ OPENSSL_free(c);
+}
+
+int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
+{
+ int i, r;
+ CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
+ if (!cpk)
+ return 0;
+ sk_X509_pop_free(cpk->chain, X509_free);
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ r = ssl_security_cert(s, ctx, sk_X509_value(chain, i), 0, 0);
+ if (r != 1) {
+ SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r);
+ return 0;
+ }
+ }
+ cpk->chain = chain;
+ return 1;
+}
+
+int ssl_cert_set1_chain(SSL *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);
+ if (!dchain)
+ return 0;
+ if (!ssl_cert_set0_chain(s, ctx, dchain)) {
+ sk_X509_pop_free(dchain, X509_free);
+ return 0;
+ }
+ return 1;
+}
+
+int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
+{
+ 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);
+ if (r != 1) {
+ SSLerr(SSL_F_SSL_CERT_ADD0_CHAIN_CERT, r);
+ 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(SSL *s, SSL_CTX *ctx, X509 *x)
+{
+ if (!ssl_cert_add0_chain_cert(s, ctx, x))
+ return 0;
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ 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++) {
+ CERT_PKEY *cpk = c->pkeys + i;
+ if (cpk->x509 == x && cpk->privatekey) {
+ c->key = cpk;
+ return 1;
+ }
+ }
+
+ for (i = 0; i < SSL_PKEY_NUM; i++) {
+ CERT_PKEY *cpk = c->pkeys + i;
+ if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) {
+ c->key = cpk;
+ 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++) {
+ CERT_PKEY *cpk = c->pkeys + i;
+ if (cpk->x509 && cpk->privatekey) {
+ c->key = cpk;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg)
+{
+ c->cert_cb = cb;
+ c->cert_cb_arg = arg;
+}
+
+int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
+{
+ X509 *x;
+ int i;
+ X509_STORE *verify_store;
+ X509_STORE_CTX ctx;
+
+ if (s->cert->verify_store)
+ verify_store = s->cert->verify_store;
+ else
+ verify_store = s->ctx->cert_store;
+
+ if ((sk == NULL) || (sk_X509_num(sk) == 0))
+ return (0);
+
+ x = sk_X509_value(sk, 0);
+ if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) {
+ 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));
+ X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
+
+ /*
+ * We need to inherit the verify parameters. These can be determined by
+ * the context: if its a server it will verify SSL client certificates or
+ * vice versa.
+ */
+
+ X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
+ /*
+ * Anything non-default in "param" should overwrite anything in the ctx.
+ */
+ X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
+
+ if (s->verify_callback)
+ X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+
+ if (s->ctx->app_verify_callback != NULL)
+ i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
+ else {
+ i = X509_verify_cert(&ctx);
+# if 0
+ /* Dummy error calls so mkerr generates them */
+ SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_EE_KEY_TOO_SMALL);
+ SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_CA_KEY_TOO_SMALL);
+ SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_CA_MD_TOO_WEAK);
+# endif
+ if (i > 0)
+ i = ssl_security_cert_chain(s, ctx.chain, NULL, 1);
+ }
+
+ s->verify_result = ctx.error;
+ X509_STORE_CTX_cleanup(&ctx);
+
+ return (i);
+}
+
+static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
+ STACK_OF(X509_NAME) *name_list)
+{
+ sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
+ *ca_list = name_list;
+}