diff options
-rw-r--r-- | luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp index 8e82ef057b..b23adb7abb 100644 --- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp +++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp @@ -24,6 +24,7 @@ #include <fcntl.h> #include <sys/socket.h> #include <unistd.h> +#include <vector> #include <jni.h> @@ -154,6 +155,35 @@ struct X509_Delete { }; typedef UniquePtr<X509, X509_Delete> Unique_X509; +class X509Chain { + public: + X509Chain(size_t n) : x509s_(n) {} + + ~X509Chain() { + // TODO: C++0x auto + for (std::vector<X509*>::const_iterator it = x509s_.begin(); it != x509s_.end(); ++it) { + X509_free(*it); + } + } + + X509*& operator[](size_t n) { + return x509s_[n]; + } + + X509* operator[](size_t n) const { + return x509s_[n]; + } + + X509* release(size_t i) { + X509* x = x509s_[i]; + x509s_[i] = NULL; + return x; + } + + private: + std::vector<X509*> x509s_; +}; + struct X509_NAME_Delete { void operator()(X509_NAME* p) const { X509_NAME_free(p); @@ -2968,7 +2998,7 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, return; } - Unique_X509 certificatesX509[length]; + X509Chain certificatesX509(length); for (int i = 0; i < length; i++) { ScopedLocalRef<jbyteArray> certificate(env, reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i))); @@ -2984,9 +3014,9 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, return; } const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get()); - certificatesX509[i].reset(d2i_X509(NULL, &tmp, buf.size())); + certificatesX509[i] = d2i_X509(NULL, &tmp, buf.size()); - if (certificatesX509[i].get() == NULL) { + if (certificatesX509[i] == NULL) { ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate"); SSL_clear(ssl); @@ -2995,9 +3025,9 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, } } - int ret = SSL_use_certificate(ssl, certificatesX509[0].get()); + int ret = SSL_use_certificate(ssl, certificatesX509[0]); if (ret == 1) { - OWNERSHIP_TRANSFERRED(certificatesX509[0]); + certificatesX509.release(0); } else { ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate"); @@ -3013,7 +3043,7 @@ static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, return; } for (int i = 1; i < length; i++) { - if (!sk_X509_push(chain.get(), certificatesX509[i].release())) { + if (!sk_X509_push(chain.get(), certificatesX509.release(i))) { jniThrowOutOfMemoryError(env, "Unable to push certificate"); JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl); return; |