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
diff --git a/patches/jsse.patch b/patches/jsse.patch
index b0ae319..09087de 100644
--- a/patches/jsse.patch
+++ b/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,7 +10,7 @@
/* 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);
@@ -18,7 +18,16 @@
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);
@@ -26,7 +35,15 @@
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
@@ -34,8 +51,8 @@
#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;
}