]> granicus.if.org Git - apache/commitdiff
mod_ssl adjustments to help with using toolkits other than OpenSSL:
authorDoug MacEachern <dougm@apache.org>
Thu, 10 Jan 2002 04:55:19 +0000 (04:55 +0000)
committerDoug MacEachern <dougm@apache.org>
Thu, 10 Jan 2002 04:55:19 +0000 (04:55 +0000)
  Use SSL functions/macros instead of directly dereferencing SSL
  structures wherever possible.
  Add type-casts for the cases where functions return a generic pointer.
  Add $SSL/include to configure search path.
PR:
Obtained from:
Submitted by: Madhusudan Mathihalli <madhusudan_mathihalli@hp.com>
Reviewed by: dougm

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@92800 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
acinclude.m4
modules/ssl/mod_ssl.h
modules/ssl/ssl_engine_init.c
modules/ssl/ssl_engine_kernel.c
modules/ssl/ssl_engine_vars.c
modules/ssl/ssl_util.c
modules/ssl/ssl_util_ssl.c

diff --git a/CHANGES b/CHANGES
index 98c32691154ee26610d6f234d7fd3e6bc59deb12..4a9a79e079179cb6b0a82f4c671faf29c65f6991 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,11 @@
 Changes with Apache 2.0.31-dev
+  *) mod_ssl adjustments to help with using toolkits other than OpenSSL:
+      Use SSL functions/macros instead of directly dereferencing SSL
+      structures wherever possible.
+      Add type-casts for the cases where functions return a generic pointer.
+      Add $SSL/include to configure search path.
+     [Madhusudan Mathihalli <madhusudan_mathihalli@hp.com>]
+
   *) Moved several pointers out of the shared Scoreboard so it is
      more portable, and will present the vhost name across server
      generation restarts.  [William Rowe]
index bda7b56b918e5e1df0bdc7a0b123b8c5477e9fb0..dc47ddc01bb21b4aeb478f3bb4c6b78ae06d334d 100644 (file)
@@ -451,6 +451,9 @@ if test "x$ap_ssltk_base" = "x"; then
     if test -f "$p/openssl/ssl.h"; then
       ap_ssltk_incdir="$p"
       break
+    elif test -f "$p/ssl.h"; then
+      ap_ssltk_incdir="$p"
+      break
     fi
   done
   if test "x$ap_ssltk_incdir" = "x"; then
index b5e98325419a7af2c4324a91713184e92070f776..19dc1e549da44f45656154065a059f22be1c40a3 100644 (file)
@@ -345,6 +345,31 @@ typedef enum {
 
 #ifndef X509_V_ERR_CERT_UNTRUSTED
 #define X509_V_ERR_CERT_UNTRUSTED 27
+
+#endif
+
+#ifdef OPENSSL_VERSION_NUMBER
+
+#define EVP_PKEY_key_type(k)              (EVP_PKEY_type(k->type))
+
+#define X509_NAME_get_entries(xs)         (xs->entries)
+#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber)
+
+#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm)
+#define X509_get_key_algorithm(xs)       (xs->cert_info->key->algor->algorithm)
+
+#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data)
+#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length)
+
+#define SSL_CTX_get_extra_certs(ctx)       (ctx->extra_certs)
+#define SSL_CTX_set_extra_certs(ctx,value) {ctx->extra_certs = value;}
+
+#define SSL_CIPHER_get_name(s)             (s->name)
+#define SSL_CIPHER_get_valid(s)            (s->valid)
+
+#define SSL_SESSION_get_session_id(s)      (s->session_id)
+#define SSL_SESSION_get_session_id_length(s) (s->session_id_length)
+
 #endif
 
 #define ssl_verify_error_is_optional(errnum) \
index 26fb44db57782f2b15247e81799dd337216459a1..7d4e4e197d2c76bdd26edcf064a768efb5f470ff 100644 (file)
@@ -604,7 +604,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
                     "CA certificates for client authentication", cpVHostID);
             ssl_die();
         }
-        SSL_CTX_set_client_CA_list(sc->pSSLCtx, skCAList);
+        SSL_CTX_set_client_CA_list(sc->pSSLCtx, (STACK *)skCAList);
     }
 
     /*
@@ -628,7 +628,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
      * should take place. This cannot work.
      */
     if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
-        skCAList = SSL_CTX_get_client_CA_list(ctx);
+        skCAList = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx);
         if (sk_X509_NAME_num(skCAList) == 0)
             ssl_log(s, SSL_LOG_WARN,
                     "Init: Ops, you want to request client authentication, "
@@ -785,7 +785,7 @@ void ssl_init_ConfigureServer(server_rec *s, apr_pool_t *p, SSLSrvConfigRec *sc)
         && sc->pPrivateKey[SSL_AIDX_DSA] != NULL) {
         pKey = X509_get_pubkey(sc->pPublicCert[SSL_AIDX_DSA]);
         if (   pKey != NULL
-            && EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA 
+            && EVP_PKEY_key_type(pKey) == EVP_PKEY_DSA 
             && EVP_PKEY_missing_parameters(pKey))
             EVP_PKEY_copy_parameters(pKey, sc->pPrivateKey[SSL_AIDX_DSA]);
     }
@@ -924,7 +924,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *pp, const ch
      * Process CA certificate bundle file
      */
     if (cpCAfile != NULL) {
-        sk = SSL_load_client_CA_file(cpCAfile);
+        sk = (STACK_OF(X509_NAME) *)SSL_load_client_CA_file(cpCAfile);
         for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
             ssl_log(s, SSL_LOG_TRACE,
                     "CA certificate: %s",
@@ -941,7 +941,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, apr_pool_t *pp, const ch
         apr_dir_open(&dir, cpCApath, p);
         while ((apr_dir_read(&direntry, APR_FINFO_DIRENT, dir)) != APR_SUCCESS) {
             cp = apr_pstrcat(p, cpCApath, "/", direntry.name, NULL);
-            sk = SSL_load_client_CA_file(cp);
+            sk = (STACK_OF(X509_NAME) *)SSL_load_client_CA_file(cp);
             for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
                 ssl_log(s, SSL_LOG_TRACE,
                         "CA certificate: %s",
index 6d8091e659a9a9825383ba9570a2818306fc03c1..5226fa352379c6bc8722e49373fea3e120595930 100644 (file)
@@ -489,7 +489,7 @@ int ssl_hook_Access(request_rec *r)
         if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE)
             pCipher = SSL_get_current_cipher(ssl);
         else {
-            skCipherOld = SSL_get_ciphers(ssl);
+            skCipherOld = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
             if (skCipherOld != NULL)
                 skCipherOld = sk_SSL_CIPHER_dup(skCipherOld);
         }
@@ -502,7 +502,7 @@ int ssl_hook_Access(request_rec *r)
             return HTTP_FORBIDDEN;
         }
         /* determine whether a renegotiation has to be forced */
-        skCipher = SSL_get_ciphers(ssl);
+        skCipher = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
         if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) {
             /* optimized way */
             if ((pCipher == NULL && skCipher != NULL) ||
@@ -741,19 +741,23 @@ int ssl_hook_Access(request_rec *r)
          * here because it resets too much of the connection.  So we set the
          * state explicitly and continue the handshake manually.
          */
-        ssl_log(r->server, SSL_LOG_INFO, "Requesting connection re-negotiation");
+        ssl_log(r->server, SSL_LOG_INFO,
+                "Requesting connection re-negotiation");
         if (renegotiate_quick) {
             /* perform just a manual re-verification of the peer */
             ssl_log(r->server, SSL_LOG_TRACE,
-                    "Performing quick renegotiation: just re-verifying the peer");
+                    "Performing quick renegotiation: "
+                    "just re-verifying the peer");
             certstore = SSL_CTX_get_cert_store(ctx);
             if (certstore == NULL) {
-                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find certificate storage");
+                ssl_log(r->server, SSL_LOG_ERROR,
+                        "Cannot find certificate storage");
                 return HTTP_FORBIDDEN;
             }
-            certstack = SSL_get_peer_cert_chain(ssl);
+            certstack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl);
             if (certstack == NULL || sk_X509_num(certstack) == 0) {
-                ssl_log(r->server, SSL_LOG_ERROR, "Cannot find peer certificate chain");
+                ssl_log(r->server, SSL_LOG_ERROR,
+                        "Cannot find peer certificate chain");
                 return HTTP_FORBIDDEN;
             }
             cert = sk_X509_value(certstack, 0);
@@ -772,9 +776,11 @@ int ssl_hook_Access(request_rec *r)
         else {
             /* do a full renegotiation */
             ssl_log(r->server, SSL_LOG_TRACE,
-                    "Performing full renegotiation: complete handshake protocol");
+                    "Performing full renegotiation: "
+                    "complete handshake protocol");
             if (r->main != NULL)
-                SSL_set_session_id_context(ssl, (unsigned char *)&(r->main), sizeof(r->main));
+                SSL_set_session_id_context(ssl, (unsigned char *)&(r->main),
+                                           sizeof(r->main));
             else
                 SSL_set_session_id_context(ssl, (unsigned char *)&r, sizeof(r));
             /* will need to push to / pull from filters to renegotiate */
@@ -783,11 +789,13 @@ int ssl_hook_Access(request_rec *r)
             SSL_do_handshake(ssl);
 
             if (SSL_get_state(ssl) != SSL_ST_OK) {
-                ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation request failed");
+                ssl_log(r->server, SSL_LOG_ERROR,
+                        "Re-negotiation request failed");
                 ssl_bio_hooks_unset(ssl);
                 return HTTP_FORBIDDEN;
             }
-            ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake");
+            ssl_log(r->server, SSL_LOG_INFO,
+                    "Awaiting re-negotiation handshake");
             SSL_set_state(ssl, SSL_ST_ACCEPT);
             SSL_do_handshake(ssl);
 
@@ -795,7 +803,8 @@ int ssl_hook_Access(request_rec *r)
 
             if (SSL_get_state(ssl) != SSL_ST_OK) {
                 ssl_log(r->server, SSL_LOG_ERROR,
-                        "Re-negotiation handshake failed: Not accepted by client!?");
+                        "Re-negotiation handshake failed: "
+                        "Not accepted by client!?");
                 return HTTP_FORBIDDEN;
             }
         }
@@ -1124,7 +1133,7 @@ int ssl_hook_Fixup(request_rec *r)
         apr_table_set(e, "SSL_SERVER_CERT", val);
         val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_CERT");
         apr_table_set(e, "SSL_CLIENT_CERT", val);
-        if ((sk = SSL_get_peer_cert_chain(ssl)) != NULL) {
+        if ((sk = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl)) != NULL) {
             for (i = 0; i < sk_X509_num(sk); i++) {
                 var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i);
                 val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
@@ -1485,11 +1494,14 @@ int ssl_callback_SSLVerify_CRL(
 #else
             revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
 #endif
-            if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(xs)) == 0) {
+            if (ASN1_INTEGER_cmp(X509_REVOKED_get_serialNumber(revoked),
+                                 X509_get_serialNumber(xs)) == 0) {
+
 
                 if (sc->nLogLevel >= SSL_LOG_INFO) {
                     char *cp = X509_NAME_oneline(issuer, NULL, 0);
-                    long serial = ASN1_INTEGER_get(revoked->serialNumber);
+                    long serial = ASN1_INTEGER_get(
+                                       X509_REVOKED_get_serialNumber(revoked));
 
                     ssl_log(s, SSL_LOG_INFO,
                             "Certificate with serial %ld (0x%lX) "
@@ -1520,6 +1532,9 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
     SSLSrvConfigRec *sc;
     long t;
     BOOL rc;
+    unsigned char *session_id;
+    unsigned int session_id_length;
+
 
     /*
      * Get Apache context back through OpenSSL context
@@ -1539,8 +1554,12 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
      * Store the SSL_SESSION in the inter-process cache with the
      * same expire time, so it expires automatically there, too.
      */
+    session_id = SSL_SESSION_get_session_id(pNew);
+    session_id_length = SSL_SESSION_get_session_id_length(pNew);
+
     t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout);
-    rc = ssl_scache_store(s, pNew->session_id, pNew->session_id_length, t, pNew);
+    rc = ssl_scache_store(s, session_id, session_id_length, t, pNew);
+
 
     /*
      * Log this cache operation
@@ -1548,7 +1567,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew)
     ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
             "request=SET status=%s id=%s timeout=%ds (session caching)",
             rc == TRUE ? "OK" : "BAD",
-            SSL_SESSION_id2sz(pNew->session_id, pNew->session_id_length),
+            SSL_SESSION_id2sz(session_id, session_id_length),
             t-time(NULL));
 
     /*
@@ -1615,6 +1634,9 @@ void ssl_callback_DelSessionCacheEntry(
     SSL_CTX *ctx, SSL_SESSION *pSession)
 {
     server_rec *s;
+    unsigned char *session_id;
+    unsigned int session_id_length;
+
 
     /*
      * Get Apache context back through OpenSSL context
@@ -1626,15 +1648,18 @@ void ssl_callback_DelSessionCacheEntry(
     /*
      * Remove the SSL_SESSION from the inter-process cache
      */
-    ssl_scache_remove(s, pSession->session_id, pSession->session_id_length);
+    session_id = SSL_SESSION_get_session_id(pSession);
+    session_id_length = SSL_SESSION_get_session_id_length(pSession);
+
+    ssl_scache_remove(s, session_id, session_id_length);
+
 
     /*
      * Log this cache operation
      */
     ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: "
             "request=REM status=OK id=%s (session dead)",
-            SSL_SESSION_id2sz(pSession->session_id,
-            pSession->session_id_length));
+            SSL_SESSION_id2sz(session_id, session_id_length));
 
     return;
 }
index 6e2e1901667bfb4bb7d14c0ed67b59ad8e96f85a..3c5934f554ad4b7c997ceeefa18bea1d767bd627 100644 (file)
@@ -283,8 +283,9 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
     }
     else if (ssl != NULL && strcEQ(var, "SESSION_ID")) {
         SSL_SESSION *pSession = SSL_get_session(ssl);
-        result = apr_pstrdup(p, SSL_SESSION_id2sz(pSession->session_id, 
-                                                 pSession->session_id_length));
+        result = apr_pstrdup(p, SSL_SESSION_id2sz(
+                                SSL_SESSION_get_session_id(pSession),
+                                SSL_SESSION_get_session_id_length(pSession)));
     }
     else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
         result = ssl_var_lookup_ssl_cipher(p, c, var+6);
@@ -356,13 +357,15 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var)
         resdup = FALSE;
     }
     else if (strcEQ(var, "A_SIG")) {
-        nid = OBJ_obj2nid(xs->cert_info->signature->algorithm);
-        result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
+        nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_signature_algorithm(xs));
+        result = apr_pstrdup(p, 
+                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
         resdup = FALSE;
     }
     else if (strcEQ(var, "A_KEY")) {
-        nid = OBJ_obj2nid(xs->cert_info->key->algor->algorithm);
-        result = apr_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
+        nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_key_algorithm(xs));
+        result = apr_pstrdup(p,
+                             (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
         resdup = FALSE;
     }
     else if (strcEQ(var, "CERT")) {
@@ -400,21 +403,30 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
     char *result;
     X509_NAME_ENTRY *xsne;
     int i, j, n;
+    char *data_ptr;
+    int data_len;
 
     result = NULL;
 
     for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) {
         if (strEQ(var, ssl_var_lookup_ssl_cert_dn_rec[i].name)) {
-            for (j = 0; j < sk_X509_NAME_ENTRY_num(xsname->entries); j++) {
-                xsne = sk_X509_NAME_ENTRY_value(xsname->entries, j);
-                n = OBJ_obj2nid(xsne->object);
+            for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
+                                                 X509_NAME_get_entries(xsname));
+                 j++) {
+                xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
+                                             X509_NAME_get_entries(xsname), j);
+
+                n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
+                data_ptr = X509_NAME_ENTRY_get_data_ptr(xsne);
+                data_len = X509_NAME_ENTRY_get_data_len(xsne);
+
                 if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid) {
-                    result = apr_palloc(p, xsne->value->length+1);
-                    apr_cpystrn(result, (char *)xsne->value->data, xsne->value->length+1);
+                    result = apr_palloc(p, data_len+1);
+                    apr_cpystrn(result, (char *)data_ptr, data_len+1);
 #ifdef CHARSET_EBCDIC
                     ascii2ebcdic(result, result, xsne->value->length);
 #endif /* CHARSET_EBCDIC */
-                    result[xsne->value->length] = NUL;
+                    result[data_len] = NUL;
                     break;
                 }
             }
index 2dd65083cf3284b2c344fcc01309633764677269..f4ca8ac656e2b01c8b955a261277e50e2391cf70 100644 (file)
@@ -221,7 +221,7 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
     if (pCert != NULL)
         pKey = X509_get_pubkey(pCert);
     if (pKey != NULL) {
-        switch (EVP_PKEY_type(pKey->type)) {
+        switch (EVP_PKEY_key_type(pKey)) {
             case EVP_PKEY_RSA: 
                 t = SSL_ALGO_RSA;
                 break;
index cc5d6cf04bda9712c83808f26cde44da0aac5dc7..b68ed6685e16c6795d75b86cc00516b9d04b8a41 100644 (file)
@@ -284,12 +284,12 @@ char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl)
 
     if (ssl == NULL) 
         return "";
-    if ((sk = SSL_get_ciphers(ssl)) == NULL)
+    if ((sk = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl)) == NULL)
         return "";
     l = 0;
     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
         c = sk_SSL_CIPHER_value(sk, i);
-        l += strlen(c->name)+2+1;
+        l += strlen(SSL_CIPHER_get_name(c))+2+1;
     }
     if (l == 0)
         return "";
@@ -297,11 +297,11 @@ char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl)
     cp = cpCipherSuite;
     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
         c = sk_SSL_CIPHER_value(sk, i);
-        l = strlen(c->name);
-        memcpy(cp, c->name, l);
+        l = strlen(SSL_CIPHER_get_name(c));
+        memcpy(cp, SSL_CIPHER_get_name(c), l);
         cp += l;
         *cp++ = '/';
-        *cp++ = (c->valid == 1 ? '1' : '0');
+        *cp++ = (SSL_CIPHER_get_valid(c) == 1 ? '1' : '0');
         *cp++ = ':';
     }
     *(cp-1) = NUL;
@@ -378,15 +378,21 @@ BOOL SSL_X509_getCN(apr_pool_t *p, X509 *xs, char **cppCN)
     X509_NAME *xsn;
     X509_NAME_ENTRY *xsne;
     int i, nid;
+    char *data_ptr;
+    int data_len;
 
     xsn = X509_get_subject_name(xs);
-    for (i = 0; i < sk_X509_NAME_ENTRY_num(xsn->entries); i++) {
-        xsne = sk_X509_NAME_ENTRY_value(xsn->entries, i);
-        nid = OBJ_obj2nid(xsne->object);
+    for (i = 0; i < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
+                                           X509_NAME_get_entries(xsn)); i++) {
+        xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
+                                         X509_NAME_get_entries(xsn), i);
+        nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
         if (nid == NID_commonName) {
-            *cppCN = apr_palloc(p, xsne->value->length+1);
-            apr_cpystrn(*cppCN, (char *)xsne->value->data, xsne->value->length+1);
-            (*cppCN)[xsne->value->length] = NUL;
+            data_ptr = X509_NAME_ENTRY_get_data_ptr(xsne);
+            data_len = X509_NAME_ENTRY_get_data_len(xsne);
+            *cppCN = apr_palloc(p, data_len+1);
+            apr_cpystrn(*cppCN, (char *)data_ptr, data_len+1);
+            (*cppCN)[data_len] = NUL;
 #ifdef CHARSET_EBCDIC
             ascii2ebcdic(*cppCN, *cppCN, strlen(*cppCN));
 #endif
@@ -470,6 +476,7 @@ int SSL_CTX_use_certificate_chain(
     X509 *x509;
     unsigned long err;
     int n;
+    STACK *extra_certs;
 
     if ((bio = BIO_new(BIO_s_file_internal())) == NULL)
         return -1;
@@ -490,9 +497,10 @@ int SSL_CTX_use_certificate_chain(
         X509_free(x509);
     }
     /* free a perhaps already configured extra chain */
-    if (ctx->extra_certs != NULL) {
-        sk_X509_pop_free(ctx->extra_certs, X509_free);
-        ctx->extra_certs = NULL;
+    extra_certs=SSL_CTX_get_extra_certs(ctx);
+    if (extra_certs != NULL) {
+        sk_X509_pop_free((STACK_OF(X509) *)extra_certs, X509_free);
+        SSL_CTX_set_extra_certs(ctx,NULL);
     }
     /* create new extra chain by loading the certs */
     n = 0;