diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc index d1bd6b089..3ab6fbef3 100644 --- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc +++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc @@ -203,7 +203,7 @@ static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) { } static bssl::UniquePtr arrayToBignum(JNIEnv* env, jbyteArray source) { - BIGNUM *bn = nullptr; + BIGNUM* bn = nullptr; if (!arrayToBignum(env, source, &bn)) { return nullptr; } @@ -488,7 +488,7 @@ static long bio_stream_ctrl(BIO* b, int cmd, long, void*) { } } -static const BIO_METHOD *stream_bio_method() { +static const BIO_METHOD* stream_bio_method() { static const BIO_METHOD* stream_method = []() -> const BIO_METHOD* { BIO_METHOD* method = BIO_meth_new(0, nullptr); if (!method || !BIO_meth_set_write(method, bio_stream_write) || @@ -530,8 +530,7 @@ static jbyteArray ecSignDigestWithPrivateKey(JNIEnv* env, jobject privateKey, co return reinterpret_cast(env->CallStaticObjectMethod( conscrypt::jniutil::cryptoUpcallsClass, - conscrypt::jniutil::cryptoUpcallsClass_rawSignMethod, - privateKey, messageArray.get())); + conscrypt::jniutil::cryptoUpcallsClass_rawSignMethod, privateKey, messageArray.get())); } static jbyteArray rsaSignDigestWithPrivateKey(JNIEnv* env, jobject privateKey, jint padding, @@ -558,10 +557,9 @@ static jbyteArray rsaSignDigestWithPrivateKey(JNIEnv* env, jobject privateKey, j } return reinterpret_cast( - env->CallStaticObjectMethod( - conscrypt::jniutil::cryptoUpcallsClass, - conscrypt::jniutil::cryptoUpcallsClass_rsaSignMethod, - privateKey, padding, messageArray.get())); + env->CallStaticObjectMethod(conscrypt::jniutil::cryptoUpcallsClass, + conscrypt::jniutil::cryptoUpcallsClass_rsaSignMethod, + privateKey, padding, messageArray.get())); } // rsaDecryptWithPrivateKey uses privateKey to decrypt |ciphertext_len| bytes @@ -592,10 +590,9 @@ static jbyteArray rsaDecryptWithPrivateKey(JNIEnv* env, jobject privateKey, jint } return reinterpret_cast( - env->CallStaticObjectMethod( - conscrypt::jniutil::cryptoUpcallsClass, - conscrypt::jniutil::cryptoUpcallsClass_rsaDecryptMethod, - privateKey, padding, ciphertextArray.get())); + env->CallStaticObjectMethod(conscrypt::jniutil::cryptoUpcallsClass, + conscrypt::jniutil::cryptoUpcallsClass_rsaDecryptMethod, + privateKey, padding, ciphertextArray.get())); } // ********************************************* @@ -626,22 +623,14 @@ struct KeyExData { // ExDataDup is called when one of the RSA or EC_KEY objects is duplicated. We // don't support this and it should never happen. -int ExDataDup(CRYPTO_EX_DATA* /* to */, - const CRYPTO_EX_DATA* /* from */, - void** /* from_d */, - int /* index */, - long /* argl */ /* NOLINT(runtime/int) */, - void* /* argp */) { - return 0; +int ExDataDup(CRYPTO_EX_DATA* /* to */, const CRYPTO_EX_DATA* /* from */, void** /* from_d */, + int /* index */, long /* argl */ /* NOLINT(runtime/int) */, void* /* argp */) { + return 0; } // ExDataFree is called when one of the RSA or EC_KEY objects is freed. -void ExDataFree(void* /* parent */, - void* ptr, - CRYPTO_EX_DATA* /* ad */, - int /* index */, - long /* argl */ /* NOLINT(runtime/int) */, - void* /* argp */) { +void ExDataFree(void* /* parent */, void* ptr, CRYPTO_EX_DATA* /* ad */, int /* index */, + long /* argl */ /* NOLINT(runtime/int) */, void* /* argp */) { // Ensure the global JNI reference created with this wrapper is // properly destroyed with it. KeyExData* ex_data = reinterpret_cast(ptr); @@ -774,8 +763,8 @@ int EcdsaMethodSign(const uint8_t* digest, size_t digest_len, uint8_t* sig, unsi // Sign message with it through JNI. ScopedLocalRef signature( - env, ecSignDigestWithPrivateKey(env, private_key, - reinterpret_cast(digest), digest_len)); + env, ecSignDigestWithPrivateKey(env, private_key, reinterpret_cast(digest), + digest_len)); if (signature.get() == nullptr) { CONSCRYPT_LOG_ERROR("Could not sign message in EcdsaMethodDoSign!"); return 0; @@ -1228,9 +1217,8 @@ static jlong NativeCrypto_EVP_parse_private_key(JNIEnv* env, jclass, jbyteArray return reinterpret_cast(pkey.release()); } - -static jbyteArray NativeCrypto_EVP_raw_X25519_private_key( - JNIEnv* env, jclass cls, jbyteArray keyJavaBytes) { +static jbyteArray NativeCrypto_EVP_raw_X25519_private_key(JNIEnv* env, jclass cls, + jbyteArray keyJavaBytes) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("NativeCrypto_EVP_raw_X25519_private_key(%p)", keyJavaBytes); @@ -1259,8 +1247,8 @@ static jbyteArray NativeCrypto_EVP_raw_X25519_private_key( return nullptr; } - if (EVP_PKEY_get_raw_private_key( - pkey.get(), reinterpret_cast(bytes.get()), &key_length) == 0) { + if (EVP_PKEY_get_raw_private_key(pkey.get(), reinterpret_cast(bytes.get()), + &key_length) == 0) { conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_get_raw_private_key"); return nullptr; } @@ -1530,8 +1518,8 @@ static jint RSA_crypt_operation(RSACryptOperation operation, const char* caller, operation(static_cast(flen), reinterpret_cast(from.get()), reinterpret_cast(to.get()), rsa.get(), padding); if (resultSize == -1) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, caller, - conscrypt::jniutil::throwBadPaddingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, caller, conscrypt::jniutil::throwBadPaddingException); JNI_TRACE("%s => threw error", caller); return -1; } @@ -1697,8 +1685,9 @@ static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, job } static void NativeCrypto_chacha20_encrypt_decrypt(JNIEnv* env, jclass, jbyteArray inBytes, - jint inOffset, jbyteArray outBytes, jint outOffset, jint length, jbyteArray keyBytes, - jbyteArray nonceBytes, jint blockCounter) { + jint inOffset, jbyteArray outBytes, + jint outOffset, jint length, jbyteArray keyBytes, + jbyteArray nonceBytes, jint blockCounter) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("chacha20_encrypt_decrypt"); ScopedByteArrayRO in(env, inBytes); @@ -1722,13 +1711,10 @@ static void NativeCrypto_chacha20_encrypt_decrypt(JNIEnv* env, jclass, jbyteArra return; } - CRYPTO_chacha_20( - reinterpret_cast(out.get()) + outOffset, - reinterpret_cast(in.get()) + inOffset, - length, - reinterpret_cast(key.get()), - reinterpret_cast(nonce.get()), - blockCounter); + CRYPTO_chacha_20(reinterpret_cast(out.get()) + outOffset, + reinterpret_cast(in.get()) + inOffset, length, + reinterpret_cast(key.get()), + reinterpret_cast(nonce.get()), blockCounter); } static jlong NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava) { @@ -1815,7 +1801,8 @@ static jlong NativeCrypto_EC_GROUP_new_arbitrary(JNIEnv* env, jclass, jbyteArray return 0; } - if (!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(), x.get(), y.get(), ctx.get())) { + if (!EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(), x.get(), y.get(), + ctx.get())) { JNI_TRACE("EC_POINT_set_affine_coordinates_GFp => error"); conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EC_POINT_set_affine_coordinates_GFp"); @@ -2350,16 +2337,16 @@ static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass, jbyteArray outArr bssl::UniquePtr pubkey(EVP_PKEY_get1_EC_KEY(pubPkey)); if (pubkey.get() == nullptr) { JNI_TRACE("ECDH_compute_key(%p) => can't get public key", pubPkey); - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_get1_EC_KEY public", - conscrypt::jniutil::throwInvalidKeyException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "EVP_PKEY_get1_EC_KEY public", conscrypt::jniutil::throwInvalidKeyException); return -1; } const EC_POINT* pubkeyPoint = EC_KEY_get0_public_key(pubkey.get()); if (pubkeyPoint == nullptr) { JNI_TRACE("ECDH_compute_key(%p) => can't get public key point", pubPkey); - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_get1_EC_KEY public", - conscrypt::jniutil::throwInvalidKeyException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "EVP_PKEY_get1_EC_KEY public", conscrypt::jniutil::throwInvalidKeyException); return -1; } @@ -2371,8 +2358,8 @@ static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass, jbyteArray outArr bssl::UniquePtr privkey(EVP_PKEY_get1_EC_KEY(privPkey)); if (privkey.get() == nullptr) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_PKEY_get1_EC_KEY private", - conscrypt::jniutil::throwInvalidKeyException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "EVP_PKEY_get1_EC_KEY private", conscrypt::jniutil::throwInvalidKeyException); return -1; } @@ -2381,8 +2368,8 @@ static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass, jbyteArray outArr privkey.get(), nullptr /* No KDF */); if (outputLength == -1) { JNI_TRACE("ECDH_compute_key(%p) => outputLength = -1", pubPkey); - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "ECDH_compute_key", - conscrypt::jniutil::throwInvalidKeyException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "ECDH_compute_key", conscrypt::jniutil::throwInvalidKeyException); return -1; } @@ -2505,13 +2492,14 @@ static jint NativeCrypto_ECDSA_verify(JNIEnv* env, jclass, jbyteArray data, jbyt } static jboolean NativeCrypto_X25519(JNIEnv* env, jclass, jbyteArray outArray, - jbyteArray privkeyArray, jbyteArray pubkeyArray) { + jbyteArray privkeyArray, jbyteArray pubkeyArray) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("X25519(%p, %p, %p)", outArray, privkeyArray, pubkeyArray); ScopedByteArrayRW out(env, outArray); if (out.get() == nullptr) { - JNI_TRACE("X25519(%p, %p, %p) can't get output buffer", outArray, privkeyArray, pubkeyArray); + JNI_TRACE("X25519(%p, %p, %p) can't get output buffer", outArray, privkeyArray, + pubkeyArray); return JNI_FALSE; } @@ -2531,8 +2519,8 @@ static jboolean NativeCrypto_X25519(JNIEnv* env, jclass, jbyteArray outArray, reinterpret_cast(privkey.get()), reinterpret_cast(pubkey.get())) != 1) { JNI_TRACE("X25519(%p) => failure", outArray); - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "X25519", - conscrypt::jniutil::throwInvalidKeyException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "X25519", conscrypt::jniutil::throwInvalidKeyException); return JNI_FALSE; } @@ -2540,31 +2528,73 @@ static jboolean NativeCrypto_X25519(JNIEnv* env, jclass, jbyteArray outArray, return JNI_TRUE; } -static void NativeCrypto_X25519_keypair(JNIEnv* env, jclass, jbyteArray outPublicArray, jbyteArray outPrivateArray) { +static void NativeCrypto_X25519_keypair(JNIEnv* env, jclass, jbyteArray outPublicArray, + jbyteArray outPrivateArray) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("X25519_keypair(%p, %p)", outPublicArray, outPrivateArray); ScopedByteArrayRW outPublic(env, outPublicArray); if (outPublic.get() == nullptr) { - JNI_TRACE("X25519_keypair(%p, %p) can't get output public key buffer", outPublicArray, outPrivateArray); + JNI_TRACE("X25519_keypair(%p, %p) can't get output public key buffer", outPublicArray, + outPrivateArray); return; } ScopedByteArrayRW outPrivate(env, outPrivateArray); if (outPrivate.get() == nullptr) { - JNI_TRACE("X25519_keypair(%p, %p) can't get output private key buffer", outPublicArray, outPrivateArray); + JNI_TRACE("X25519_keypair(%p, %p) can't get output private key buffer", outPublicArray, + outPrivateArray); return; } - if (outPublic.size() != X25519_PUBLIC_VALUE_LEN || outPrivate.size() != X25519_PRIVATE_KEY_LEN) { - conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", "Output key array length != 32"); + if (outPublic.size() != X25519_PUBLIC_VALUE_LEN || + outPrivate.size() != X25519_PRIVATE_KEY_LEN) { + conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", + "Output key array length != 32"); return; } - X25519_keypair(reinterpret_cast(outPublic.get()), reinterpret_cast(outPrivate.get())); + X25519_keypair(reinterpret_cast(outPublic.get()), + reinterpret_cast(outPrivate.get())); JNI_TRACE("X25519_keypair(%p, %p) => success", outPublicArray, outPrivateArray); } +static void NativeCrypto_ED25519_keypair(JNIEnv* env, jclass, jbyteArray outPublicArray, + jbyteArray outPrivateArray) { + CHECK_ERROR_QUEUE_ON_RETURN; + JNI_TRACE("ED25519_keypair(%p, %p)", outPublicArray, outPrivateArray); + + ScopedByteArrayRW outPublic(env, outPublicArray); + if (outPublic.get() == nullptr) { + JNI_TRACE("ED25519_keypair(%p, %p) can't get output public key buffer", outPublicArray, + outPrivateArray); + return; + } + + ScopedByteArrayRW outPrivate(env, outPrivateArray); + if (outPrivate.get() == nullptr) { + JNI_TRACE("ED25519_keypair(%p, %p) can't get output private key buffer", outPublicArray, + outPrivateArray); + return; + } + + if (outPublic.size() != ED25519_PUBLIC_KEY_LEN) { + conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", + "Output public key array length != 32"); + return; + } + + if (outPrivate.size() != ED25519_PRIVATE_KEY_LEN) { + conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", + "Output private key array length != 64"); + return; + } + + ED25519_keypair(reinterpret_cast(outPublic.get()), + reinterpret_cast(outPrivate.get())); + JNI_TRACE("ED25519_keypair(%p, %p) => success", outPublicArray, outPrivateArray); +} + static jlong NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE_MD("EVP_MD_CTX_create()"); @@ -2763,7 +2793,7 @@ static jlong evpDigestSignVerifyInit(JNIEnv* env, } JNI_TRACE("%s(%p, %p, %p) <- ptr", jniName, mdCtx, md, pkey); - if (md == nullptr) { + if (md == nullptr && (EVP_PKEY_id(pkey) != EVP_PKEY_ED25519)) { JNI_TRACE("ctx=%p %s => md == null", mdCtx, jniName); conscrypt::jniutil::throwNullPointerException(env, "md == null"); return 0; @@ -2921,14 +2951,14 @@ static void NativeCrypto_EVP_DigestSignUpdate(JNIEnv* env, jclass, jobject evpMd jint inLength) { CHECK_ERROR_QUEUE_ON_RETURN; evpUpdate(env, evpMdCtxRef, inJavaBytes, inOffset, inLength, "EVP_DigestSignUpdate", - EVP_DigestSignUpdate); + EVP_DigestSignUpdate); } static void NativeCrypto_EVP_DigestSignUpdateDirect(JNIEnv* env, jclass, jobject evpMdCtxRef, - jlong inPtr, jint inLength) { + jlong inPtr, jint inLength) { CHECK_ERROR_QUEUE_ON_RETURN; evpUpdate(env, evpMdCtxRef, inPtr, inLength, "EVP_DigestSignUpdateDirect", - EVP_DigestSignUpdate); + EVP_DigestSignUpdate); } static void NativeCrypto_EVP_DigestVerifyUpdate(JNIEnv* env, jclass, jobject evpMdCtxRef, @@ -3037,6 +3067,137 @@ static jboolean NativeCrypto_EVP_DigestVerifyFinal(JNIEnv* env, jclass, jobject return result; } +static jbyteArray NativeCrypto_EVP_DigestSign(JNIEnv* env, jclass, jobject evpMdCtxRef, + jbyteArray inJavaBytes, jint inOffset, + jint inLength) { + CHECK_ERROR_QUEUE_ON_RETURN; + + EVP_MD_CTX* mdCtx = fromContextObject(env, evpMdCtxRef); + JNI_TRACE_MD("%s(%p, %p, %d, %d)", "EVP_DigestSign", mdCtx, inJavaBytes, inOffset, inLength); + + if (mdCtx == nullptr) { + return nullptr; + } + + if (inJavaBytes == nullptr) { + conscrypt::jniutil::throwNullPointerException(env, "inBytes"); + return nullptr; + } + + size_t array_size = static_cast(env->GetArrayLength(inJavaBytes)); + if (ARRAY_CHUNK_INVALID(array_size, inOffset, inLength)) { + conscrypt::jniutil::throwException(env, "java/lang/ArrayIndexOutOfBoundsException", + "inBytes"); + return nullptr; + } + + jint in_offset = inOffset; + jint in_size = inLength; + + jbyte* array_elements = env->GetByteArrayElements(inJavaBytes, nullptr); + if (array_elements == nullptr) { + conscrypt::jniutil::throwOutOfMemory(env, "Unable to obtain elements of inBytes"); + return nullptr; + } + const unsigned char* buf = reinterpret_cast(array_elements); + const unsigned char* inStart = buf + in_offset; + size_t inLen = static_cast(in_size); + + size_t maxLen; + if (EVP_DigestSign(mdCtx, nullptr, &maxLen, inStart, inLen) != 1) { + JNI_TRACE("ctx=%p EVP_DigestSign => threw exception", mdCtx); + conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_DigestSign"); + return nullptr; + } + + std::unique_ptr buffer(new unsigned char[maxLen]); + if (buffer.get() == nullptr) { + conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate signature buffer"); + return nullptr; + } + size_t actualLen(maxLen); + if (EVP_DigestSign(mdCtx, buffer.get(), &actualLen, inStart, inLen) != 1) { + JNI_TRACE("ctx=%p EVP_DigestSign => threw exception", mdCtx); + conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_DigestSign"); + return nullptr; + } + if (actualLen > maxLen) { + JNI_TRACE("ctx=%p EVP_DigestSign => signature too long: %zd vs %zd", mdCtx, actualLen, + maxLen); + conscrypt::jniutil::throwRuntimeException(env, "EVP_DigestSign signature too long"); + return nullptr; + } + + ScopedLocalRef sigJavaBytes(env, env->NewByteArray(static_cast(actualLen))); + if (sigJavaBytes.get() == nullptr) { + conscrypt::jniutil::throwOutOfMemory(env, "Failed to allocate signature byte[]"); + return nullptr; + } + env->SetByteArrayRegion(sigJavaBytes.get(), 0, static_cast(actualLen), + reinterpret_cast(buffer.get())); + + JNI_TRACE("EVP_DigestSign(%p) => %p", mdCtx, sigJavaBytes.get()); + return sigJavaBytes.release(); +} + +static jboolean NativeCrypto_EVP_DigestVerify(JNIEnv* env, jclass, jobject evpMdCtxRef, + jbyteArray signature, jint sigOffset, jint sigLen, + jbyteArray data, jint dataOffset, jint dataLen) { + CHECK_ERROR_QUEUE_ON_RETURN; + EVP_MD_CTX* mdCtx = fromContextObject(env, evpMdCtxRef); + JNI_TRACE("EVP_DigestVerify(%p)", mdCtx); + + if (mdCtx == nullptr) { + return 0; + } + + ScopedByteArrayRO sigBytes(env, signature); + if (sigBytes.get() == nullptr) { + return 0; + } + + if (ARRAY_OFFSET_LENGTH_INVALID(sigBytes, sigOffset, sigLen)) { + conscrypt::jniutil::throwException(env, "java/lang/ArrayIndexOutOfBoundsException", + "signature"); + return 0; + } + + ScopedByteArrayRO dataBytes(env, data); + if (dataBytes.get() == nullptr) { + return 0; + } + + if (ARRAY_OFFSET_LENGTH_INVALID(dataBytes, dataOffset, dataLen)) { + conscrypt::jniutil::throwException(env, "java/lang/ArrayIndexOutOfBoundsException", "data"); + return 0; + } + + const unsigned char* sigBuf = reinterpret_cast(sigBytes.get()); + const unsigned char* dataBuf = reinterpret_cast(dataBytes.get()); + int err = EVP_DigestVerify(mdCtx, sigBuf + sigOffset, static_cast(sigLen), + dataBuf + dataOffset, static_cast(dataLen)); + jboolean result; + if (err == 1) { + // Signature verified + result = 1; + } else if (err == 0) { + // Signature did not verify + result = 0; + } else { + // Error while verifying signature + JNI_TRACE("ctx=%p EVP_DigestVerify => threw exception", mdCtx); + conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_DigestVerify"); + return 0; + } + + // If the signature did not verify, BoringSSL error queue contains an error (BAD_SIGNATURE). + // Clear the error queue to prevent its state from affecting future operations. + ERR_clear_error(); + + JNI_TRACE("EVP_DigestVerify(%p) => %d", mdCtx, result); + return result; +} + static jint evpPkeyEncryptDecrypt(JNIEnv* env, int (*encrypt_decrypt_func)(EVP_PKEY_CTX*, uint8_t*, size_t*, const uint8_t*, size_t), @@ -3446,8 +3607,8 @@ static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jobject ctxRef, int outl; if (!EVP_CipherFinal_ex(ctx, out + outOffset, &outl)) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_CipherFinal_ex", - conscrypt::jniutil::throwBadPaddingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "EVP_CipherFinal_ex", conscrypt::jniutil::throwBadPaddingException); JNI_TRACE("ctx=%p EVP_CipherFinal_ex => threw error", ctx); return 0; } @@ -3643,9 +3804,10 @@ typedef int (*evp_aead_ctx_op_func)(const EVP_AEAD_CTX* ctx, uint8_t* out, size_ size_t ad_len); static jint evp_aead_ctx_op_common(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArray, jint tagLen, - uint8_t* outBuf, jbyteArray nonceArray, - const uint8_t* inBuf, jbyteArray aadArray, - evp_aead_ctx_op_func realFunc, jobject inBuffer, jobject outBuffer, jint outRange, jint inRange) { + uint8_t* outBuf, jbyteArray nonceArray, const uint8_t* inBuf, + jbyteArray aadArray, evp_aead_ctx_op_func realFunc, + jobject inBuffer, jobject outBuffer, jint outRange, + jint inRange) { const EVP_AEAD* evpAead = reinterpret_cast(evpAeadRef); ScopedByteArrayRO keyBytes(env, keyArray); @@ -3676,26 +3838,22 @@ static jint evp_aead_ctx_op_common(JNIEnv* env, jlong evpAeadRef, jbyteArray key static_cast(tagLen), nullptr)) { conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "failure initializing AEAD context"); - JNI_TRACE( - "evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p) => fail EVP_AEAD_CTX_init", - evpAead, keyArray, tagLen, outBuffer, nonceArray, inBuffer, - aadArray); + JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p) => fail EVP_AEAD_CTX_init", evpAead, + keyArray, tagLen, outBuffer, nonceArray, inBuffer, aadArray); return 0; } const uint8_t* nonceTmp = reinterpret_cast(nonceBytes.get()); size_t actualOutLength; - if (!realFunc(aeadCtx.get(), outBuf, &actualOutLength, outRange, - nonceTmp, nonceBytes.size(), inBuf, static_cast(inRange), - aad_chars, aad_chars_size)) { + if (!realFunc(aeadCtx.get(), outBuf, &actualOutLength, outRange, nonceTmp, nonceBytes.size(), + inBuf, static_cast(inRange), aad_chars, aad_chars_size)) { conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "evp_aead_ctx_op"); return 0; } - JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p) => success outlength=%zd", - evpAead, keyArray, tagLen, outBuffer, nonceArray, inBuffer, - aadArray, actualOutLength); + JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p) => success outlength=%zd", evpAead, + keyArray, tagLen, outBuffer, nonceArray, inBuffer, aadArray, actualOutLength); return static_cast(actualOutLength); } @@ -3707,7 +3865,6 @@ static jint evp_aead_ctx_op(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArray, JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %d, %p, %p, %d, %d, %p)", evpAead, keyArray, tagLen, outArray, outOffset, nonceArray, inArray, inOffset, inLength, aadArray); - ScopedByteArrayRW outBytes(env, outArray); if (outBytes.get() == nullptr) { return 0; @@ -3739,18 +3896,17 @@ static jint evp_aead_ctx_op(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArray, uint8_t* outTmp = reinterpret_cast(outBytes.get()); const uint8_t* inTmp = reinterpret_cast(inBytes.get()); - return evp_aead_ctx_op_common(env, evpAeadRef, keyArray, tagLen, outTmp + outOffset, nonceArray, inTmp + inOffset, - aadArray, realFunc, inArray, outArray, outBytes.size() - outOffset, inLength); + return evp_aead_ctx_op_common(env, evpAeadRef, keyArray, tagLen, outTmp + outOffset, nonceArray, + inTmp + inOffset, aadArray, realFunc, inArray, outArray, + outBytes.size() - outOffset, inLength); } static jint evp_aead_ctx_op_buf(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArray, jint tagLen, - jobject outBuffer, jbyteArray nonceArray, - jobject inBuffer, jbyteArray aadArray, - evp_aead_ctx_op_func realFunc) { - + jobject outBuffer, jbyteArray nonceArray, jobject inBuffer, + jbyteArray aadArray, evp_aead_ctx_op_func realFunc) { const EVP_AEAD* evpAead = reinterpret_cast(evpAeadRef); - JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p)", evpAead, keyArray, tagLen, - outBuffer, nonceArray, inBuffer, aadArray); + JNI_TRACE("evp_aead_ctx_op(%p, %p, %d, %p, %p, %p, %p)", evpAead, keyArray, tagLen, outBuffer, + nonceArray, inBuffer, aadArray); if (!conscrypt::jniutil::isDirectByteBufferInstance(env, inBuffer)) { conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", @@ -3769,19 +3925,19 @@ static jint evp_aead_ctx_op_buf(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArr jint in_position; inBuf = (uint8_t*)(env->GetDirectBufferAddress(inBuffer)); - // limit is the index of the first element that should not be read or written - in_limit = env->CallIntMethod(inBuffer,conscrypt::jniutil::buffer_limitMethod); + // limit is the index of the first element that should not be read or written + in_limit = env->CallIntMethod(inBuffer, conscrypt::jniutil::buffer_limitMethod); // position is the index of the next element to be read or written - in_position = env->CallIntMethod(inBuffer,conscrypt::jniutil::buffer_positionMethod); + in_position = env->CallIntMethod(inBuffer, conscrypt::jniutil::buffer_positionMethod); uint8_t* outBuf; jint out_limit; jint out_position; outBuf = (uint8_t*)(env->GetDirectBufferAddress(outBuffer)); // limit is the index of the first element that should not be read or written - out_limit = env->CallIntMethod(outBuffer,conscrypt::jniutil::buffer_limitMethod); + out_limit = env->CallIntMethod(outBuffer, conscrypt::jniutil::buffer_limitMethod); // position is the index of the next element to be read or written - out_position = env->CallIntMethod(outBuffer,conscrypt::jniutil::buffer_positionMethod); + out_position = env->CallIntMethod(outBuffer, conscrypt::jniutil::buffer_positionMethod); // Shifting over of ByteBuffer address to start at true position inBuf += in_position; @@ -3791,9 +3947,9 @@ static jint evp_aead_ctx_op_buf(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArr uint8_t* outBufEnd = outBuf + out_limit - out_position; uint8_t* inBufEnd = inBuf + inSize; std::unique_ptr inCopy; - if (outBufEnd >= inBuf && inBufEnd >= outBuf) { // We have an overlap - inCopy.reset((new(std::nothrow) uint8_t[inSize])); - if (inCopy.get() == nullptr) { + if (outBufEnd >= inBuf && inBufEnd >= outBuf) { // We have an overlap + inCopy.reset((new (std::nothrow) uint8_t[inSize])); + if (inCopy.get() == nullptr) { conscrypt::jniutil::throwOutOfMemory(env, "Unable to allocate new buffer for overlap"); return 0; } @@ -3801,8 +3957,9 @@ static jint evp_aead_ctx_op_buf(JNIEnv* env, jlong evpAeadRef, jbyteArray keyArr inBuf = inCopy.get(); } - return evp_aead_ctx_op_common(env, evpAeadRef, keyArray, tagLen, outBuf, nonceArray, inBuf, aadArray, realFunc, - inBuffer, outBuffer, out_limit-out_position, in_limit-in_position); + return evp_aead_ctx_op_common(env, evpAeadRef, keyArray, tagLen, outBuf, nonceArray, inBuf, + aadArray, realFunc, inBuffer, outBuffer, out_limit - out_position, + in_limit - in_position); } static jint NativeCrypto_EVP_AEAD_CTX_seal(JNIEnv* env, jclass, jlong evpAeadRef, @@ -3826,19 +3983,21 @@ static jint NativeCrypto_EVP_AEAD_CTX_open(JNIEnv* env, jclass, jlong evpAeadRef } static jint NativeCrypto_EVP_AEAD_CTX_seal_buf(JNIEnv* env, jclass, jlong evpAeadRef, - jbyteArray keyArray, jint tagLen, jobject outBuffer, - jbyteArray nonceArray, jobject inBuffer, jbyteArray aadArray) { + jbyteArray keyArray, jint tagLen, jobject outBuffer, + jbyteArray nonceArray, jobject inBuffer, + jbyteArray aadArray) { CHECK_ERROR_QUEUE_ON_RETURN; - return evp_aead_ctx_op_buf(env, evpAeadRef, keyArray, tagLen, outBuffer, nonceArray, - inBuffer, aadArray, EVP_AEAD_CTX_seal); + return evp_aead_ctx_op_buf(env, evpAeadRef, keyArray, tagLen, outBuffer, nonceArray, inBuffer, + aadArray, EVP_AEAD_CTX_seal); } static jint NativeCrypto_EVP_AEAD_CTX_open_buf(JNIEnv* env, jclass, jlong evpAeadRef, - jbyteArray keyArray, jint tagLen, jobject outBuffer, - jbyteArray nonceArray, jobject inBuffer, jbyteArray aadArray) { + jbyteArray keyArray, jint tagLen, jobject outBuffer, + jbyteArray nonceArray, jobject inBuffer, + jbyteArray aadArray) { CHECK_ERROR_QUEUE_ON_RETURN; - return evp_aead_ctx_op_buf(env, evpAeadRef, keyArray, tagLen, outBuffer, nonceArray, - inBuffer, aadArray, EVP_AEAD_CTX_open); + return evp_aead_ctx_op_buf(env, evpAeadRef, keyArray, tagLen, outBuffer, nonceArray, inBuffer, + aadArray, EVP_AEAD_CTX_open); } static jbyteArray NativeCrypto_EVP_HPKE_CTX_export(JNIEnv* env, jclass, jobject hpkeCtxRef, @@ -3874,7 +4033,8 @@ static jbyteArray NativeCrypto_EVP_HPKE_CTX_export(JNIEnv* env, jclass, jobject return {}; } - ScopedLocalRef exportedArray(env, env->NewByteArray(static_cast(exportedLen))); + ScopedLocalRef exportedArray(env, + env->NewByteArray(static_cast(exportedLen))); if (exportedArray.get() == nullptr) { return {}; } @@ -3945,7 +4105,8 @@ static jbyteArray NativeCrypto_EVP_HPKE_CTX_open(JNIEnv* env, jclass, jobject re } plaintext.resize(plaintextLen); - ScopedLocalRef plaintextArray(env, env->NewByteArray(static_cast(plaintextLen))); + ScopedLocalRef plaintextArray(env, + env->NewByteArray(static_cast(plaintextLen))); if (plaintextArray.get() == nullptr) { return {}; } @@ -4001,7 +4162,8 @@ static jbyteArray NativeCrypto_EVP_HPKE_CTX_seal(JNIEnv* env, jclass, jobject se return {}; } - ScopedLocalRef ciphertextArray(env, env->NewByteArray(static_cast(encryptedLen))); + ScopedLocalRef ciphertextArray(env, + env->NewByteArray(static_cast(encryptedLen))); if (ciphertextArray.get() == nullptr) { return {}; } @@ -4048,12 +4210,9 @@ const EVP_HPKE_KEM* getHpkeKem(JNIEnv* env, jint kemValue) { } } -static jobject NativeCrypto_EVP_HPKE_CTX_setup_base_mode_recipient(JNIEnv* env, jclass, - jint kemValue,jint kdfValue, - jint aeadValue, - jbyteArray privateKeyArray, - jbyteArray encArray, - jbyteArray infoArray) { +static jobject NativeCrypto_EVP_HPKE_CTX_setup_base_mode_recipient( + JNIEnv* env, jclass, jint kemValue, jint kdfValue, jint aeadValue, + jbyteArray privateKeyArray, jbyteArray encArray, jbyteArray infoArray) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("EVP_HPKE_CTX_setup_recipient(%d, %d, %d, %p, %p, %p)", kemValue, kdfValue, aeadValue, privateKeyArray, encArray, infoArray); @@ -4118,14 +4277,14 @@ static jobject NativeCrypto_EVP_HPKE_CTX_setup_base_mode_recipient(JNIEnv* env, } ScopedLocalRef ctxObject( - env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, - conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, - reinterpret_cast(ctx.release()))); + env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, + conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, + reinterpret_cast(ctx.release()))); return ctxObject.release(); } static jobjectArray NativeCrypto_EVP_HPKE_CTX_setup_base_mode_sender(JNIEnv* env, jclass, - jint kemValue,jint kdfValue, + jint kemValue, jint kdfValue, jint aeadValue, jbyteArray publicKeyArray, jbyteArray infoArray) { @@ -4169,22 +4328,24 @@ static jobjectArray NativeCrypto_EVP_HPKE_CTX_setup_base_mode_sender(JNIEnv* env bssl::UniquePtr ctx(EVP_HPKE_CTX_new()); - if (!EVP_HPKE_CTX_setup_sender(/* ctx= */ ctx.get(), - /* out_enc= */ encapsulatedSharedSecret, - /* out_enc_len= */ &encapsulatedSharedSecretLen, - /* max_enc= */ EVP_HPKE_MAX_ENC_LENGTH, - /* kem= */ kem, - /* kdf= */ kdf, - /* aead= */ aead, - /* peer_public_key= */ reinterpret_cast(peer_public_key.get()), - /* peer_public_key_len= */ peer_public_key.size(), - /* info= */ info, - /* info_len= */ infoLen)) { + if (!EVP_HPKE_CTX_setup_sender( + /* ctx= */ ctx.get(), + /* out_enc= */ encapsulatedSharedSecret, + /* out_enc_len= */ &encapsulatedSharedSecretLen, + /* max_enc= */ EVP_HPKE_MAX_ENC_LENGTH, + /* kem= */ kem, + /* kdf= */ kdf, + /* aead= */ aead, + /* peer_public_key= */ reinterpret_cast(peer_public_key.get()), + /* peer_public_key_len= */ peer_public_key.size(), + /* info= */ info, + /* info_len= */ infoLen)) { conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "EVP_HPKE_CTX_setup_sender"); return {}; } - ScopedLocalRef encArray(env, env->NewByteArray(static_cast(encapsulatedSharedSecretLen))); + ScopedLocalRef encArray( + env, env->NewByteArray(static_cast(encapsulatedSharedSecretLen))); if (encArray.get() == nullptr) { return {}; } @@ -4192,15 +4353,16 @@ static jobjectArray NativeCrypto_EVP_HPKE_CTX_setup_base_mode_sender(JNIEnv* env if (encBytes.get() == nullptr) { return {}; } - memcpy(encBytes.get(), reinterpret_cast(encapsulatedSharedSecret), encapsulatedSharedSecretLen); + memcpy(encBytes.get(), reinterpret_cast(encapsulatedSharedSecret), + encapsulatedSharedSecretLen); ScopedLocalRef result( env, env->NewObjectArray(2, conscrypt::jniutil::objectClass, nullptr)); ScopedLocalRef ctxObject( - env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, - conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, - reinterpret_cast(ctx.release()))); + env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, + conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, + reinterpret_cast(ctx.release()))); env->SetObjectArrayElement(result.get(), 0, ctxObject.release()); env->SetObjectArrayElement(result.get(), 1, encArray.release()); @@ -4254,25 +4416,26 @@ static jobjectArray NativeCrypto_EVP_HPKE_CTX_setup_base_mode_sender_with_seed_f bssl::UniquePtr ctx(EVP_HPKE_CTX_new()); if (!EVP_HPKE_CTX_setup_sender_with_seed_for_testing( - /* ctx= */ ctx.get(), - /* out_enc= */ encapsulatedSharedSecret, - /* out_enc_len= */ &encapsulatedSharedSecretLen, - /* max_enc= */ EVP_HPKE_MAX_ENC_LENGTH, - /* kem= */ kem, - /* kdf= */ kdf, - /* aead= */ aead, - /* peer_public_key= */ reinterpret_cast(peer_public_key.get()), - /* peer_public_key_len= */ peer_public_key.size(), - /* info= */ info, - /* info_len= */ infoLen, - /* seed= */ reinterpret_cast(seed.get()), - /* seed_len= */ seed.size())) { + /* ctx= */ ctx.get(), + /* out_enc= */ encapsulatedSharedSecret, + /* out_enc_len= */ &encapsulatedSharedSecretLen, + /* max_enc= */ EVP_HPKE_MAX_ENC_LENGTH, + /* kem= */ kem, + /* kdf= */ kdf, + /* aead= */ aead, + /* peer_public_key= */ reinterpret_cast(peer_public_key.get()), + /* peer_public_key_len= */ peer_public_key.size(), + /* info= */ info, + /* info_len= */ infoLen, + /* seed= */ reinterpret_cast(seed.get()), + /* seed_len= */ seed.size())) { conscrypt::jniutil::throwExceptionFromBoringSSLError( env, "EVP_HPKE_CTX_setup_sender_with_seed_for_testing"); return {}; } - ScopedLocalRef encArray(env, env->NewByteArray(static_cast(encapsulatedSharedSecretLen))); + ScopedLocalRef encArray( + env, env->NewByteArray(static_cast(encapsulatedSharedSecretLen))); if (encArray.get() == nullptr) { return {}; } @@ -4280,15 +4443,16 @@ static jobjectArray NativeCrypto_EVP_HPKE_CTX_setup_base_mode_sender_with_seed_f if (encBytes.get() == nullptr) { return {}; } - memcpy(encBytes.get(), reinterpret_cast(encapsulatedSharedSecret), encapsulatedSharedSecretLen); + memcpy(encBytes.get(), reinterpret_cast(encapsulatedSharedSecret), + encapsulatedSharedSecretLen); ScopedLocalRef result( env, env->NewObjectArray(2, conscrypt::jniutil::objectClass, nullptr)); ScopedLocalRef ctxObject( - env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, - conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, - reinterpret_cast(ctx.release()))); + env, env->NewObject(conscrypt::jniutil::nativeRefHpkeCtxClass, + conscrypt::jniutil::nativeRefHpkeCtxClass_constructor, + reinterpret_cast(ctx.release()))); env->SetObjectArrayElement(result.get(), 0, ctxObject.release()); env->SetObjectArrayElement(result.get(), 1, encArray.release()); @@ -4333,21 +4497,21 @@ static void NativeCrypto_CMAC_Init(JNIEnv* env, jclass, jobject cmacCtxRef, jbyt const uint8_t* keyPtr = reinterpret_cast(keyBytes.get()); - const EVP_CIPHER *cipher; - switch(keyBytes.size()) { - case 16: - cipher = EVP_aes_128_cbc(); - break; - case 24: - cipher = EVP_aes_192_cbc(); - break; - case 32: - cipher = EVP_aes_256_cbc(); - break; - default: - conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", - "CMAC_Init: Unsupported key length"); - return; + const EVP_CIPHER* cipher; + switch (keyBytes.size()) { + case 16: + cipher = EVP_aes_128_cbc(); + break; + case 24: + cipher = EVP_aes_192_cbc(); + break; + case 32: + cipher = EVP_aes_256_cbc(); + break; + default: + conscrypt::jniutil::throwException(env, "java/lang/IllegalArgumentException", + "CMAC_Init: Unsupported key length"); + return; } if (!CMAC_Init(cmacCtx, keyPtr, keyBytes.size(), cipher, nullptr)) { @@ -4651,7 +4815,7 @@ static jlong NativeCrypto_create_BIO_InputStream(JNIEnv* env, jclass, jobject st return 0; } - const BIO_METHOD *method = stream_bio_method(); + const BIO_METHOD* method = stream_bio_method(); if (!method) { return 0; } @@ -4675,7 +4839,7 @@ static jlong NativeCrypto_create_BIO_OutputStream(JNIEnv* env, jclass, jobject s return 0; } - const BIO_METHOD *method = stream_bio_method(); + const BIO_METHOD* method = stream_bio_method(); if (!method) { return 0; } @@ -4752,7 +4916,7 @@ static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) { // Converting ASCII to UTF-16 is the identity function. jchars.push_back(data[i]); } - JNI_TRACE("GENERAL_NAME_to_jobject(%p)=> Email/DNS/URI \"%.*s\"", gen, (int) len, data); + JNI_TRACE("GENERAL_NAME_to_jobject(%p)=> Email/DNS/URI \"%.*s\"", gen, (int)len, data); return env->NewString(jchars.data(), jchars.size()); } case GEN_DIRNAME: @@ -4830,7 +4994,8 @@ static jobjectArray NativeCrypto_get_X509_GENERAL_NAME_stack(JNIEnv* env, jclass // TODO(https://github.com/google/conscrypt/issues/916): Handle errors, remove // |ERR_clear_error|, and throw CertificateParsingException. if (gn_stack == nullptr) { - JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => null (no extension or error)", x509, type); + JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => null (no extension or error)", x509, + type); ERR_clear_error(); return nullptr; } @@ -5749,12 +5914,9 @@ static void NativeCrypto_ASN1_TIME_to_Calendar(JNIEnv* env, jclass, jlong asn1Ti int year, mon, mday, hour, min, sec; const char* data = reinterpret_cast(ASN1_STRING_get0_data(gen.get())); - if (!decimal_to_integer(data, 4, &year) || - !decimal_to_integer(data + 4, 2, &mon) || - !decimal_to_integer(data + 6, 2, &mday) || - !decimal_to_integer(data + 8, 2, &hour) || - !decimal_to_integer(data + 10, 2, &min) || - !decimal_to_integer(data + 12, 2, &sec)) { + if (!decimal_to_integer(data, 4, &year) || !decimal_to_integer(data + 4, 2, &mon) || + !decimal_to_integer(data + 6, 2, &mday) || !decimal_to_integer(data + 8, 2, &hour) || + !decimal_to_integer(data + 10, 2, &min) || !decimal_to_integer(data + 12, 2, &sec)) { conscrypt::jniutil::throwParsingException(env, "Invalid date format"); return; } @@ -6342,8 +6504,8 @@ static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, uint8_t* data; size_t len; if (!BIO_read_asn1(bio, &data, &len, 256 * 1024 * 1024 /* max length, 256MB for sanity */)) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "Error reading PKCS#7 data", - conscrypt::jniutil::throwParsingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "Error reading PKCS#7 data", conscrypt::jniutil::throwParsingException); JNI_TRACE("d2i_PKCS7_bio(%p, %d) => error reading BIO", bio, which); return nullptr; } @@ -6355,8 +6517,8 @@ static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, if (which == PKCS7_CERTS) { bssl::UniquePtr outCerts(sk_X509_new_null()); if (!PKCS7_get_certificates(outCerts.get(), &cbs)) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, - "PKCS7_get_certificates", conscrypt::jniutil::throwParsingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "PKCS7_get_certificates", conscrypt::jniutil::throwParsingException); JNI_TRACE("d2i_PKCS7_bio(%p, %d) => error reading certs", bio, which); return nullptr; } @@ -6365,8 +6527,8 @@ static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, } else if (which == PKCS7_CRLS) { bssl::UniquePtr outCRLs(sk_X509_CRL_new_null()); if (!PKCS7_get_CRLs(outCRLs.get(), &cbs)) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "PKCS7_get_CRLs", - conscrypt::jniutil::throwParsingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "PKCS7_get_CRLs", conscrypt::jniutil::throwParsingException); JNI_TRACE("d2i_PKCS7_bio(%p, %d) => error reading CRLs", bio, which); return nullptr; } @@ -6391,8 +6553,8 @@ static jlongArray NativeCrypto_ASN1_seq_unpack_X509_bio(JNIEnv* env, jclass, jlo uint8_t* data; size_t len; if (!BIO_read_asn1(bio, &data, &len, 256 * 1024 * 1024 /* max length, 256MB for sanity */)) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "Error reading X.509 data", - conscrypt::jniutil::throwParsingException); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "Error reading X.509 data", conscrypt::jniutil::throwParsingException); JNI_TRACE("ASN1_seq_unpack_X509_bio(%p) => error reading BIO", bio); return nullptr; } @@ -7040,8 +7202,9 @@ static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, break; } - if (WSAEventSelect(fd.get(), events[1], (type == SSL_ERROR_WANT_READ ? FD_READ : FD_WRITE) | - FD_CLOSE) == SOCKET_ERROR) { + if (WSAEventSelect(fd.get(), events[1], + (type == SSL_ERROR_WANT_READ ? FD_READ : FD_WRITE) | FD_CLOSE) == + SOCKET_ERROR) { JNI_TRACE("sslSelect failure in WSAEventSelect: %d", WSAGetLastError()); break; } @@ -7266,7 +7429,7 @@ static void info_callback(const SSL* ssl, int type, int value) { JNI_TRACE("ssl=%p info_callback calling onSSLStateChange", ssl); env->CallVoidMethod(sslHandshakeCallbacks, - conscrypt::jniutil::sslHandshakeCallbacks_onSSLStateChange, type, value); + conscrypt::jniutil::sslHandshakeCallbacks_onSSLStateChange, type, value); if (env->ExceptionCheck()) { JNI_TRACE("ssl=%p info_callback exception", ssl); @@ -8278,8 +8441,8 @@ static jbyteArray NativeCrypto_SSL_export_keying_material(JNIEnv* env, jclass, j int ret; if (context == nullptr) { ret = SSL_export_keying_material(ssl, out.get(), num_bytes, - reinterpret_cast(labelBytes.get()), labelBytes.size(), - nullptr, 0, 0); + reinterpret_cast(labelBytes.get()), + labelBytes.size(), nullptr, 0, 0); } else { ScopedByteArrayRO contextBytes(env, context); if (contextBytes.get() == nullptr) { @@ -8293,8 +8456,8 @@ static jbyteArray NativeCrypto_SSL_export_keying_material(JNIEnv* env, jclass, j contextBytes.size(), 1); } if (!ret) { - conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "SSL_export_keying_material", - conscrypt::jniutil::throwSSLExceptionStr); + conscrypt::jniutil::throwExceptionFromBoringSSLError( + env, "SSL_export_keying_material", conscrypt::jniutil::throwSSLExceptionStr); JNI_TRACE("ssl=%p NativeCrypto_SSL_export_keying_material => exception", ssl); return nullptr; } @@ -8656,8 +8819,7 @@ static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_ad * which should take precedence. */ static int selectApplicationProtocol(SSL* ssl, unsigned char** out, unsigned char* outLength, - const unsigned char* primary, - const unsigned int primaryLength, + const unsigned char* primary, const unsigned int primaryLength, const unsigned char* secondary, const unsigned int secondaryLength) { JNI_TRACE("primary=%p, length=%d", primary, primaryLength); @@ -8683,9 +8845,8 @@ static int selectApplicationProtocol(SSL* ssl, unsigned char** out, unsigned cha * Calls out to an application-provided selector to choose the ALPN protocol. */ static int selectApplicationProtocol(SSL* ssl, JNIEnv* env, jobject sslHandshakeCallbacks, - unsigned char** out, - unsigned char* outLen, const unsigned char* in, - const unsigned int inLen) { + unsigned char** out, unsigned char* outLen, + const unsigned char* in, const unsigned int inLen) { // Copy the input array. ScopedLocalRef protocols(env, env->NewByteArray(static_cast(inLen))); if (protocols.get() == nullptr) { @@ -8745,10 +8906,10 @@ static int alpn_select_callback(SSL* ssl, const unsigned char** out, unsigned ch const_cast(out), outLen, in, inLen); } - return selectApplicationProtocol(ssl, const_cast(out), outLen, - reinterpret_cast(appData->applicationProtocolsData), - static_cast(appData->applicationProtocolsLength), - in, inLen); + return selectApplicationProtocol( + ssl, const_cast(out), outLen, + reinterpret_cast(appData->applicationProtocolsData), + static_cast(appData->applicationProtocolsLength), in, inLen); } static jbyteArray NativeCrypto_getApplicationProtocol(JNIEnv* env, jclass, jlong ssl_address, @@ -9183,7 +9344,9 @@ static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* b } // Everything else is basically an error. - default: { return THROW_SSLEXCEPTION; } + default: { + return THROW_SSLEXCEPTION; + } } } @@ -9460,7 +9623,9 @@ static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const } // Everything else is basically an error. - default: { return THROW_SSLEXCEPTION; } + default: { + return THROW_SSLEXCEPTION; + } } } JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count); @@ -10851,8 +11016,9 @@ static jboolean NativeCrypto_usesBoringSsl_FIPS_mode() { * Scrypt support */ -static jbyteArray NativeCrypto_Scrypt_generate_key(JNIEnv* env, jclass, jbyteArray password, jbyteArray salt, - jint n, jint r, jint p, jint key_len) { +static jbyteArray NativeCrypto_Scrypt_generate_key(JNIEnv* env, jclass, jbyteArray password, + jbyteArray salt, jint n, jint r, jint p, + jint key_len) { CHECK_ERROR_QUEUE_ON_RETURN; JNI_TRACE("Scrypt_generate_key(%p, %p, %d, %d, %d, %d)", password, salt, n, r, p, key_len); @@ -10879,10 +11045,10 @@ static jbyteArray NativeCrypto_Scrypt_generate_key(JNIEnv* env, jclass, jbyteArr ScopedByteArrayRO password_bytes(env, password); ScopedByteArrayRO salt_bytes(env, salt); - int result = EVP_PBE_scrypt(reinterpret_cast(password_bytes.get()), password_bytes.size(), - reinterpret_cast(salt_bytes.get()), salt_bytes.size(), - n, r, p, memory_limit, - reinterpret_cast(out_key.get()), key_len); + int result = EVP_PBE_scrypt( + reinterpret_cast(password_bytes.get()), password_bytes.size(), + reinterpret_cast(salt_bytes.get()), salt_bytes.size(), n, r, p, + memory_limit, reinterpret_cast(out_key.get()), key_len); if (result <= 0) { conscrypt::jniutil::throwExceptionFromBoringSSLError(env, "Scrypt_generate_key"); @@ -11035,8 +11201,7 @@ static jlong NativeCrypto_SSL_get1_session(JNIEnv* env, jclass, jlong ssl_addres // TESTING METHODS END #define CONSCRYPT_NATIVE_METHOD(functionName, signature) \ - { \ - /* NOLINTNEXTLINE */ \ + { /* NOLINTNEXTLINE */ \ (char*)#functionName, (char*)(signature), \ reinterpret_cast(NativeCrypto_##functionName) \ } @@ -11122,6 +11287,7 @@ static JNINativeMethod sNativeCryptoMethods[] = { CONSCRYPT_NATIVE_METHOD(ECDSA_verify, "([B[B" REF_EVP_PKEY ")I"), CONSCRYPT_NATIVE_METHOD(X25519, "([B[B[B)Z"), CONSCRYPT_NATIVE_METHOD(X25519_keypair, "([B[B)V"), + CONSCRYPT_NATIVE_METHOD(ED25519_keypair, "([B[B)V"), CONSCRYPT_NATIVE_METHOD(EVP_MD_CTX_create, "()J"), CONSCRYPT_NATIVE_METHOD(EVP_MD_CTX_cleanup, "(" REF_EVP_MD_CTX ")V"), CONSCRYPT_NATIVE_METHOD(EVP_MD_CTX_destroy, "(J)V"), @@ -11140,6 +11306,8 @@ static JNINativeMethod sNativeCryptoMethods[] = { CONSCRYPT_NATIVE_METHOD(EVP_DigestVerifyUpdate, "(" REF_EVP_MD_CTX "[BII)V"), CONSCRYPT_NATIVE_METHOD(EVP_DigestVerifyUpdateDirect, "(" REF_EVP_MD_CTX "JI)V"), CONSCRYPT_NATIVE_METHOD(EVP_DigestVerifyFinal, "(" REF_EVP_MD_CTX "[BII)Z"), + CONSCRYPT_NATIVE_METHOD(EVP_DigestSign, "(" REF_EVP_MD_CTX "[BII)[B"), + CONSCRYPT_NATIVE_METHOD(EVP_DigestVerify, "(" REF_EVP_MD_CTX "[BII[BII)Z"), CONSCRYPT_NATIVE_METHOD(EVP_PKEY_encrypt_init, "(" REF_EVP_PKEY ")J"), CONSCRYPT_NATIVE_METHOD(EVP_PKEY_encrypt, "(" REF_EVP_PKEY_CTX "[BI[BII)I"), CONSCRYPT_NATIVE_METHOD(EVP_PKEY_decrypt_init, "(" REF_EVP_PKEY ")J"), @@ -11179,8 +11347,10 @@ static JNINativeMethod sNativeCryptoMethods[] = { CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_free, "(J)V"), CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_open, "(" REF_EVP_HPKE_CTX "[B[B)[B"), CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_seal, "(" REF_EVP_HPKE_CTX "[B[B)[B"), - CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_setup_base_mode_recipient, "(III[B[B[B)Ljava/lang/Object;"), - CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_setup_base_mode_sender, "(III[B[B)[Ljava/lang/Object;"), + CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_setup_base_mode_recipient, + "(III[B[B[B)Ljava/lang/Object;"), + CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_setup_base_mode_sender, + "(III[B[B)[Ljava/lang/Object;"), CONSCRYPT_NATIVE_METHOD(EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing, "(III[B[B[B)[Ljava/lang/Object;"), CONSCRYPT_NATIVE_METHOD(HMAC_CTX_new, "()J"), diff --git a/common/src/main/java/org/conscrypt/NativeCrypto.java b/common/src/main/java/org/conscrypt/NativeCrypto.java index f33acbce4..e180fd0cf 100644 --- a/common/src/main/java/org/conscrypt/NativeCrypto.java +++ b/common/src/main/java/org/conscrypt/NativeCrypto.java @@ -16,6 +16,8 @@ package org.conscrypt; +import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; + import java.io.FileDescriptor; import java.io.IOException; import java.io.OutputStream; @@ -37,12 +39,12 @@ import java.util.HashSet; import java.util.List; import java.util.Set; + import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.ShortBufferException; import javax.net.ssl.SSLException; import javax.security.auth.x500.X500Principal; -import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; /** * Provides the Java side of our JNI glue for OpenSSL. @@ -51,7 +53,8 @@ * native pointer in the form of a long in addition to the long itself and don't use * the Java object in the native implementation. This is to prevent the Java object * from becoming eligible for GC while the native method is executing. See - * this + * this * for more details. */ @Internal @@ -208,10 +211,13 @@ static native int ECDH_compute_key(byte[] out, int outOffset, NativeRef.EVP_PKEY // --- Curve25519 -------------- - static native boolean X25519(byte[] out, byte[] privateKey, byte[] publicKey) throws InvalidKeyException; + static native boolean X25519(byte[] out, byte[] privateKey, byte[] publicKey) + throws InvalidKeyException; static native void X25519_keypair(byte[] outPublicKey, byte[] outPrivateKey); + static native void ED25519_keypair(byte[] outPublicKey, byte[] outPrivateKey); + // --- Message digest functions -------------- // These return const references @@ -264,6 +270,12 @@ static native void EVP_DigestVerifyUpdate( static native boolean EVP_DigestVerifyFinal(NativeRef.EVP_MD_CTX ctx, byte[] signature, int offset, int length) throws IndexOutOfBoundsException; + static native byte[] EVP_DigestSign( + NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset, int length); + + static native boolean EVP_DigestVerify(NativeRef.EVP_MD_CTX ctx, byte[] sigBuffer, + int sigOffset, int sigLen, byte[] dataBuffer, int dataOffset, int dataLen); + static native long EVP_PKEY_encrypt_init(NativeRef.EVP_PKEY pkey) throws InvalidKeyException; static native int EVP_PKEY_encrypt(NativeRef.EVP_PKEY_CTX ctx, byte[] out, int outOffset, @@ -343,16 +355,16 @@ static native int EVP_AEAD_CTX_seal(long evpAead, byte[] key, int tagLengthInByt int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad) throws ShortBufferException, BadPaddingException; - static native int EVP_AEAD_CTX_seal_buf(long evpAead, byte[] key, int tagLengthInBytes, ByteBuffer out, - byte[] nonce, ByteBuffer input, byte[] ad) + static native int EVP_AEAD_CTX_seal_buf(long evpAead, byte[] key, int tagLengthInBytes, + ByteBuffer out, byte[] nonce, ByteBuffer input, byte[] ad) throws ShortBufferException, BadPaddingException; static native int EVP_AEAD_CTX_open(long evpAead, byte[] key, int tagLengthInBytes, byte[] out, int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad) throws ShortBufferException, BadPaddingException; - static native int EVP_AEAD_CTX_open_buf(long evpAead, byte[] key, int tagLengthInBytes, ByteBuffer out, - byte[] nonce, ByteBuffer input, byte[] ad) + static native int EVP_AEAD_CTX_open_buf(long evpAead, byte[] key, int tagLengthInBytes, + ByteBuffer out, byte[] nonce, ByteBuffer input, byte[] ad) throws ShortBufferException, BadPaddingException; // --- CMAC functions ------------------------------------------------------ @@ -404,9 +416,8 @@ static native Object EVP_HPKE_CTX_setup_base_mode_recipient( static Object EVP_HPKE_CTX_setup_base_mode_recipient( HpkeSuite suite, byte[] privateKey, byte[] enc, byte[] info) { - return EVP_HPKE_CTX_setup_base_mode_recipient( - suite.getKem().getId(), suite.getKdf().getId(), suite.getAead().getId(), - privateKey, enc, info); + return EVP_HPKE_CTX_setup_base_mode_recipient(suite.getKem().getId(), + suite.getKdf().getId(), suite.getAead().getId(), privateKey, enc, info); } static native Object[] EVP_HPKE_CTX_setup_base_mode_sender( @@ -414,18 +425,16 @@ static native Object[] EVP_HPKE_CTX_setup_base_mode_sender( static Object[] EVP_HPKE_CTX_setup_base_mode_sender( HpkeSuite suite, byte[] publicKey, byte[] info) { - return EVP_HPKE_CTX_setup_base_mode_sender( - suite.getKem().getId(), suite.getKdf().getId(), suite.getAead().getId(), - publicKey, info); + return EVP_HPKE_CTX_setup_base_mode_sender(suite.getKem().getId(), suite.getKdf().getId(), + suite.getAead().getId(), publicKey, info); } static native Object[] EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing( int kem, int kdf, int aead, byte[] publicKey, byte[] info, byte[] seed); static Object[] EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing( HpkeSuite suite, byte[] publicKey, byte[] info, byte[] seed) { - return EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing( - suite.getKem().getId(), suite.getKdf().getId(), suite.getAead().getId(), - publicKey, info, seed); + return EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing(suite.getKem().getId(), + suite.getKdf().getId(), suite.getAead().getId(), publicKey, info, seed); } // --- RAND ---------------------------------------------------------------- @@ -490,9 +499,11 @@ private static int X509_NAME_hash(X500Principal principal, String algorithm) { static native void X509_free(long x509ctx, OpenSSLX509Certificate holder); - static native int X509_cmp(long x509ctx1, OpenSSLX509Certificate holder, long x509ctx2, OpenSSLX509Certificate holder2); + static native int X509_cmp(long x509ctx1, OpenSSLX509Certificate holder, long x509ctx2, + OpenSSLX509Certificate holder2); - static native void X509_print_ex(long bioCtx, long x509ctx, OpenSSLX509Certificate holder, long nmflag, long certflag); + static native void X509_print_ex( + long bioCtx, long x509ctx, OpenSSLX509Certificate holder, long nmflag, long certflag); static native byte[] X509_get_issuer_name(long x509ctx, OpenSSLX509Certificate holder); @@ -513,10 +524,11 @@ static native long X509_get_pubkey(long x509ctx, OpenSSLX509Certificate holder) static native byte[] X509_get_ext_oid(long x509ctx, OpenSSLX509Certificate holder, String oid); - static native String[] get_X509_ext_oids(long x509ctx, OpenSSLX509Certificate holder, int critical); + static native String[] get_X509_ext_oids( + long x509ctx, OpenSSLX509Certificate holder, int critical); - static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, OpenSSLX509Certificate holder, int type) - throws CertificateParsingException; + static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, + OpenSSLX509Certificate holder, int type) throws CertificateParsingException; static native boolean[] get_X509_ex_kusage(long x509ctx, OpenSSLX509Certificate holder); @@ -534,13 +546,13 @@ static native long X509_get_notAfter(long x509ctx, OpenSSLX509Certificate holder static native byte[] X509_get_serialNumber(long x509ctx, OpenSSLX509Certificate holder); - static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, NativeRef.EVP_PKEY pkeyCtx) - throws BadPaddingException, IllegalBlockSizeException; + static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, + NativeRef.EVP_PKEY pkeyCtx) throws BadPaddingException, IllegalBlockSizeException; static native byte[] get_X509_tbs_cert(long x509ctx, OpenSSLX509Certificate holder); - - static native byte[] get_X509_tbs_cert_without_ext(long x509ctx, OpenSSLX509Certificate holder, String oid); + static native byte[] get_X509_tbs_cert_without_ext( + long x509ctx, OpenSSLX509Certificate holder, String oid); static native byte[] get_X509_signature(long x509ctx, OpenSSLX509Certificate holder); @@ -548,7 +560,8 @@ static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, Nati // Used by Android platform TrustedCertificateStore. @SuppressWarnings("unused") - static native int X509_check_issued(long ctx, OpenSSLX509Certificate holder, long ctx2, OpenSSLX509Certificate holder2); + static native int X509_check_issued( + long ctx, OpenSSLX509Certificate holder, long ctx2, OpenSSLX509Certificate holder2); // --- PKCS7 --------------------------------------------------------------- @@ -586,15 +599,18 @@ static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, Nati static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx, OpenSSLX509CRL holder); /** Returns X509_REVOKED reference that is not duplicated! */ - static native long X509_CRL_get0_by_cert(long x509CrlCtx, OpenSSLX509CRL holder, long x509Ctx, OpenSSLX509Certificate holder2); + static native long X509_CRL_get0_by_cert( + long x509CrlCtx, OpenSSLX509CRL holder, long x509Ctx, OpenSSLX509Certificate holder2); /** Returns X509_REVOKED reference that is not duplicated! */ - static native long X509_CRL_get0_by_serial(long x509CrlCtx, OpenSSLX509CRL holder, byte[] serial); + static native long X509_CRL_get0_by_serial( + long x509CrlCtx, OpenSSLX509CRL holder, byte[] serial); /** Returns an array of X509_REVOKED that are owned by the caller. */ static native long[] X509_CRL_get_REVOKED(long x509CrlCtx, OpenSSLX509CRL holder); - static native String[] get_X509_CRL_ext_oids(long x509Crlctx, OpenSSLX509CRL holder, int critical); + static native String[] get_X509_CRL_ext_oids( + long x509Crlctx, OpenSSLX509CRL holder, int critical); static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, OpenSSLX509CRL holder, String oid); @@ -605,8 +621,9 @@ static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder, Nati static native byte[] get_X509_CRL_signature(long x509ctx, OpenSSLX509CRL holder); static native void X509_CRL_verify(long x509CrlCtx, OpenSSLX509CRL holder, - NativeRef.EVP_PKEY pkeyCtx) throws BadPaddingException, SignatureException, - NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException; + NativeRef.EVP_PKEY pkeyCtx) throws BadPaddingException, SignatureException, + NoSuchAlgorithmException, InvalidKeyException, + IllegalBlockSizeException; static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx, OpenSSLX509CRL holder); @@ -641,7 +658,8 @@ static native long X509_CRL_get_nextUpdate(long x509CrlCtx, OpenSSLX509CRL holde // --- ASN1_TIME ----------------------------------------------------------- - static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal) throws ParsingException; + static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal) + throws ParsingException; // --- ASN1 Encoding ------------------------------------------------------- @@ -810,8 +828,8 @@ static native long X509_CRL_get_nextUpdate(long x509CrlCtx, OpenSSLX509CRL holde // OpenSSL-style names. private static final Set SUPPORTED_LEGACY_CIPHER_SUITES_SET = new HashSet(); - static final Set SUPPORTED_TLS_1_3_CIPHER_SUITES_SET = new HashSet( - Arrays.asList(SUPPORTED_TLS_1_3_CIPHER_SUITES)); + static final Set SUPPORTED_TLS_1_3_CIPHER_SUITES_SET = + new HashSet(Arrays.asList(SUPPORTED_TLS_1_3_CIPHER_SUITES)); /** * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation @@ -962,22 +980,27 @@ static String cipherSuiteFromJava(String javaCipherSuite) { }; static String[] getSupportedCipherSuites() { - return SSLUtils.concat(SUPPORTED_TLS_1_3_CIPHER_SUITES, SUPPORTED_TLS_1_2_CIPHER_SUITES.clone()); + return SSLUtils.concat( + SUPPORTED_TLS_1_3_CIPHER_SUITES, SUPPORTED_TLS_1_2_CIPHER_SUITES.clone()); } static native void SSL_CTX_free(long ssl_ctx, AbstractSessionContext holder); - static native void SSL_CTX_set_session_id_context(long ssl_ctx, AbstractSessionContext holder, byte[] sid_ctx); + static native void SSL_CTX_set_session_id_context( + long ssl_ctx, AbstractSessionContext holder, byte[] sid_ctx); - static native long SSL_CTX_set_timeout(long ssl_ctx, AbstractSessionContext holder, long seconds); + static native long SSL_CTX_set_timeout( + long ssl_ctx, AbstractSessionContext holder, long seconds); static native long SSL_new(long ssl_ctx, AbstractSessionContext holder) throws SSLException; - static native void SSL_enable_tls_channel_id(long ssl, NativeSsl ssl_holder) throws SSLException; + static native void SSL_enable_tls_channel_id(long ssl, NativeSsl ssl_holder) + throws SSLException; static native byte[] SSL_get_tls_channel_id(long ssl, NativeSsl ssl_holder) throws SSLException; - static native void SSL_set1_tls_channel_id(long ssl, NativeSsl ssl_holder, NativeRef.EVP_PKEY pkey); + static native void SSL_set1_tls_channel_id( + long ssl, NativeSsl ssl_holder, NativeRef.EVP_PKEY pkey); /** * Sets the local certificates and private key. @@ -987,11 +1010,11 @@ static String[] getSupportedCipherSuites() { * @param pkey a reference to the private key. * @throws SSLException if a problem occurs setting the cert/key. */ - static native void setLocalCertsAndPrivateKey(long ssl, NativeSsl ssl_holder, byte[][] encodedCertificates, - NativeRef.EVP_PKEY pkey) throws SSLException; + static native void setLocalCertsAndPrivateKey(long ssl, NativeSsl ssl_holder, + byte[][] encodedCertificates, NativeRef.EVP_PKEY pkey) throws SSLException; - static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[][] asn1DerEncodedX500Principals) - throws SSLException; + static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, + byte[][] asn1DerEncodedX500Principals) throws SSLException; static native long SSL_set_mode(long ssl, NativeSsl ssl_holder, long mode); @@ -999,13 +1022,15 @@ static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[] static native long SSL_clear_options(long ssl, NativeSsl ssl_holder, long options); - static native int SSL_set_protocol_versions(long ssl, NativeSsl ssl_holder, int min_version, int max_version); + static native int SSL_set_protocol_versions( + long ssl, NativeSsl ssl_holder, int min_version, int max_version); static native void SSL_enable_signed_cert_timestamps(long ssl, NativeSsl ssl_holder); static native byte[] SSL_get_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder); - static native void SSL_set_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder, byte[] list); + static native void SSL_set_signed_cert_timestamp_list( + long ssl, NativeSsl ssl_holder, byte[] list); static native void SSL_enable_ocsp_stapling(long ssl, NativeSsl ssl_holder); @@ -1015,47 +1040,51 @@ static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder, byte[] static native byte[] SSL_get_tls_unique(long ssl, NativeSsl ssl_holder); - static native byte[] SSL_export_keying_material(long ssl, NativeSsl ssl_holder, byte[] label, byte[] context, int num_bytes) throws SSLException; + static native byte[] SSL_export_keying_material(long ssl, NativeSsl ssl_holder, byte[] label, + byte[] context, int num_bytes) throws SSLException; - static native void SSL_use_psk_identity_hint(long ssl, NativeSsl ssl_holder, String identityHint) throws SSLException; + static native void SSL_use_psk_identity_hint( + long ssl, NativeSsl ssl_holder, String identityHint) throws SSLException; - static native void set_SSL_psk_client_callback_enabled(long ssl, NativeSsl ssl_holder, boolean enabled); + static native void set_SSL_psk_client_callback_enabled( + long ssl, NativeSsl ssl_holder, boolean enabled); - static native void set_SSL_psk_server_callback_enabled(long ssl, NativeSsl ssl_holder, boolean enabled); + static native void set_SSL_psk_server_callback_enabled( + long ssl, NativeSsl ssl_holder, boolean enabled); public static void setTlsV1DeprecationStatus(boolean deprecated, boolean supported) { if (deprecated) { TLSV12_PROTOCOLS = new String[] { - SUPPORTED_PROTOCOL_TLSV1_2, + SUPPORTED_PROTOCOL_TLSV1_2, }; TLSV13_PROTOCOLS = new String[] { - SUPPORTED_PROTOCOL_TLSV1_2, - SUPPORTED_PROTOCOL_TLSV1_3, + SUPPORTED_PROTOCOL_TLSV1_2, + SUPPORTED_PROTOCOL_TLSV1_3, }; } else { TLSV12_PROTOCOLS = new String[] { - DEPRECATED_PROTOCOL_TLSV1, - DEPRECATED_PROTOCOL_TLSV1_1, - SUPPORTED_PROTOCOL_TLSV1_2, + DEPRECATED_PROTOCOL_TLSV1, + DEPRECATED_PROTOCOL_TLSV1_1, + SUPPORTED_PROTOCOL_TLSV1_2, }; TLSV13_PROTOCOLS = new String[] { - DEPRECATED_PROTOCOL_TLSV1, - DEPRECATED_PROTOCOL_TLSV1_1, - SUPPORTED_PROTOCOL_TLSV1_2, - SUPPORTED_PROTOCOL_TLSV1_3, + DEPRECATED_PROTOCOL_TLSV1, + DEPRECATED_PROTOCOL_TLSV1_1, + SUPPORTED_PROTOCOL_TLSV1_2, + SUPPORTED_PROTOCOL_TLSV1_3, }; } if (supported) { SUPPORTED_PROTOCOLS = new String[] { - DEPRECATED_PROTOCOL_TLSV1, - DEPRECATED_PROTOCOL_TLSV1_1, - SUPPORTED_PROTOCOL_TLSV1_2, - SUPPORTED_PROTOCOL_TLSV1_3, + DEPRECATED_PROTOCOL_TLSV1, + DEPRECATED_PROTOCOL_TLSV1_1, + SUPPORTED_PROTOCOL_TLSV1_2, + SUPPORTED_PROTOCOL_TLSV1_3, }; } else { SUPPORTED_PROTOCOLS = new String[] { - SUPPORTED_PROTOCOL_TLSV1_2, - SUPPORTED_PROTOCOL_TLSV1_3, + SUPPORTED_PROTOCOL_TLSV1_2, + SUPPORTED_PROTOCOL_TLSV1_3, }; } } @@ -1127,7 +1156,7 @@ static void setEnabledProtocols(long ssl, NativeSsl ssl_holder, String[] protoco checkEnabledProtocols(protocols); Range range = getProtocolRange(protocols); SSL_set_protocol_versions( - ssl, ssl_holder, getProtocolConstant(range.min), getProtocolConstant(range.max)); + ssl, ssl_holder, getProtocolConstant(range.min), getProtocolConstant(range.max)); } private static int getProtocolConstant(String protocol) { @@ -1168,8 +1197,8 @@ static String[] checkEnabledProtocols(String[] protocols) { */ static native long[] SSL_get_ciphers(long ssl, NativeSsl ssl_holder); - static void setEnabledCipherSuites(long ssl, NativeSsl ssl_holder, String[] cipherSuites, - String[] protocols) { + static void setEnabledCipherSuites( + long ssl, NativeSsl ssl_holder, String[] cipherSuites, String[] protocols) { checkEnabledCipherSuites(cipherSuites); String maxProtocol = getProtocolRange(protocols).max; List opensslSuites = new ArrayList(); @@ -1183,13 +1212,14 @@ static void setEnabledCipherSuites(long ssl, NativeSsl ssl_holder, String[] ciph // for more discussion. if (cipherSuite.equals(TLS_FALLBACK_SCSV) && (maxProtocol.equals(DEPRECATED_PROTOCOL_TLSV1) - || maxProtocol.equals(DEPRECATED_PROTOCOL_TLSV1_1))) { + || maxProtocol.equals(DEPRECATED_PROTOCOL_TLSV1_1))) { SSL_set_mode(ssl, ssl_holder, NativeConstants.SSL_MODE_SEND_FALLBACK_SCSV); continue; } opensslSuites.add(cipherSuiteFromJava(cipherSuite)); } - SSL_set_cipher_lists(ssl, ssl_holder, opensslSuites.toArray(new String[opensslSuites.size()])); + SSL_set_cipher_lists( + ssl, ssl_holder, opensslSuites.toArray(new String[opensslSuites.size()])); } static String[] checkEnabledCipherSuites(String[] cipherSuites) { @@ -1235,14 +1265,15 @@ static native void SSL_set_session_creation_enabled( static native boolean SSL_session_reused(long ssl, NativeSsl ssl_holder); - static native void SSL_accept_renegotiations(long ssl, NativeSsl ssl_holder) throws SSLException; + static native void SSL_accept_renegotiations(long ssl, NativeSsl ssl_holder) + throws SSLException; static native void SSL_set_tlsext_host_name(long ssl, NativeSsl ssl_holder, String hostname) throws SSLException; static native String SSL_get_servername(long ssl, NativeSsl ssl_holder); - static native void SSL_do_handshake( - long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc, int timeoutMillis) + static native void SSL_do_handshake(long ssl, NativeSsl ssl_holder, FileDescriptor fd, + SSLHandshakeCallbacks shc, int timeoutMillis) throws SSLException, SocketTimeoutException, CertificateException; public static native String SSL_get_current_cipher(long ssl, NativeSsl ssl_holder); @@ -1258,8 +1289,9 @@ static native void SSL_do_handshake( * Reads with the native SSL_read function from the encrypted data stream * @return -1 if error or the end of the stream is reached. */ - static native int SSL_read(long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc, - byte[] b, int off, int len, int readTimeoutMillis) throws IOException; + static native int SSL_read(long ssl, NativeSsl ssl_holder, FileDescriptor fd, + SSLHandshakeCallbacks shc, byte[] b, int off, int len, int readTimeoutMillis) + throws IOException; /** * Writes with the native SSL_write function to the encrypted data stream. @@ -1269,8 +1301,8 @@ static native void SSL_write(long ssl, NativeSsl ssl_holder, FileDescriptor fd, throws IOException; static native void SSL_interrupt(long ssl, NativeSsl ssl_holder); - static native void SSL_shutdown( - long ssl, NativeSsl ssl_holder, FileDescriptor fd, SSLHandshakeCallbacks shc) throws IOException; + static native void SSL_shutdown(long ssl, NativeSsl ssl_holder, FileDescriptor fd, + SSLHandshakeCallbacks shc) throws IOException; static native int SSL_get_shutdown(long ssl, NativeSsl ssl_holder); @@ -1334,8 +1366,9 @@ void verifyCertificateChain(byte[][] certificateChain, String authMethod) * convertible to strings with #keyType * @param asn1DerEncodedX500Principals CAs known to the server */ - @SuppressWarnings("unused") void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs, - byte[][] asn1DerEncodedX500Principals) + @SuppressWarnings("unused") + void clientCertificateRequested( + byte[] keyTypes, int[] signatureAlgs, byte[][] asn1DerEncodedX500Principals) throws CertificateEncodingException, SSLException; /** @@ -1415,8 +1448,9 @@ void verifyCertificateChain(byte[][] certificateChain, String authMethod) static native String[] get_cipher_names(String selection); - public static native byte[] get_ocsp_single_extension( - byte[] ocspResponse, String oid, long x509Ref, OpenSSLX509Certificate holder, long issuerX509Ref, OpenSSLX509Certificate holder2); + public static native byte[] get_ocsp_single_extension(byte[] ocspResponse, String oid, + long x509Ref, OpenSSLX509Certificate holder, long issuerX509Ref, + OpenSSLX509Certificate holder2); /** * Returns the starting address of the memory region referenced by the provided direct @@ -1455,8 +1489,8 @@ static native void setApplicationProtocols( * correct protocol during a handshake. Calling this method overrides * {@link #setApplicationProtocols(long, NativeSsl, boolean, byte[])}. */ - static native void setHasApplicationProtocolSelector(long ssl, NativeSsl ssl_holder, boolean hasSelector) - throws IOException; + static native void setHasApplicationProtocolSelector( + long ssl, NativeSsl ssl_holder, boolean hasSelector) throws IOException; /** * Returns the selected ALPN protocol. If the server did not select a @@ -1474,8 +1508,8 @@ static native void setHasApplicationProtocolSelector(long ssl, NativeSsl ssl_hol * SSL_ERROR_NONE}, {@code SSL_ERROR_WANT_READ}, or {@code SSL_ERROR_WANT_WRITE}. * @throws IOException when the error code is anything except those returned by this method. */ - static native int ENGINE_SSL_do_handshake(long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc) - throws IOException; + static native int ENGINE_SSL_do_handshake( + long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc) throws IOException; /** * Variant of the {@link #SSL_read} for a direct {@link java.nio.ByteBuffer} used by {@link @@ -1491,45 +1525,46 @@ static native int ENGINE_SSL_do_handshake(long ssl, NativeSsl ssl_holder, SSLHan * Only occurs during handshake processing. * @throws SSLException if any other error occurs. */ - static native int ENGINE_SSL_read_direct(long ssl, NativeSsl ssl_holder, long address, int length, - SSLHandshakeCallbacks shc) throws IOException, CertificateException; + static native int ENGINE_SSL_read_direct(long ssl, NativeSsl ssl_holder, long address, + int length, SSLHandshakeCallbacks shc) throws IOException, CertificateException; /** * Variant of the {@link #SSL_write} for a direct {@link java.nio.ByteBuffer} used by {@link * ConscryptEngine}. This version does not lock or and does no error pre-processing. */ - static native int ENGINE_SSL_write_direct(long ssl, NativeSsl ssl_holder, long address, int length, - SSLHandshakeCallbacks shc) throws IOException; + static native int ENGINE_SSL_write_direct(long ssl, NativeSsl ssl_holder, long address, + int length, SSLHandshakeCallbacks shc) throws IOException; /** * Writes data from the given direct {@link java.nio.ByteBuffer} to the BIO. */ - static native int ENGINE_SSL_write_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, long pos, int length, - SSLHandshakeCallbacks shc) throws IOException; + static native int ENGINE_SSL_write_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, + long pos, int length, SSLHandshakeCallbacks shc) throws IOException; /** * Reads data from the given BIO into a direct {@link java.nio.ByteBuffer}. */ - static native int ENGINE_SSL_read_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, long address, int len, - SSLHandshakeCallbacks shc) throws IOException; + static native int ENGINE_SSL_read_BIO_direct(long ssl, NativeSsl ssl_holder, long bioRef, + long address, int len, SSLHandshakeCallbacks shc) throws IOException; /** * Forces the SSL object to process any data pending in the BIO. */ - static native void ENGINE_SSL_force_read(long ssl, NativeSsl ssl_holder, - SSLHandshakeCallbacks shc) throws IOException; + static native void ENGINE_SSL_force_read( + long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc) throws IOException; /** * Variant of the {@link #SSL_shutdown} used by {@link ConscryptEngine}. This version does not * lock. */ - static native void ENGINE_SSL_shutdown(long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc) - throws IOException; + static native void ENGINE_SSL_shutdown( + long ssl, NativeSsl ssl_holder, SSLHandshakeCallbacks shc) throws IOException; /** * Generates a key from a password and salt using Scrypt. */ - static native byte[] Scrypt_generate_key(byte[] password, byte[] salt, int n, int r, int p, int key_len); + static native byte[] Scrypt_generate_key( + byte[] password, byte[] salt, int n, int r, int p, int key_len); /** * Return {@code true} if BoringSSL has been built in FIPS mode. diff --git a/constants/src/gen/cpp/generate_constants.cc b/constants/src/gen/cpp/generate_constants.cc index 60fe93d8b..8624e37f5 100644 --- a/constants/src/gen/cpp/generate_constants.cc +++ b/constants/src/gen/cpp/generate_constants.cc @@ -55,6 +55,7 @@ int main(int /* argc */, char ** /* argv */) { CONST(EVP_PKEY_RSA); CONST(EVP_PKEY_EC); + CONST(EVP_PKEY_ED25519); CONST(RSA_PKCS1_PADDING); CONST(RSA_NO_PADDING); diff --git a/openjdk/src/test/java/org/conscrypt/NativeCryptoTest.java b/openjdk/src/test/java/org/conscrypt/NativeCryptoTest.java index af2e9ca70..eb910edbc 100644 --- a/openjdk/src/test/java/org/conscrypt/NativeCryptoTest.java +++ b/openjdk/src/test/java/org/conscrypt/NativeCryptoTest.java @@ -26,20 +26,35 @@ import static org.conscrypt.NativeConstants.TLS1_1_VERSION; import static org.conscrypt.NativeConstants.TLS1_2_VERSION; import static org.conscrypt.NativeConstants.TLS1_VERSION; +import static org.conscrypt.TestUtils.decodeHex; import static org.conscrypt.TestUtils.isWindows; import static org.conscrypt.TestUtils.openTestFile; import static org.conscrypt.TestUtils.readTestFile; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.when; +import org.conscrypt.NativeCrypto.SSLHandshakeCallbacks; +import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; +import org.conscrypt.io.IoUtils; +import org.conscrypt.java.security.StandardNames; +import org.conscrypt.java.security.TestKeyStore; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; @@ -74,22 +89,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; + import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLProtocolException; import javax.security.auth.x500.X500Principal; -import org.conscrypt.NativeCrypto.SSLHandshakeCallbacks; -import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException; -import org.conscrypt.io.IoUtils; -import org.conscrypt.java.security.StandardNames; -import org.conscrypt.java.security.TestKeyStore; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.ArgumentMatchers; -import org.mockito.Mockito; @RunWith(JUnit4.class) public class NativeCryptoTest { @@ -125,15 +130,19 @@ public static void initStatics() throws Exception { m_Platform_getFileDescriptor.setAccessible(true); } - PrivateKeyEntry serverPrivateKeyEntry = TestKeyStore.getServer().getPrivateKey("RSA", "RSA"); + PrivateKeyEntry serverPrivateKeyEntry = + TestKeyStore.getServer().getPrivateKey("RSA", "RSA"); SERVER_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(serverPrivateKeyEntry.getPrivateKey()); - SERVER_CERTIFICATES_HOLDER = encodeCertificateList(serverPrivateKeyEntry.getCertificateChain()); + SERVER_CERTIFICATES_HOLDER = + encodeCertificateList(serverPrivateKeyEntry.getCertificateChain()); SERVER_CERTIFICATE_REFS = getCertificateReferences(SERVER_CERTIFICATES_HOLDER); ENCODED_SERVER_CERTIFICATES = getEncodedCertificates(SERVER_CERTIFICATES_HOLDER); - PrivateKeyEntry clientPrivateKeyEntry = TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA"); + PrivateKeyEntry clientPrivateKeyEntry = + TestKeyStore.getClientCertificate().getPrivateKey("RSA", "RSA"); CLIENT_PRIVATE_KEY = OpenSSLKey.fromPrivateKey(clientPrivateKeyEntry.getPrivateKey()); - CLIENT_CERTIFICATES_HOLDER = encodeCertificateList(clientPrivateKeyEntry.getCertificateChain()); + CLIENT_CERTIFICATES_HOLDER = + encodeCertificateList(clientPrivateKeyEntry.getCertificateChain()); CLIENT_CERTIFICATE_REFS = getCertificateReferences(CLIENT_CERTIFICATES_HOLDER); ENCODED_CLIENT_CERTIFICATES = getEncodedCertificates(CLIENT_CERTIFICATES_HOLDER); @@ -141,20 +150,22 @@ public static void initStatics() throws Exception { String caCertAlias = ks.aliases().nextElement(); X509Certificate certificate = (X509Certificate) ks.getCertificate(caCertAlias); X500Principal principal = certificate.getIssuerX500Principal(); - CA_PRINCIPALS = new byte[][] { principal.getEncoded() }; + CA_PRINCIPALS = new byte[][] {principal.getEncoded()}; // NIST P-256 aka SECG secp256r1 aka X9.62 prime256v1 OpenSSLECGroupContext openSslSpec = OpenSSLECGroupContext.getCurveByName("prime256v1"); BigInteger s = new BigInteger( "229cdbbf489aea584828a261a23f9ff8b0f66f7ccac98bf2096ab3aee41497c5", 16); - CHANNEL_ID_PRIVATE_KEY = new OpenSSLECPrivateKey(new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())) - .getOpenSSLKey(); + CHANNEL_ID_PRIVATE_KEY = + new OpenSSLECPrivateKey(new ECPrivateKeySpec(s, openSslSpec.getECParameterSpec())) + .getOpenSSLKey(); // Channel ID is the concatenation of the X and Y coordinates of the public key. CHANNEL_ID = new BigInteger( "702b07871fd7955c320b26f15e244e47eed60272124c92b9ebecf0b42f90069b" + "ab53592ebfeb4f167dbf3ce61513afb0e354c479b1c1b69874fa471293494f77", - 16).toByteArray(); + 16) + .toByteArray(); // RSA keys are slow to generate, so prefer to reuse the key when possible. TEST_RSA_KEY = generateRsaKey(); @@ -350,7 +361,8 @@ public void setLocalCertsAndPrivateKey_withNullCertificatesShouldThrow() throws long c = NativeCrypto.SSL_CTX_new(); long s = NativeCrypto.SSL_new(c, null); try { - NativeCrypto.setLocalCertsAndPrivateKey(s, null, null, SERVER_PRIVATE_KEY.getNativeRef()); + NativeCrypto.setLocalCertsAndPrivateKey( + s, null, null, SERVER_PRIVATE_KEY.getNativeRef()); } finally { NativeCrypto.SSL_free(s, null); NativeCrypto.SSL_CTX_free(c, null); @@ -508,10 +520,16 @@ public void SSL_set_protocol_versions_withNullShouldThrow() throws Exception { public void SSL_set_protocol_versions() throws Exception { long c = NativeCrypto.SSL_CTX_new(); long s = NativeCrypto.SSL_new(c, null); - assertEquals(1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_VERSION, TLS1_1_VERSION)); - assertEquals(1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_2_VERSION, TLS1_2_VERSION)); - assertEquals(0, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_2_VERSION + 413, TLS1_1_VERSION)); - assertEquals(0, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_1_VERSION, TLS1_2_VERSION + 413)); + assertEquals( + 1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_VERSION, TLS1_1_VERSION)); + assertEquals( + 1, NativeCrypto.SSL_set_protocol_versions(s, null, TLS1_2_VERSION, TLS1_2_VERSION)); + assertEquals(0, + NativeCrypto.SSL_set_protocol_versions( + s, null, TLS1_2_VERSION + 413, TLS1_1_VERSION)); + assertEquals(0, + NativeCrypto.SSL_set_protocol_versions( + s, null, TLS1_1_VERSION, TLS1_2_VERSION + 413)); NativeCrypto.SSL_free(s, null); NativeCrypto.SSL_CTX_free(c, null); } @@ -685,7 +703,8 @@ static class TestSSLHandshakeCallbacks implements SSLHandshakeCallbacks { private final Hooks hooks; private final ApplicationProtocolSelectorAdapter alpnSelector; - TestSSLHandshakeCallbacks(Socket socket, long sslNativePointer, Hooks hooks, ApplicationProtocolSelectorAdapter alpnSelector) { + TestSSLHandshakeCallbacks(Socket socket, long sslNativePointer, Hooks hooks, + ApplicationProtocolSelectorAdapter alpnSelector) { this.socket = socket; this.sslNativePointer = sslNativePointer; this.hooks = hooks; @@ -763,8 +782,8 @@ public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] ke if (DEBUG) { System.out.println("ssl=0x" + Long.toString(sslNativePointer, 16) + " clientPSKKeyRequested" - + " identityHint=" + identityHint + " identity capacity=" + identity.length - + " key capacity=" + key.length); + + " identityHint=" + identityHint + " identity capacity=" + + identity.length + " key capacity=" + key.length); } clientPSKKeyRequestedInvoked = true; clientPSKKeyRequestedIdentityHint = identityHint; @@ -894,7 +913,8 @@ public ServerHooks() { public long beforeHandshake(long c) throws SSLException { long s = super.beforeHandshake(c); if (privateKey != null && certificates != null) { - NativeCrypto.setLocalCertsAndPrivateKey(s, null, certificates, privateKey.getNativeRef()); + NativeCrypto.setLocalCertsAndPrivateKey( + s, null, certificates, privateKey.getNativeRef()); } if (channelIdEnabled) { NativeCrypto.SSL_enable_tls_channel_id(s, null); @@ -953,8 +973,7 @@ public TestSSLHandshakeCallbacks call() throws Exception { return new TestSSLHandshakeCallbacks(socket, 0, null, null); } FileDescriptor fd = - (FileDescriptor) m_Platform_getFileDescriptor.invoke( - null, socket); + (FileDescriptor) m_Platform_getFileDescriptor.invoke(null, socket); long c = hooks.getContext(); long s = hooks.beforeHandshake(c); TestSSLHandshakeCallbacks callback = @@ -974,7 +993,8 @@ public TestSSLHandshakeCallbacks call() throws Exception { NativeCrypto.SSL_set_accept_state(s, null); } if (alpnProtocols != null) { - NativeCrypto.setApplicationProtocols(s, null, client, alpnProtocols); + NativeCrypto.setApplicationProtocols( + s, null, client, alpnProtocols); } if (!client && alpnSelector != null) { NativeCrypto.setHasApplicationProtocolSelector(s, null, true); @@ -982,8 +1002,7 @@ public TestSSLHandshakeCallbacks call() throws Exception { NativeCrypto.SSL_do_handshake(s, null, fd, callback, timeout); session = NativeCrypto.SSL_get1_session(s, null); if (DEBUG) { - System.out.println("ssl=0x" + Long.toString(s, 16) - + " handshake" + System.out.println("ssl=0x" + Long.toString(s, 16) + " handshake" + " session=0x" + Long.toString(session, 16)); } } finally { @@ -1040,8 +1059,7 @@ public void test_SSL_do_handshake_normal() throws Exception { TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback.authMethod); assertFalse(serverCallback.verifyCertificateChainCalled); assertFalse(clientCallback.clientCertificateRequestedCalled); @@ -1079,8 +1097,7 @@ public void configureCallbacks(TestSSLHandshakeCallbacks callbacks) { TestSSLHandshakeCallbacks clientCallback1 = client1.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback1 = server1.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback1.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback1.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback1.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback1.authMethod); assertFalse(serverCallback1.verifyCertificateChainCalled); assertFalse(clientCallback1.clientCertificateRequestedCalled); @@ -1121,8 +1138,7 @@ public long beforeHandshake(long c) throws SSLException { TestSSLHandshakeCallbacks clientCallback2 = client2.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback2 = server2.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback2.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback2.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback2.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback2.authMethod); assertFalse(serverCallback2.verifyCertificateChainCalled); assertFalse(clientCallback2.clientCertificateRequestedCalled); @@ -1171,12 +1187,10 @@ public long beforeHandshake(long c) throws SSLException { TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback.authMethod); assertTrue(serverCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - CLIENT_CERTIFICATE_REFS, serverCallback.certificateChainRefs); + assertEqualCertificateChains(CLIENT_CERTIFICATE_REFS, serverCallback.certificateChainRefs); assertEquals("ECDHE_RSA", serverCallback.authMethod); assertTrue(clientCallback.clientCertificateRequestedCalled); @@ -1291,8 +1305,7 @@ public void test_SSL_do_handshake_with_channel_id_normal() throws Exception { TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback.authMethod); assertFalse(serverCallback.verifyCertificateChainCalled); assertFalse(clientCallback.clientCertificateRequestedCalled); @@ -1328,8 +1341,7 @@ public void test_SSL_do_handshake_with_channel_id_not_supported_by_server() thro TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback.authMethod); assertFalse(serverCallback.verifyCertificateChainCalled); assertFalse(clientCallback.clientCertificateRequestedCalled); @@ -1365,8 +1377,7 @@ public void test_SSL_do_handshake_with_channel_id_not_enabled_by_client() throws TestSSLHandshakeCallbacks clientCallback = client.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); TestSSLHandshakeCallbacks serverCallback = server.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); assertTrue(clientCallback.verifyCertificateChainCalled); - assertEqualCertificateChains( - SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); + assertEqualCertificateChains(SERVER_CERTIFICATE_REFS, clientCallback.certificateChainRefs); assertEquals("ECDHE_RSA", clientCallback.authMethod); assertFalse(serverCallback.verifyCertificateChainCalled); assertFalse(clientCallback.clientCertificateRequestedCalled); @@ -1608,7 +1619,8 @@ public long beforeHandshake(long c) throws SSLException { @Override public void afterHandshake(long session, long ssl, long context, Socket socket, FileDescriptor fd, SSLHandshakeCallbacks callback) throws Exception { - assertEqualByteArrays(OCSP_TEST_DATA, NativeCrypto.SSL_get_ocsp_response(ssl, null)); + assertEqualByteArrays( + OCSP_TEST_DATA, NativeCrypto.SSL_get_ocsp_response(ssl, null)); super.afterHandshake(session, ssl, context, socket, fd, callback); } }; @@ -1738,8 +1750,7 @@ public void afterHandshake(long session, long s, long c, Socket sock, clientSession[0] = session; } }; - Hooks sHooks = new ServerHooks( - SERVER_PRIVATE_KEY, ENCODED_SERVER_CERTIFICATES) { + Hooks sHooks = new ServerHooks(SERVER_PRIVATE_KEY, ENCODED_SERVER_CERTIFICATES) { @Override public long getContext() { return serverContext; @@ -1778,8 +1789,7 @@ public void afterHandshake(long session, long s, long c, Socket sock, super.afterHandshake(NULL, s, NULL, sock, fd, callback); } }; - Hooks sHooks = new ServerHooks( - SERVER_PRIVATE_KEY, ENCODED_SERVER_CERTIFICATES) { + Hooks sHooks = new ServerHooks(SERVER_PRIVATE_KEY, ENCODED_SERVER_CERTIFICATES) { @Override public long getContext() { return serverContext; @@ -2050,7 +2060,8 @@ public void afterHandshake(long session, long ssl, long c, Socket sock, ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class); SSLEngine engine = Mockito.mock(SSLEngine.class); - ApplicationProtocolSelectorAdapter adapter = new ApplicationProtocolSelectorAdapter(engine, selector); + ApplicationProtocolSelectorAdapter adapter = + new ApplicationProtocolSelectorAdapter(engine, selector); when(selector.selectApplicationProtocol(same(engine), ArgumentMatchers.anyList())) .thenReturn("spdy/2"); @@ -2089,7 +2100,8 @@ public void afterHandshake(long session, long ssl, long c, Socket sock, ApplicationProtocolSelector selector = Mockito.mock(ApplicationProtocolSelector.class); SSLEngine engine = Mockito.mock(SSLEngine.class); - ApplicationProtocolSelectorAdapter adapter = new ApplicationProtocolSelectorAdapter(engine, selector); + ApplicationProtocolSelectorAdapter adapter = + new ApplicationProtocolSelectorAdapter(engine, selector); when(selector.selectApplicationProtocol(same(engine), ArgumentMatchers.anyList())) .thenReturn("h2"); @@ -2379,7 +2391,8 @@ public void run() { } } }.start(); - assertEquals(-1, NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 0)); + assertEquals( + -1, NativeCrypto.SSL_read(s, null, fd, callback, new byte[1], 0, 1, 0)); super.afterHandshake(session, s, c, sock, fd, callback); } }; @@ -2716,6 +2729,79 @@ public void test_EVP_DigestSignInit() throws Exception { } } + @Test + public void test_ED25519_keypair_works() throws Exception { + byte[] publicKeyBytes = new byte[32]; + byte[] privateKeyBytes = new byte[64]; + NativeCrypto.ED25519_keypair(publicKeyBytes, privateKeyBytes); + + byte[] publicKeyBytes2 = new byte[32]; + byte[] privateKeyBytes2 = new byte[64]; + NativeCrypto.ED25519_keypair(publicKeyBytes2, privateKeyBytes2); + + // keys must be random + assertNotEquals(publicKeyBytes, publicKeyBytes2); + assertNotEquals(privateKeyBytes, privateKeyBytes2); + } + + @Test + public void test_ED25519_keypair_32BytePrivateKey_throws() throws Exception { + byte[] publicKeyBytes = new byte[32]; + byte[] privateKeyBytes = new byte[32]; + assertThrows(IllegalArgumentException.class, + () -> NativeCrypto.ED25519_keypair(publicKeyBytes, privateKeyBytes)); + } + + @Test + public void test_EVP_DigestSign_Ed25519_works() throws Exception { + // Test vectors from https://datatracker.ietf.org/doc/html/rfc8032#section-7 + // PKCS#8 encoding for Ed25519 is defined in https://datatracker.ietf.org/doc/html/rfc8410 + byte[] pkcs8EncodedPrivateKey = decodeHex( + // PKCS#8 header + "302e020100300506032b657004220420" + // raw private key + + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"); + byte[] data = decodeHex(""); + byte[] expectedSig = + decodeHex("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + + NativeRef.EVP_PKEY privateKey = + new NativeRef.EVP_PKEY(NativeCrypto.EVP_parse_private_key(pkcs8EncodedPrivateKey)); + + NativeRef.EVP_MD_CTX ctx = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create()); + + NativeCrypto.EVP_DigestSignInit(ctx, 0, privateKey); + byte[] sig = NativeCrypto.EVP_DigestSign(ctx, data, 0, data.length); + + assertArrayEquals(expectedSig, sig); + } + + @Test + public void test_EVP_DigestVerify_Ed25519_works() throws Exception { + // Test vectors from https://datatracker.ietf.org/doc/html/rfc8032#section-7 + // X.509 encoding for Ed25519 is defined in https://datatracker.ietf.org/doc/html/rfc8410 + byte[] x509EncodedPublicKey = decodeHex( + // X.509 header + "302a300506032b6570032100" + // raw public key + + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"); + byte[] data = decodeHex(""); + byte[] sig = decodeHex("e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"); + + NativeRef.EVP_MD_CTX ctx = new NativeRef.EVP_MD_CTX(NativeCrypto.EVP_MD_CTX_create()); + + NativeRef.EVP_PKEY publicKey = + new NativeRef.EVP_PKEY(NativeCrypto.EVP_parse_public_key(x509EncodedPublicKey)); + + NativeCrypto.EVP_DigestVerifyInit(ctx, 0, publicKey); + boolean result = + NativeCrypto.EVP_DigestVerify(ctx, sig, 0, sig.length, data, 0, data.length); + + assertTrue(result); + } + @Test(expected = NullPointerException.class) public void get_RSA_private_params_NullArgument() throws Exception { NativeCrypto.get_RSA_private_params(null); @@ -2776,9 +2862,22 @@ public void test_RSA_public_decrypt_NullArgumentFailure() throws Exception { * openssl rand -hex 16 */ private static final byte[] AES_128_KEY = new byte[] { - (byte) 0x3d, (byte) 0x4f, (byte) 0x89, (byte) 0x70, (byte) 0xb1, (byte) 0xf2, - (byte) 0x75, (byte) 0x37, (byte) 0xf4, (byte) 0x0a, (byte) 0x39, (byte) 0x29, - (byte) 0x8a, (byte) 0x41, (byte) 0x55, (byte) 0x5f, + (byte) 0x3d, + (byte) 0x4f, + (byte) 0x89, + (byte) 0x70, + (byte) 0xb1, + (byte) 0xf2, + (byte) 0x75, + (byte) 0x37, + (byte) 0xf4, + (byte) 0x0a, + (byte) 0x39, + (byte) 0x29, + (byte) 0x8a, + (byte) 0x41, + (byte) 0x55, + (byte) 0x5f, }; @Test @@ -2994,8 +3093,8 @@ public void test_get_ocsp_single_extension() throws Exception { OpenSSLX509Certificate issuer = OpenSSLX509Certificate.fromX509PemInputStream(openTestFile("ca-cert.pem")); - byte[] extension = NativeCrypto.get_ocsp_single_extension( - ocspResponse, OCSP_SCT_LIST_OID, certificate.getContext(), certificate, issuer.getContext(), issuer); + byte[] extension = NativeCrypto.get_ocsp_single_extension(ocspResponse, OCSP_SCT_LIST_OID, + certificate.getContext(), certificate, issuer.getContext(), issuer); assertEqualByteArrays(expected, extension); }