1cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler/* 2cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * Copyright (C) 2017 The Android Open Source Project 3cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * 4cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * Licensed under the Apache License, Version 2.0 (the "License"); 5cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * you may not use this file except in compliance with the License. 6cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * You may obtain a copy of the License at 7cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * 8cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * http://www.apache.org/licenses/LICENSE-2.0 9cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * 10cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * Unless required by applicable law or agreed to in writing, software 11cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * distributed under the License is distributed on an "AS IS" BASIS, 12cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * See the License for the specific language governing permissions and 14cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler * limitations under the License. 15cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler */ 16cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 17cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#include <conscrypt/jniutil.h> 18cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 19cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#include <conscrypt/compat.h> 20cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#include <conscrypt/trace.h> 21cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#include <cstdlib> 22cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#include <errno.h> 23cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 24cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlernamespace conscrypt { 25cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlernamespace jniutil { 26cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 27cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerJavaVM *gJavaVM; 28cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass cryptoUpcallsClass; 29cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass openSslInputStreamClass; 30cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass nativeRefClass; 31cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 32cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass byteArrayClass; 33cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass calendarClass; 34cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass objectClass; 35cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass objectArrayClass; 36cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass integerClass; 37cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass inputStreamClass; 38cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass outputStreamClass; 39cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerjclass stringClass; 40cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 41cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjfieldID nativeRef_context; 42cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 43cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID calendar_setMethod; 44cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID inputStream_readMethod; 45cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID integer_valueOfMethod; 46cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID openSslInputStream_readLineMethod; 47cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID outputStream_writeMethod; 48cd7a158c79e938d71584008964d05b2eb281d498Nathan MittlerjmethodID outputStream_flushMethod; 49cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 50cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlervoid init(JavaVM* vm, JNIEnv* env) { 51cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler gJavaVM = vm; 52cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 53cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler byteArrayClass = findClass(env, "[B"); 54cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler calendarClass = findClass(env, "java/util/Calendar"); 55cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler inputStreamClass = findClass(env, "java/io/InputStream"); 56cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler integerClass = findClass(env, "java/lang/Integer"); 57cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler objectClass = findClass(env, "java/lang/Object"); 58cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler objectArrayClass = findClass(env, "[Ljava/lang/Object;"); 59cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler outputStreamClass = findClass(env, "java/io/OutputStream"); 60cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler stringClass = findClass(env, "java/lang/String"); 61cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 62cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler cryptoUpcallsClass = getGlobalRefToClass( 63cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/CryptoUpcalls"); 64cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler nativeRefClass = getGlobalRefToClass( 65cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef"); 66cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler openSslInputStreamClass = getGlobalRefToClass( 67cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream"); 68cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 69cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler nativeRef_context = getFieldRef(env, nativeRefClass, "context", "J"); 70cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 71cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler calendar_setMethod = getMethodRef(env, calendarClass, "set", "(IIIIII)V"); 72cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler inputStream_readMethod = getMethodRef(env, inputStreamClass, "read", "([B)I"); 73cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler integer_valueOfMethod = 74cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env->GetStaticMethodID(integerClass, "valueOf", "(I)Ljava/lang/Integer;"); 75cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler openSslInputStream_readLineMethod = 76cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler getMethodRef(env, openSslInputStreamClass, "gets", "([B)I"); 77cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler outputStream_writeMethod = getMethodRef(env, outputStreamClass, "write", "([B)V"); 78cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler outputStream_flushMethod = getMethodRef(env, outputStreamClass, "flush", "()V"); 79cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 80cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 81cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlervoid jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, 82cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int numMethods) { 83cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ALOGV("Registering %s's %d native methods...", className, numMethods); 84cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 85cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ScopedLocalRef<jclass> c(env, env->FindClass(className)); 86cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (c.get() == nullptr) { 87cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char* msg; 88cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (void)asprintf(&msg, "Native registration unable to find class '%s'; aborting...", 89cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler className); 90cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env->FatalError(msg); 91cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 92cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 93cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (env->RegisterNatives(c.get(), gMethods, numMethods) < 0) { 94cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char* msg; 95cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (void)asprintf(&msg, "RegisterNatives failed for '%s'; aborting...", className); 96cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env->FatalError(msg); 97cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 98cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 99cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 100cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) { 101cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ScopedLocalRef<jclass> localClass(env, env->FindClass("java/io/FileDescriptor")); 102cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ANDROID) && !defined(CONSCRYPT_OPENJDK) 103cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler static jfieldID fid = env->GetFieldID(localClass.get(), "descriptor", "I"); 104cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#else /* !ANDROID || CONSCRYPT_OPENJDK */ 105cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler static jfieldID fid = env->GetFieldID(localClass.get(), "fd", "I"); 106cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 107cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (fileDescriptor != nullptr) { 108cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return env->GetIntField(fileDescriptor, fid); 109cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } else { 110cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return -1; 111cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 112cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 113cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 114cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerbool isGetByteArrayElementsLikelyToReturnACopy(size_t size) { 115cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ANDROID) && !defined(CONSCRYPT_OPENJDK) 116cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // ART's GetByteArrayElements creates copies only for arrays smaller than 12 kB. 117cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return size <= 12 * 1024; 118cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#else 119cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (void)size; 120cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // On OpenJDK based VMs GetByteArrayElements appears to always create a copy. 121cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return true; 122cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 123cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 124cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 125be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianint throwException(JNIEnv* env, const char* className, const char* msg) { 126cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler jclass exceptionClass = env->FindClass(className); 127cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 128cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (exceptionClass == nullptr) { 129cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ALOGD("Unable to find exception class %s", className); 130cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler /* ClassNotFoundException now pending */ 131cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return -1; 132cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 133cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 134cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (env->ThrowNew(exceptionClass, msg) != JNI_OK) { 135cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ALOGD("Failed throwing '%s' '%s'", className, msg); 136cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler /* an exception, most likely OOM, will now be pending */ 137cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return -1; 138cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 139cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 140cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler env->DeleteLocalRef(exceptionClass); 141cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return 0; 142cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 143cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 144be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianint throwRuntimeException(JNIEnv* env, const char* msg) { 145be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/lang/RuntimeException", msg); 146cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 147cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 148be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianint throwAssertionError(JNIEnv* env, const char* msg) { 149be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/lang/AssertionError", msg); 150cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 151cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 152be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianint throwNullPointerException(JNIEnv* env, const char* msg) { 153be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/lang/NullPointerException", msg); 154be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian} 155be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian 156be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianint throwOutOfMemory(JNIEnv* env, const char* message) { 157be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/lang/OutOfMemoryError", message); 158cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 159cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 160cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwBadPaddingException(JNIEnv* env, const char* message) { 161cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwBadPaddingException %s", message); 162be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "javax/crypto/BadPaddingException", message); 163cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 164cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 165cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSignatureException(JNIEnv* env, const char* message) { 166cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwSignatureException %s", message); 167be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/security/SignatureException", message); 168cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 169cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 170cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwInvalidKeyException(JNIEnv* env, const char* message) { 171cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwInvalidKeyException %s", message); 172be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/security/InvalidKeyException", message); 173cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 174cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 175cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwIllegalBlockSizeException(JNIEnv* env, const char* message) { 176cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwIllegalBlockSizeException %s", message); 177be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException( 17837da11e7b50e02d9271a611ca8db5544bf3464a1Adam Vartanian env, "javax/crypto/IllegalBlockSizeException", message); 179cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 180cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 181cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwNoSuchAlgorithmException(JNIEnv* env, const char* message) { 182cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwUnknownAlgorithmException %s", message); 183be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException( 18437da11e7b50e02d9271a611ca8db5544bf3464a1Adam Vartanian env, "java/security/NoSuchAlgorithmException", message); 185cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 186cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 187cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwIOException(JNIEnv* env, const char* message) { 188cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwIOException %s", message); 189be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/io/IOException", message); 190cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 191cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 192cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwParsingException(JNIEnv* env, const char* message) { 193be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, TO_STRING(JNI_JARJAR_PREFIX) 194cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler "org/conscrypt/OpenSSLX509CertificateFactory$ParsingException", 195cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler message); 196cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 197cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 198cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwInvalidAlgorithmParameterException(JNIEnv* env, const char* message) { 199cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwInvalidAlgorithmParameterException %s", message); 200be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException( 20137da11e7b50e02d9271a611ca8db5544bf3464a1Adam Vartanian env, "java/security/InvalidAlgorithmParameterException", message); 202cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 203cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 204cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwForAsn1Error(JNIEnv* env, int reason, const char* message, 205cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*defaultThrow)(JNIEnv*, const char*)) { 206cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (reason) { 207cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE: 208cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ASN1_R_UNABLE_TO_DECODE_RSA_KEY) 209cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNABLE_TO_DECODE_RSA_KEY: 210cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 211cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ASN1_R_WRONG_PUBLIC_KEY_TYPE) 212cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_WRONG_PUBLIC_KEY_TYPE: 213cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 214cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY) 215cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY: 216cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 217cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE) 218cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE: 219cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 220cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwInvalidKeyException(env, message); 221cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 222cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM: 223cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM: 224cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwNoSuchAlgorithmException(env, message); 225cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 226cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 227cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return defaultThrow(env, message); 228cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 229cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 230cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwForCipherError(JNIEnv* env, int reason, const char* message, 231cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*defaultThrow)(JNIEnv*, const char*)) { 232cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (reason) { 233cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_BAD_DECRYPT: 234cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwBadPaddingException(env, message); 235cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 236cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH: 237cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_WRONG_FINAL_BLOCK_LENGTH: 238cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwIllegalBlockSizeException(env, message); 239cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 240cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_AES_KEY_SETUP_FAILED: 241cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_BAD_KEY_LENGTH: 242cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case CIPHER_R_UNSUPPORTED_KEY_SIZE: 243cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwInvalidKeyException(env, message); 244cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 245cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 246cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return defaultThrow(env, message); 247cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 248cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 249cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwForEvpError(JNIEnv* env, int reason, const char* message, 250cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*defaultThrow)(JNIEnv*, const char*)) { 251cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (reason) { 252cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case EVP_R_MISSING_PARAMETERS: 253cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwInvalidKeyException(env, message); 254cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 255cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case EVP_R_UNSUPPORTED_ALGORITHM: 256cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(EVP_R_X931_UNSUPPORTED) 257cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case EVP_R_X931_UNSUPPORTED: 258cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 259cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwNoSuchAlgorithmException(env, message); 260cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 261cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(EVP_R_WRONG_PUBLIC_KEY_TYPE) 262cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case EVP_R_WRONG_PUBLIC_KEY_TYPE: 263cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwInvalidKeyException(env, message); 264cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 265cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 266cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM) 267cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM: 268cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwNoSuchAlgorithmException(env, message); 269cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 270cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 271cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler default: 272cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return defaultThrow(env, message); 273cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 274cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 275cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 276cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 277cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwForRsaError(JNIEnv* env, int reason, const char* message, 278cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*defaultThrow)(JNIEnv*, const char*)) { 279cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (reason) { 280cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_BLOCK_TYPE_IS_NOT_01: 281cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_PKCS_DECODING_ERROR: 282cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#if defined(RSA_R_BLOCK_TYPE_IS_NOT_02) 283cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_BLOCK_TYPE_IS_NOT_02: 284cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler#endif 285cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwBadPaddingException(env, message); 286cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 287cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_BAD_SIGNATURE: 288cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_INVALID_MESSAGE_LENGTH: 289cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_WRONG_SIGNATURE_LENGTH: 290cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwSignatureException(env, message); 291cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 292cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_UNKNOWN_ALGORITHM_TYPE: 293cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwNoSuchAlgorithmException(env, message); 294cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 295cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_MODULUS_TOO_LARGE: 296cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_NO_PUBLIC_EXPONENT: 297cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwInvalidKeyException(env, message); 298cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 29960836adf1bf204ed8e666568c73276973b9ac048Adam Vartanian case RSA_R_DATA_TOO_LARGE: 30060836adf1bf204ed8e666568c73276973b9ac048Adam Vartanian case RSA_R_DATA_TOO_LARGE_FOR_MODULUS: 301cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE: 302cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwIllegalBlockSizeException(env, message); 303cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 304cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 305cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return defaultThrow(env, message); 306cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 307cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 308cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwForX509Error(JNIEnv* env, int reason, const char* message, 309cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*defaultThrow)(JNIEnv*, const char*)) { 310cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (reason) { 311cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case X509_R_UNSUPPORTED_ALGORITHM: 312cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return throwNoSuchAlgorithmException(env, message); 313cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 314cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler default: 315cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return defaultThrow(env, message); 316cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 317cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 318cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 319cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 320be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanianvoid throwExceptionFromBoringSSLError(JNIEnv* env, CONSCRYPT_UNUSED const char* location, 321be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian int (*defaultThrow)(JNIEnv*, const char*)) { 322cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler const char* file; 323cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int line; 324cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler const char* data; 325cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int flags; 326cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // NOLINTNEXTLINE(runtime/int) 327cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler unsigned long error = ERR_get_error_line_data(&file, &line, &data, &flags); 328be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian 329be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian if (error == 0) { 330be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian throwAssertionError(env, "throwExceptionFromBoringSSLError called with no error"); 331be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return; 332be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian } 333cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 33470eb95881de277fce5b386a7b259892af090f2e6Adam Vartanian // If there's an error from BoringSSL it may have been caused by an exception in Java code, so 33570eb95881de277fce5b386a7b259892af090f2e6Adam Vartanian // ensure there isn't a pending exception before we throw a new one. 336be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian if (!env->ExceptionCheck()) { 337cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char message[256]; 338cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ERR_error_string_n(error, message, sizeof(message)); 339cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int library = ERR_GET_LIB(error); 340cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int reason = ERR_GET_REASON(error); 341cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("OpenSSL error in %s error=%lx library=%x reason=%x (%s:%d): %s %s", location, 342cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler error, library, reason, file, line, message, 343cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (flags & ERR_TXT_STRING) ? data : "(no data)"); 344cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (library) { 345cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_RSA: 346cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwForRsaError(env, reason, message, defaultThrow); 347cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 348cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_ASN1: 349cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwForAsn1Error(env, reason, message, defaultThrow); 350cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 351cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_CIPHER: 352cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwForCipherError(env, reason, message, defaultThrow); 353cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 354cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_EVP: 355cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwForEvpError(env, reason, message, defaultThrow); 356cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 357cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_X509: 358cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwForX509Error(env, reason, message, defaultThrow); 359cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 360cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case ERR_LIB_DSA: 361cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler throwInvalidKeyException(env, message); 362cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 363cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler default: 364cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler defaultThrow(env, message); 365cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 366cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 367cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 368cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 369cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ERR_clear_error(); 370cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 371cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 372cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSocketTimeoutException(JNIEnv* env, const char* message) { 373cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwSocketTimeoutException %s", message); 374be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "java/net/SocketTimeoutException", message); 375cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 376cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 377cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSSLHandshakeExceptionStr(JNIEnv* env, const char* message) { 378cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwSSLExceptionStr %s", message); 379be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException( 38037da11e7b50e02d9271a611ca8db5544bf3464a1Adam Vartanian env, "javax/net/ssl/SSLHandshakeException", message); 381cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 382cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 383cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSSLExceptionStr(JNIEnv* env, const char* message) { 384cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwSSLExceptionStr %s", message); 385be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException(env, "javax/net/ssl/SSLException", message); 386cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 387cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 388cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) { 389cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler JNI_TRACE("throwSSLProtocolExceptionStr %s", message); 390be361cf9ce25c704982422ef47c4f4354daf3d9fAdam Vartanian return conscrypt::jniutil::throwException( 39137da11e7b50e02d9271a611ca8db5544bf3464a1Adam Vartanian env, "javax/net/ssl/SSLProtocolException", message); 392cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 393cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 394cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittlerint throwSSLExceptionWithSslErrors(JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message, 395cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int (*actualThrow)(JNIEnv*, const char*)) { 396cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (message == nullptr) { 397cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler message = "SSL error"; 398cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 399cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 400cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // First consult the SSL error code for the general message. 401cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler const char* sslErrorStr = nullptr; 402cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler switch (sslErrorCode) { 403cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_NONE: 404cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (ERR_peek_error() == 0) { 405cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "OK"; 406cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } else { 407cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = ""; 408cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 409cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 410cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_SSL: 411cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "Failure in SSL library, usually a protocol error"; 412cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 413cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_WANT_READ: 414cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this."; 415cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 416cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_WANT_WRITE: 417cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this."; 418cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 419cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_WANT_X509_LOOKUP: 420cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this."; 421cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 422cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_SYSCALL: 423cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "I/O error during system call"; 424cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 425cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_ZERO_RETURN: 426cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this."; 427cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 428cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_WANT_CONNECT: 429cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this."; 430cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 431cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler case SSL_ERROR_WANT_ACCEPT: 432cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this."; 433cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 434cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler default: 435cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler sslErrorStr = "Unknown SSL error"; 436cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 437cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 438cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // Prepend either our explicit message or a default one. 439cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char* str; 440cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) { 441cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // problem with asprintf, just throw argument message, log everything 442cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int ret = actualThrow(env, message); 443cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ALOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr); 444cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ERR_clear_error(); 445cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return ret; 446cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 447cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 448cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char* allocStr = str; 449cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 450cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // For protocol errors, SSL might have more information. 451cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) { 452cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // Append each error as an additional line to the message. 453cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler for (;;) { 454cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler char errStr[256]; 455cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler const char* file; 456cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int line; 457cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler const char* data; 458cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int flags; 459cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // NOLINTNEXTLINE(runtime/int) 460cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags); 461cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (err == 0) { 462cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 463cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 464cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 465cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ERR_error_string_n(err, errStr, sizeof(errStr)); 466cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 467cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)", 468cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (allocStr == nullptr) ? "" : allocStr, errStr, file, line, 469cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler (flags & ERR_TXT_STRING) ? data : "(no data)", flags); 470cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 471cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (ret < 0) { 472cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler break; 473cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 474cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 475cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler free(allocStr); 476cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler allocStr = str; 477cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 478cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // For errors during system calls, errno might be our friend. 479cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } else if (sslErrorCode == SSL_ERROR_SYSCALL) { 480cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) { 481cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler free(allocStr); 482cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler allocStr = str; 483cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 484cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler // If the error code is invalid, print it. 485cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) { 486cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) { 487cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler free(allocStr); 488cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler allocStr = str; 489cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 490cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 491cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 492cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler int ret; 493cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler if (sslErrorCode == SSL_ERROR_SSL) { 494cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ret = throwSSLProtocolExceptionStr(env, allocStr); 495cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } else { 496cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ret = actualThrow(env, allocStr); 497cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler } 498cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 499cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ALOGV("%s", allocStr); 500cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler free(allocStr); 501cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler ERR_clear_error(); 502cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler return ret; 503cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} 504cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler 505cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} // namespace jniutil 506cd7a158c79e938d71584008964d05b2eb281d498Nathan Mittler} // namespace conscrypt 507