Skip to content

Commit

Permalink
Merge pull request #564 from pshipton/0.32ossl3
Browse files Browse the repository at this point in the history
(0.32) Add openssl version 3+ support for Linux platforms
  • Loading branch information
keithc-ca authored Apr 21, 2022
2 parents 167bb92 + 66014df commit 56132a5
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2018, 2019 All Rights Reserved
* (c) Copyright IBM Corp. 2018, 2022 All Rights Reserved
* ===========================================================================
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -34,16 +34,26 @@

public class NativeCrypto {

//ossl_ver:
// -1 : library load failed
// 0 : openssl 1.0.x
// 1 : openssl 1.1.x or newer
private static final boolean loaded = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () -> {
Boolean isLoaded = Boolean.FALSE;

boolean traceEnabled = Boolean.getBoolean("jdk.nativeCryptoTrace");
try {
System.loadLibrary("jncrypto"); // check for native library
// load OpenSSL crypto library dynamically.
if (loadCrypto() == 0) {
int ossl_ver = loadCrypto(traceEnabled);
if (ossl_ver != -1) {
isLoaded = Boolean.TRUE;
}
} catch (UnsatisfiedLinkError usle) {
if (traceEnabled) {
System.err.println("UnsatisfiedLinkError: Failure attempting to load jncrypto JNI library");
}
// Return that isLoaded is false (default set above)
}

Expand All @@ -70,7 +80,7 @@ public static NativeCrypto getNativeCrypto() {
}

/* Native digest interfaces */
static final native int loadCrypto();
private static final native int loadCrypto(boolean traceEnabled);

public final native long DigestCreateContext(long nativeBuffer,
int algoIndex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2018, 2021 All Rights Reserved
* (c) Copyright IBM Corp. 2018, 2022 All Rights Reserved
* ===========================================================================
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -38,6 +38,9 @@

#define OPENSSL_VERSION_1_0 "OpenSSL 1.0."
#define OPENSSL_VERSION_1_1 "OpenSSL 1.1."
/* Per new OpenSSL naming convention starting from OpenSSL 3, all major versions are ABI and API compatible. */
#define OPENSSL_VERSION_3_X "OpenSSL 3."

/* needed for OpenSSL 1.0.2 Thread handling routines */
# define CRYPTO_LOCK 1

Expand Down Expand Up @@ -188,10 +191,11 @@ static void *crypto_library = NULL;
/*
* Class: jdk_crypto_jniprovider_NativeCrypto
* Method: loadCrypto
* Signature: ()I
* Signature: (Z)I
*/
JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
(JNIEnv *env, jclass thisObj){
(JNIEnv *env, jclass thisObj, jboolean traceEnabled)
{

typedef const char* OSSL_version_t(int);

Expand All @@ -201,41 +205,42 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
int ossl_ver;

/* Load OpenSSL Crypto library */
crypto_library = load_crypto_library();
crypto_library = load_crypto_library(traceEnabled);
if (NULL == crypto_library) {
#if 0
fprintf(stderr, " :FAILED TO LOAD OPENSSL CRYPTO LIBRARY\n");
fflush(stderr);
#endif /* 0 */
if (traceEnabled) {
fprintf(stderr, " :FAILED TO LOAD OPENSSL CRYPTO LIBRARY\n");
fflush(stderr);
}
return -1;
}

/* Different symbols are used by OpenSSL with 1.0 and 1.1.
* The symbol 'OpenSSL_version' is used by OpenSSL 1.1 where as
/*
* Different symbols are used by OpenSSL with 1.0 and 1.1 and later.
* The symbol 'OpenSSL_version' is used by OpenSSL 1.1 and later where as
* the symbol "SSLeay_version" is used by OpenSSL 1.0.
* Currently only openssl 1.0.x and 1.1.x are supported.
* Currently only openssl 1.0.x, 1.1.x and 3.x.x are supported.
*/
OSSL_version = (OSSL_version_t*)find_crypto_symbol(crypto_library, "OpenSSL_version");

if (NULL == OSSL_version) {
OSSL_version = (OSSL_version_t*)find_crypto_symbol(crypto_library, "SSLeay_version");

if (NULL == OSSL_version) {
#if 0
fprintf(stderr, "Only openssl 1.0.x and 1.1.x are supported\n");
fflush(stderr);
#endif /* 0 */
if (traceEnabled) {
fprintf(stderr, "Only OpenSSL 1.0.x, 1.1.x and 3.x are supported\n");
fflush(stderr);
}
unload_crypto_library(crypto_library);
crypto_library = NULL;
return -1;
} else {
openssl_version = (*OSSL_version)(0); /* get OPENSSL_VERSION */
/* Ensure the OpenSSL version is "OpenSSL 1.0.x" */
if (0 != strncmp(openssl_version, OPENSSL_VERSION_1_0, strlen(OPENSSL_VERSION_1_0))) {
#if 0
fprintf(stderr, "Incompatable OpenSSL version: %s\n", openssl_version);
fflush(stderr);
#endif /* 0 */
if (traceEnabled) {
fprintf(stderr, "Incompatable OpenSSL version: %s\n", openssl_version);
fflush(stderr);
}
unload_crypto_library(crypto_library);
crypto_library = NULL;
return -1;
Expand All @@ -244,19 +249,26 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
}
} else {
openssl_version = (*OSSL_version)(0); /* get OPENSSL_VERSION */
/* Ensure the OpenSSL version is "OpenSSL 1.1.x". */
if (0 != strncmp(openssl_version,OPENSSL_VERSION_1_1, strlen(OPENSSL_VERSION_1_1))) {
#if 0
fprintf(stderr, "Incompatable OpenSSL version: %s\n", openssl_version);
fflush(stderr);
#endif /* 0 */
/* Ensure the OpenSSL version is "OpenSSL 1.1.x" or "OpenSSL 3.x.x". */
if ((0 != strncmp(openssl_version, OPENSSL_VERSION_1_1, strlen(OPENSSL_VERSION_1_1)))
&& (0 != strncmp(openssl_version, OPENSSL_VERSION_3_X, strlen(OPENSSL_VERSION_3_X)))
) {
if (traceEnabled) {
fprintf(stderr, "Incompatable OpenSSL version: %s\n", openssl_version);
fflush(stderr);
}
unload_crypto_library(crypto_library);
crypto_library = NULL;
return -1;
}
ossl_ver = 1;
}

if (traceEnabled) {
fprintf(stderr, "Supported OpenSSL version: %s\n", openssl_version);
fflush(stderr);
}

/* Load the function symbols for OpenSSL errors. */
OSSL_error_string_n = (OSSL_error_string_n_t*)find_crypto_symbol(crypto_library, "ERR_error_string_n");
OSSL_error_string = (OSSL_error_string_t*)find_crypto_symbol(crypto_library, "ERR_error_string");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2019, 2019 All Rights Reserved
* (c) Copyright IBM Corp. 2019, 2022 All Rights Reserved
* ===========================================================================
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,7 +25,9 @@
#ifndef NATIVECRYPTO_MD_H
#define NATIVECRYPTO_MD_H

void * load_crypto_library();
#include <jni.h>

void * load_crypto_library(jboolean traceEnabled);
void unload_crypto_library(void *handle);
void * find_crypto_symbol(void *handle, const char *symname);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2019, 2019 All Rights Reserved
* (c) Copyright IBM Corp. 2019, 2022 All Rights Reserved
* ===========================================================================
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -29,13 +29,18 @@
#include <dlfcn.h>
#include "NativeCrypto_md.h"

#if defined(__linux__)
#include <link.h>
#endif /* defined(__linux__) */

/* Load the crypto library (return NULL on error) */
void * load_crypto_library() {
void * load_crypto_library(jboolean traceEnabled)
{
void * result = NULL;
int flags = RTLD_NOW;
size_t i = 0;

// Library names for OpenSSL 1.1.1, 1.1.0, 1.0.2 and symbolic links
// Library names for OpenSSL 3.x, 1.1.1, 1.1.0, 1.0.2 and symbolic links
static const char * const libNames[] = {
#if defined(_AIX)
"libcrypto.a(libcrypto64.so.1.1)",
Expand All @@ -47,6 +52,7 @@ void * load_crypto_library() {
"libcrypto.1.0.0.dylib",
"libcrypto.dylib"
#else
"libcrypto.so.3", // 3.x library name
"libcrypto.so.1.1",
"libcrypto.so.1.0.0",
"libcrypto.so.10",
Expand All @@ -67,6 +73,15 @@ void * load_crypto_library() {
result = dlopen (libName, flags);
}

#if defined(__linux__)
if (traceEnabled && (NULL != result)) {
struct link_map *map = NULL;
dlinfo(result, RTLD_DI_LINKMAP, &map);
fprintf(stderr, "Attempt to load OpenSSL %s\n", map->l_name);
fflush(stderr);
}
#endif /* defined(__linux__) */

return result;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* ===========================================================================
* (c) Copyright IBM Corp. 2019, 2019 All Rights Reserved
* (c) Copyright IBM Corp. 2019, 2022 All Rights Reserved
* ===========================================================================
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -37,7 +37,7 @@ static jboolean GetApplicationHome(char *buf, jint bufsize);
static int JLI_Snprintf(char* buffer, size_t size, const char* format, ...);

/* Load the crypto library (return NULL on error) */
void * load_crypto_library() {
void * load_crypto_library(jboolean traceEnabled) {
void * result = NULL;
const char *libname;
const char *oldname = "libeay32.dll";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
* questions.
*/

/*
* ===========================================================================
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
* ===========================================================================
*/

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
Expand All @@ -36,7 +42,15 @@
*/
public class GCMParameterSpecTest {

private static final int[] IV_LENGTHS = { 96, 8, 1024 };
/*
* OpenSSL3 only supports IV lengths up to 16 bytes.
* When the IV length is set to be larger than 16 bytes, an error is thrown.
* According to the OpenSSL docs([1]), in OpenSSL1.1.1 and older, there is
* no error thrown but unpredictable behavior will happen for large IV sizes.
*
* [1] https://www.openssl.org/docs/man1.1.1/man3/EVP_CIPHER_CTX_block_size.html
*/
private static final int[] IV_LENGTHS = { 96, 8 };
private static final int[] KEY_LENGTHS = { 128, 192, 256 };
private static final int[] DATA_LENGTHS = { 0, 128, 1024 };
private static final int[] AAD_LENGTHS = { 0, 128, 1024 };
Expand Down

0 comments on commit 56132a5

Please sign in to comment.