Skip to content
Browse files

Improved client certificate and certificate chain support

Summary:
- openssl: add openssl support for specifying per key certificate chains
- libcore: properly implement client certificate request call back
- libcore: properly implement sending certificate chain
- libcore: properly implement retreiving local certificate chain
- libcore: added an SSLContext for non-OpenSSL SSLSocket creation

Details:

external/openssl

    Improve patch generate support by applying all other patches to
    baseline to remove cross polluting other patch changes into target
    patch. Move cleanup of ./Configure output to import script from
    openssl.config.

 	import_openssl.sh
	openssl.config

   Adding SSL_use_certificate_chain and SSL_get_certificate_chain to
   continue to finish most of remaining JSSE issues.

	include/openssl/ssl.h
	ssl/s3_both.c
	ssl/ssl.h
	ssl/ssl_locl.h
	ssl/ssl_rsa.c

   Updated patch (and list of input files to patch)

	patches/jsse.patch
	openssl.config

libcore

    Restoring SSLContextImpl as provider of non-OpenSSL SSLSocketImpl
    instances for interoperability testing. OpenSSLContextImpl is the
    new subclass that provides OpenSSLSocketImpl. JSSEProvider
    provides the old style SSLContexts, OpenSSLProvider provides the
    OpenSSL SSLContext, which includes the "default" context. Changed
    to register SSLContexts without aliases to match the RI.

	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/JSSEProvider.java
	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLProvider.java

	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/DefaultSSLContextImpl.java
	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLContextImpl.java
	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/SSLContextImpl.java

    Native interface updates to support OpenSSLSocketImpl improvements
    - KEY_TYPES now expanded based on what we are being provided by OpenSSL.
      keyType function now maps key type values received from
      clientCertificateRequested callback.
    - Removed remaining uses of string PEM encoding, now using ASN1 DER consistently
      Includes SSL_SESSION_get_peer_cert_chain, verifyCertificateChain
    - Fixed clientCertificateRequested to properly include all key
      types supported by server, not just the one from the cipher
      suite. We also now properly include the list of supported CAs to
      help the client select a certificate to use.
    - Fixed NativeCrypto.SSL_use_certificate implementation to use new
      SSL_use_certificate_chain function from openssl to pass chain to
      OpenSSL.
    - Added error handling of all uses of sk_*_push which can fail due to out of memory
    - Fixed compile warning due to missing JNI_TRACE argument
	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
	luni/src/main/native/NativeCrypto.cpp
	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java

    Pass this into chooseServerAlias call as well in significantly revamped choseClientAlias

	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java

    Minor code cleanup while reviewing diff between checkClientTrusted and checkServerTrusted

	luni/src/main/java/org/apache/harmony/xnet/provider/jsse/TrustManagerImpl.java

   Improvements to SSL test support to go along with client
   certificate and certificate chain changes. TestSSLContext now has
   separate contexts for the client and server (as well as seperate
   key stores information). TestKeyStore now is more realistic by
   default, creating a CA, intermediate CA, and separate client and
   server certificates, as well as a client keystore that simply
   contains the CA and no certificates.

	support/src/test/java/javax/net/ssl/TestKeyStore.java
	support/src/test/java/javax/net/ssl/TestSSLContext.java

     Tests tracking API changes. Tests involving cert chains now now
     updated to use TestKeyStore.assertChainLength to avoid hardwiring
     expected chain length in tests. These tests also now use
     TestSSLContext.assertClientCertificateChain to validate that the
     chain is properly constructed and trusted by a trust manager.

	luni/src/test/java/java/net/URLConnectionTest.java
	luni/src/test/java/javax/net/ssl/SSLContextTest.java
	luni/src/test/java/javax/net/ssl/SSLEngineTest.java
	luni/src/test/java/javax/net/ssl/SSLSessionContextTest.java
	luni/src/test/java/javax/net/ssl/SSLSessionTest.java
	luni/src/test/java/javax/net/ssl/SSLSocketTest.java
	support/src/test/java/java/security/StandardNames.java
	support/src/test/java/javax/net/ssl/TestSSLEnginePair.java
	support/src/test/java/javax/net/ssl/TestSSLSocketPair.java

frameworks/base

    Tracking change of SSLContextImpl to OpenSSLContextImpl

	core/java/android/net/SSLCertificateSocketFactory.java
	core/java/android/net/http/HttpsConnection.java
	tests/CoreTests/android/core/SSLPerformanceTest.java
	tests/CoreTests/android/core/SSLSocketTest.java

    Tracking changes to TestSSLContext

	core/tests/coretests/src/android/net/http/HttpsThroughHttpProxyTest.java

Change-Id: I792921617164a98467c500d7fe53dbd738adfa02
  • Loading branch information...
1 parent 81f8385 commit 4f16e619f191ec2041275b4ff5235663d583e484 @bdcgoogle bdcgoogle committed Jul 12, 2010
Showing with 193 additions and 32 deletions.
  1. +19 −7 import_openssl.sh
  2. +3 −0 include/openssl/ssl.h
  3. +3 −2 openssl.config
  4. +120 −22 patches/jsse.patch
  5. +8 −1 ssl/s3_both.c
  6. +3 −0 ssl/ssl.h
  7. +1 −0 ssl/ssl_locl.h
  8. +36 −0 ssl/ssl_rsa.c
View
26 import_openssl.sh
@@ -99,13 +99,14 @@ function main() {
function import() {
declare -r OPENSSL_SOURCE=$1
- untar $OPENSSL_SOURCE
- applypatches
+ untar $OPENSSL_SOURCE readonly
+ applypatches $OPENSSL_DIR
cd $OPENSSL_DIR
# Configure source (and print Makefile defines for review, see README.android)
./Configure $CONFIGURE_ARGS
+ rm -f apps/CA.pl.bak crypto/opensslconf.h.bak
echo
echo BEGIN Makefile defines to compare with android-config.mk
echo
@@ -182,8 +183,8 @@ function generate() {
declare -r OPENSSL_SOURCE=$2
untar $OPENSSL_SOURCE
+ applypatches $OPENSSL_DIR_ORIG $patch
prune
- applypatches
for i in $NEEDED_SOURCES; do
echo "Restoring $i"
@@ -197,14 +198,17 @@ function generate() {
function untar() {
declare -r OPENSSL_SOURCE=$1
+ declare -r readonly=$2
# Remove old source
cleantar
# Process new source
tar -zxf $OPENSSL_SOURCE
mv $OPENSSL_DIR $OPENSSL_DIR_ORIG
- find $OPENSSL_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
+ if [ ! -z $readonly ]; then
+ find $OPENSSL_DIR_ORIG -type f -print0 | xargs -0 chmod a-w
+ fi
tar -zxf $OPENSSL_SOURCE
}
@@ -220,12 +224,20 @@ function cleantar() {
}
function applypatches () {
- cd $OPENSSL_DIR
+ declare -r dir=$1
+ declare -r skip_patch=$2
+
+ cd $dir
# Apply appropriate patches
for i in $OPENSSL_PATCHES; do
- echo "Applying patch $i"
- patch -p1 < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
+ if [ ! "$skip_patch" = "patches/$i" ]; then
+ echo "Applying patch $i"
+ patch -p1 < ../patches/$i || die "Could not apply patches/$i. Fix source and run: $0 regenerate patches/$i"
+ else
+ echo "Skiping patch $i"
+ fi
+
done
# Cleanup patch output
View
3 include/openssl/ssl.h
@@ -1528,6 +1528,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
#ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
@@ -2014,6 +2016,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
#define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
#define SSL_F_SSL_USE_PRIVATEKEY 201
#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
View
5 openssl.config
@@ -59,7 +59,6 @@ PROBLEMS \
README \
README.ASN1 \
README.ENGINE \
-apps/CA.pl.bak \
apps/Makefile \
apps/pkey.c \
apps/pkeyparam.c \
@@ -101,7 +100,6 @@ crypto/modes/cts128.c \
crypto/modes/modes.h \
crypto/objects/Makefile \
crypto/ocsp/Makefile \
-crypto/opensslconf.h.bak
crypto/pem/Makefile \
crypto/pkcs12/Makefile \
crypto/pkcs7/Makefile \
@@ -194,9 +192,12 @@ OPENSSL_PATCHES_jsse_SOURCES="\
ssl/ssl.h \
ssl/d1_clnt.c \
ssl/s23_clnt.c \
+ssl/s3_both.c \
ssl/s3_clnt.c \
ssl/s3_srvr.c \
ssl/ssl_err.c \
ssl/ssl_lib.c \
+ssl/ssl_locl.h
+ssl/ssl_rsa.c \
ssl/ssl_sess.c \
"
View
142 patches/jsse.patch
@@ -1,6 +1,6 @@
---- openssl-1.0.0.orig/ssl/ssl.h 2010-01-06 09:37:38.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl.h 2010-05-03 01:44:52.000000000 -0700
-@@ -1083,6 +1090,9 @@ struct ssl_st
+--- openssl-1.0.0.orig/ssl/ssl.h 2010-07-13 22:24:27.000000000 +0000
++++ openssl-1.0.0/ssl/ssl.h 2010-07-13 22:24:27.000000000 +0000
+@@ -1090,6 +1090,9 @@ struct ssl_st
/* This can also be in the session once a session is established */
SSL_SESSION *session;
@@ -10,32 +10,49 @@
/* Default generate session ID callback. */
GEN_SESSION_CB generate_session_id;
-@@ -1500,6 +1512,7 @@ BIO * SSL_get_rbio(const SSL *s);
+@@ -1509,6 +1512,7 @@ BIO * SSL_get_rbio(const SSL *s);
BIO * SSL_get_wbio(const SSL *s);
#endif
int SSL_set_cipher_list(SSL *s, const char *str);
+int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
-@@ -1559,6 +1572,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_
+@@ -1524,6 +1528,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKE
+ int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+ int SSL_use_certificate(SSL *ssl, X509 *x);
+ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
++int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
++STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
+
+ #ifndef OPENSSL_NO_STDIO
+ int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+@@ -1568,6 +1574,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
+void SSL_set_session_creation_enabled(SSL *, int);
int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-@@ -2204,6 +2218,7 @@ void ERR_load_SSL_strings(void);
+@@ -2009,6 +2016,7 @@ void ERR_load_SSL_strings(void);
+ #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
+ #define SSL_F_SSL_USE_CERTIFICATE 198
+ #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
++#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
+ #define SSL_F_SSL_USE_CERTIFICATE_FILE 200
+ #define SSL_F_SSL_USE_PRIVATEKEY 201
+ #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
+@@ -2213,6 +2221,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
+#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000
#define SSL_R_SHORT_READ 219
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221
---- openssl-1.0.0.orig/ssl/d1_clnt.c 2010-01-26 11:46:29.000000000 -0800
-+++ openssl-1.0.0/ssl/d1_clnt.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/d1_clnt.c 2010-01-26 19:46:29.000000000 +0000
++++ openssl-1.0.0/ssl/d1_clnt.c 2010-07-13 22:24:27.000000000 +0000
@@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s)
#endif
(s->session->not_resumable))
@@ -49,8 +66,8 @@
if (!ssl_get_new_session(s,0))
goto err;
}
---- openssl-1.0.0.orig/ssl/s23_clnt.c 2010-02-16 06:20:40.000000000 -0800
-+++ openssl-1.0.0/ssl/s23_clnt.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/s23_clnt.c 2010-02-16 14:20:40.000000000 +0000
++++ openssl-1.0.0/ssl/s23_clnt.c 2010-07-13 22:24:27.000000000 +0000
@@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s
/* Since, if we are sending a ssl23 client hello, we are not
@@ -65,9 +82,35 @@
if (!ssl_get_new_session(s,0))
goto err;
---- openssl-1.0.0.orig/ssl/s3_clnt.c 2010-02-27 16:24:24.000000000 -0800
-+++ openssl-1.0.0/ssl/s3_clnt.c 2010-05-12 22:07:36.000000000 -0700
-@@ -621,6 +668,12 @@ int ssl3_client_hello(SSL *s)
+--- openssl-1.0.0.orig/ssl/s3_both.c 2010-07-13 22:24:27.000000000 +0000
++++ openssl-1.0.0/ssl/s3_both.c 2010-07-13 22:24:27.000000000 +0000
+@@ -322,8 +322,11 @@ unsigned long ssl3_output_cert_chain(SSL
+ unsigned long l=7;
+ BUF_MEM *buf;
+ int no_chain;
++ STACK_OF(X509) *cert_chain;
+
+- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
++ cert_chain = SSL_get_certificate_chain(s, x);
++
++ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
+ no_chain = 1;
+ else
+ no_chain = 0;
+@@ -375,6 +378,10 @@ unsigned long ssl3_output_cert_chain(SSL
+ return(0);
+ }
+
++ for (i=0; i<sk_X509_num(cert_chain); i++)
++ if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
++ return(0);
++
+ l-=7;
+ p=(unsigned char *)&(buf->data[4]);
+ l2n3(l,p);
+--- openssl-1.0.0.orig/ssl/s3_clnt.c 2010-07-13 22:24:27.000000000 +0000
++++ openssl-1.0.0/ssl/s3_clnt.c 2010-07-13 22:24:27.000000000 +0000
+@@ -668,6 +668,12 @@ int ssl3_client_hello(SSL *s)
#endif
(sess->not_resumable))
{
@@ -80,7 +123,7 @@
if (!ssl_get_new_session(s,0))
goto err;
}
-@@ -829,6 +882,12 @@ int ssl3_get_server_hello(SSL *s)
+@@ -876,6 +882,12 @@ int ssl3_get_server_hello(SSL *s)
s->hit=0;
if (s->session->session_id_length > 0)
{
@@ -93,8 +136,8 @@
if (!ssl_get_new_session(s,0))
{
al=SSL_AD_INTERNAL_ERROR;
---- openssl-1.0.0.orig/ssl/s3_srvr.c 2010-02-27 15:04:10.000000000 -0800
-+++ openssl-1.0.0/ssl/s3_srvr.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/s3_srvr.c 2010-02-27 23:04:10.000000000 +0000
++++ openssl-1.0.0/ssl/s3_srvr.c 2010-07-13 22:24:27.000000000 +0000
@@ -869,6 +869,12 @@ int ssl3_get_client_hello(SSL *s)
*/
if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
@@ -121,8 +164,8 @@
if (!ssl_get_new_session(s,1))
goto err;
}
---- openssl-1.0.0.orig/ssl/ssl_err.c 2010-01-06 09:37:38.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_err.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/ssl_err.c 2010-01-06 17:37:38.000000000 +0000
++++ openssl-1.0.0/ssl/ssl_err.c 2010-07-13 22:24:27.000000000 +0000
@@ -462,6 +462,7 @@ static ERR_STRING_DATA SSL_str_reasons[]
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
@@ -131,8 +174,8 @@
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
{ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"},
---- openssl-1.0.0.orig/ssl/ssl_lib.c 2010-02-17 11:43:46.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_lib.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/ssl_lib.c 2010-07-13 22:24:27.000000000 +0000
++++ openssl-1.0.0/ssl/ssl_lib.c 2010-07-13 22:24:27.000000000 +0000
@@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx)
OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
@@ -174,8 +217,63 @@
/* works well for SSLv2, not so good for SSLv3 */
char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
{
---- openssl-1.0.0.orig/ssl/ssl_sess.c 2010-02-01 08:49:42.000000000 -0800
-+++ openssl-1.0.0/ssl/ssl_sess.c 2010-05-12 22:07:36.000000000 -0700
+--- openssl-1.0.0.orig/ssl/ssl_locl.h 2009-12-08 11:38:18.000000000 +0000
++++ openssl-1.0.0/ssl/ssl_locl.h 2010-07-13 22:24:27.000000000 +0000
+@@ -456,6 +456,7 @@
+ typedef struct cert_pkey_st
+ {
+ X509 *x509;
++ STACK_OF(X509) *cert_chain;
+ EVP_PKEY *privatekey;
+ } CERT_PKEY;
+
+--- openssl-1.0.0.orig/ssl/ssl_rsa.c 2009-09-12 23:09:26.000000000 +0000
++++ openssl-1.0.0/ssl/ssl_rsa.c 2010-07-13 22:24:27.000000000 +0000
+@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type
+ }
+
+
++int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
++ {
++ if (ssl == NULL)
++ {
++ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
++ return(0);
++ }
++ if (ssl->cert == NULL)
++ {
++ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
++ return(0);
++ }
++ if (ssl->cert->key == NULL)
++ {
++ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
++ return(0);
++ }
++ ssl->cert->key->cert_chain = cert_chain;
++ return(1);
++ }
++
++STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
++ {
++ int i;
++ if (x == NULL)
++ return NULL;
++ if (ssl == NULL)
++ return NULL;
++ if (ssl->cert == NULL)
++ return NULL;
++ for (i = 0; i < SSL_PKEY_NUM; i++)
++ if (ssl->cert->pkeys[i].x509 == x)
++ return ssl->cert->pkeys[i].cert_chain;
++ return NULL;
++ }
++
+ #ifndef OPENSSL_NO_STDIO
+ /* Read a file that contains our certificate in "PEM" format,
+ * possibly followed by a sequence of CA certificates that should be
+--- openssl-1.0.0.orig/ssl/ssl_sess.c 2010-02-01 16:49:42.000000000 +0000
++++ openssl-1.0.0/ssl/ssl_sess.c 2010-07-13 22:24:27.000000000 +0000
@@ -261,6 +261,11 @@ static int def_generate_session_id(const
return 0;
}
View
9 ssl/s3_both.c
@@ -322,8 +322,11 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
unsigned long l=7;
BUF_MEM *buf;
int no_chain;
+ STACK_OF(X509) *cert_chain;
- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
+ cert_chain = SSL_get_certificate_chain(s, x);
+
+ if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
no_chain = 1;
else
no_chain = 0;
@@ -375,6 +378,10 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
return(0);
}
+ for (i=0; i<sk_X509_num(cert_chain); i++)
+ if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
+ return(0);
+
l-=7;
p=(unsigned char *)&(buf->data[4]);
l2n3(l,p);
View
3 ssl/ssl.h
@@ -1528,6 +1528,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
+STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);
#ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
@@ -2014,6 +2016,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
#define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
+#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
#define SSL_F_SSL_USE_PRIVATEKEY 201
#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
View
1 ssl/ssl_locl.h
@@ -456,6 +456,7 @@
typedef struct cert_pkey_st
{
X509 *x509;
+ STACK_OF(X509) *cert_chain;
EVP_PKEY *privatekey;
} CERT_PKEY;
View
36 ssl/ssl_rsa.c
@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
}
+int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
+ {
+ if (ssl == NULL)
+ {
+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
+ return(0);
+ }
+ if (ssl->cert == NULL)
+ {
+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+ return(0);
+ }
+ if (ssl->cert->key == NULL)
+ {
+ SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
+ return(0);
+ }
+ ssl->cert->key->cert_chain = cert_chain;
+ return(1);
+ }
+
+STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
+ {
+ int i;
+ if (x == NULL)
+ return NULL;
+ if (ssl == NULL)
+ return NULL;
+ if (ssl->cert == NULL)
+ return NULL;
+ for (i = 0; i < SSL_PKEY_NUM; i++)
+ if (ssl->cert->pkeys[i].x509 == x)
+ return ssl->cert->pkeys[i].cert_chain;
+ return NULL;
+ }
+
#ifndef OPENSSL_NO_STDIO
/* Read a file that contains our certificate in "PEM" format,
* possibly followed by a sequence of CA certificates that should be

0 comments on commit 4f16e61

Please sign in to comment.
Something went wrong with that request. Please try again.