- }
- if (c->cert_chain != NULL)
- sk_X509_pop_free(c->cert_chain,X509_free);
- Free(c);
- }
-
-int ssl_cert_instantiate(CERT **o, CERT *d)
- {
- CERT *n;
- if (o == NULL)
- {
- SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_PASSED_NULL_PARAMETER);
- return(0);
- }
- if (*o != NULL && (d == NULL || *o != d))
- return(1);
- if ((n = ssl_cert_new()) == NULL)
- {
- SSLerr(SSL_F_SSL_CERT_INSTANTIATE, ERR_R_MALLOC_FAILURE);
- return(0);
- }
- if (*o != NULL)
- ssl_cert_free(*o);
- *o = n;
- return(1);
- }
-
-int ssl_set_cert_type(CERT *c,int type)
- {
- c->cert_type=type;
- return(1);
- }
-
-int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
- {
- X509 *x;
- int i;
- X509_STORE_CTX ctx;
-
- if ((sk == NULL) || (sk_X509_num(sk) == 0))
- return(0);
-
- x=sk_X509_value(sk,0);
- X509_STORE_CTX_init(&ctx,s->ctx->cert_store,x,sk);
- X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),
- (char *)s);
-
- if (s->ctx->app_verify_callback != NULL)
- i=s->ctx->app_verify_callback(&ctx);
- else
- {
-#ifndef NO_X509_VERIFY
- i=X509_verify_cert(&ctx);
+ }
+ OPENSSL_free(c);
+}
+
+int ssl_cert_inst(CERT **o)
+{
+ /*
+ * Create a CERT if there isn't already one (which cannot really happen,
+ * as it is initially created in SSL_CTX_new; but the earlier code
+ * usually allows for that one being non-existant, so we follow that
+ * behaviour, as it might turn out that there actually is a reason for it
+ * -- but I'm not sure that *all* of the existing code could cope with
+ * s->cert being NULL, otherwise we could do without the initialization
+ * in SSL_CTX_new).
+ */
+
+ if (o == NULL) {
+ SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
+ return (0);
+ }
+ if (*o == NULL) {
+ if ((*o = ssl_cert_new()) == NULL) {
+ SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ }
+ return (1);
+}
+
+SESS_CERT *ssl_sess_cert_new(void)
+{
+ SESS_CERT *ret;
+
+ ret = OPENSSL_malloc(sizeof *ret);
+ if (ret == NULL) {
+ SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ memset(ret, 0, sizeof *ret);
+ ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
+ ret->references = 1;
+
+ return ret;
+}
+
+void ssl_sess_cert_free(SESS_CERT *sc)
+{
+ int i;
+
+ if (sc == NULL)
+ return;
+
+ i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
+#ifdef REF_PRINT
+ REF_PRINT("SESS_CERT", sc);
+#endif
+ if (i > 0)
+ return;
+#ifdef REF_CHECK
+ if (i < 0) {
+ fprintf(stderr, "ssl_sess_cert_free, bad reference count\n");
+ abort(); /* ok */
+ }
+#endif
+
+ /* i == 0 */
+ if (sc->cert_chain != NULL)
+ sk_X509_pop_free(sc->cert_chain, X509_free);
+ for (i = 0; i < SSL_PKEY_NUM; i++) {
+ if (sc->peer_pkeys[i].x509 != NULL)
+ X509_free(sc->peer_pkeys[i].x509);
+#if 0 /* We don't have the peer's private key.
+ * These lines are just * here as a reminder
+ * that we're still using a
+ * not-quite-appropriate * data structure. */
+ if (sc->peer_pkeys[i].privatekey != NULL)
+ EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
+#endif
+ }
+
+#ifndef OPENSSL_NO_RSA
+ if (sc->peer_rsa_tmp != NULL)
+ RSA_free(sc->peer_rsa_tmp);
+#endif
+#ifndef OPENSSL_NO_DH
+ if (sc->peer_dh_tmp != NULL)
+ DH_free(sc->peer_dh_tmp);
+#endif
+#ifndef OPENSSL_NO_ECDH
+ if (sc->peer_ecdh_tmp != NULL)
+ EC_KEY_free(sc->peer_ecdh_tmp);
+#endif
+
+ 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_CTX ctx;
+
+ if ((sk == NULL) || (sk_X509_num(sk) == 0))
+ return (0);
+
+ x = sk_X509_value(sk, 0);
+ if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
+ SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
+ return (0);
+ }
+#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);