Skip to content

Commit 2fa3123

Browse files
authored
Merge pull request #183 from WilburZjh/ExpandOpenSSLVersionGranularity
Expand OpenSSL Version granularity
2 parents ed76bf1 + edbc986 commit 2fa3123

File tree

3 files changed

+70
-34
lines changed

3 files changed

+70
-34
lines changed

closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ public class NativeCrypto {
4848
public static final int SHA5_384 = 3;
4949
public static final int SHA5_512 = 4;
5050

51+
public static final long OPENSSL_VERSION_1_0_0 = 0x1_00_00_000L;
52+
public static final long OPENSSL_VERSION_1_1_0 = 0x1_01_00_000L;
53+
public static final long OPENSSL_VERSION_3_0_0 = 0x3_00_00_000L;
54+
5155
private static final Cleaner ECKeyCleaner = CleanerFactory.cleaner();
5256

5357
private static final boolean useNativeCrypto = Boolean.parseBoolean(
@@ -60,14 +64,13 @@ private static final class InstanceHolder {
6064
private static final NativeCrypto instance = new NativeCrypto();
6165
}
6266

63-
//ossl_vers:
67+
//ossl_vers will be either:
6468
// -1 : library load failed
65-
// 0 : openssl 1.0.x
66-
// 1 : openssl 1.1.x or newer
67-
private final int ossl_ver;
69+
// or one of the OPENSSL_VERSION_x_x_x constants
70+
private final long ossl_ver;
6871

69-
private static int loadCryptoLibraries() {
70-
int osslVersion;
72+
private static long loadCryptoLibraries() {
73+
long osslVersion;
7174

7275
try {
7376
// load jncrypto JNI library
@@ -91,7 +94,7 @@ private static int loadCryptoLibraries() {
9194

9295
@SuppressWarnings("removal")
9396
private NativeCrypto() {
94-
ossl_ver = AccessController.doPrivileged((PrivilegedAction<Integer>) () -> loadCryptoLibraries()).intValue();
97+
ossl_ver = AccessController.doPrivileged((PrivilegedAction<Long>) () -> loadCryptoLibraries()).longValue();
9598
}
9699

97100
/**
@@ -112,7 +115,7 @@ public static final boolean isAllowedAndLoaded() {
112115
*
113116
* @return the OpenSSL library version if it is available
114117
*/
115-
public static final int getVersionIfAvailable() {
118+
public static final long getVersionIfAvailable() {
116119
/*[IF CRIU_SUPPORT]*/
117120
if (InternalCRIUSupport.isCheckpointAllowed()) {
118121
return -1;
@@ -185,7 +188,8 @@ public void run() {
185188
}
186189

187190
/* Native digest interfaces */
188-
private static final native int loadCrypto(boolean traceEnabled);
191+
192+
private static final native long loadCrypto(boolean trace);
189193

190194
public final native long DigestCreateContext(long nativeBuffer,
191195
int algoIndex);

closed/src/java.base/share/native/libjncrypto/NativeCrypto.c

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* ===========================================================================
3-
* (c) Copyright IBM Corp. 2018, 2022 All Rights Reserved
3+
* (c) Copyright IBM Corp. 2018, 2023 All Rights Reserved
44
* ===========================================================================
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
2929
#include <openssl/ecdh.h>
3030
#include <openssl/pkcs12.h>
3131

32+
#include <ctype.h>
3233
#include <jni.h>
3334
#include <stdio.h>
3435
#include <stdint.h>
@@ -38,10 +39,15 @@
3839
#include "jdk_crypto_jniprovider_NativeCrypto.h"
3940
#include "NativeCrypto_md.h"
4041

41-
#define OPENSSL_VERSION_1_0 "OpenSSL 1.0."
42-
#define OPENSSL_VERSION_1_1 "OpenSSL 1.1."
42+
#define OPENSSL_VERSION_CODE(major, minor, fix, patch) \
43+
((((jlong)(major)) << 28) | ((minor) << 20) | ((fix) << 12) | (patch))
44+
45+
#define OPENSSL_VERSION_1_0_0 OPENSSL_VERSION_CODE(1, 0, 0, 0)
46+
#define OPENSSL_VERSION_1_1_0 OPENSSL_VERSION_CODE(1, 1, 0, 0)
47+
#define OPENSSL_VERSION_2_0_0 OPENSSL_VERSION_CODE(2, 0, 0, 0)
4348
/* Per new OpenSSL naming convention starting from OpenSSL 3, all major versions are ABI and API compatible. */
44-
#define OPENSSL_VERSION_3_X "OpenSSL 3."
49+
#define OPENSSL_VERSION_3_0_0 OPENSSL_VERSION_CODE(3, 0, 0, 0)
50+
#define OPENSSL_VERSION_4_0_0 OPENSSL_VERSION_CODE(4, 0, 0, 0)
4551

4652
/* needed for OpenSSL 1.0.2 Thread handling routines */
4753
#define CRYPTO_LOCK 1
@@ -261,13 +267,39 @@ static void printErrors(void)
261267
fflush(stderr);
262268
}
263269

270+
/*
271+
* We use a 8 digit map (ABBCCDDD) to represent the version of openssl.
272+
* A is the major version,
273+
* BB is the minor version,
274+
* CC is the fix,
275+
* DDD is the patch that could be present in any version.
276+
* For example, if an openssl version is in this scheme 1.2.3.d
277+
* where major is 1, minor is 2, fix is 3 and patch is d -> 4.
278+
* So the result would be 0x10203004, where A is 1, BB is 02, CC is 03, DDD is 004.
279+
*/
280+
static jlong extractVersionToJlong(const char *astring)
281+
{
282+
long major = 0;
283+
long minor = 0;
284+
long fix = 0;
285+
long patch = 0;
286+
char patch_char = 0;
287+
if (sscanf(astring, "OpenSSL %ld.%ld.%ld%c", &major, &minor, &fix, &patch_char) < 3) {
288+
return -1;
289+
}
290+
if (isalpha(patch_char)) {
291+
patch = tolower(patch_char) - 'a' + 1;
292+
}
293+
return (jlong)OPENSSL_VERSION_CODE(major, minor, fix, patch);
294+
}
295+
264296
static void *crypto_library = NULL;
265297
/*
266298
* Class: jdk_crypto_jniprovider_NativeCrypto
267299
* Method: loadCrypto
268-
* Signature: (Z)I
300+
* Signature: (Z)J
269301
*/
270-
JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
302+
JNIEXPORT jlong JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
271303
(JNIEnv *env, jclass thisObj, jboolean trace)
272304
{
273305
char *error;
@@ -276,7 +308,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
276308
/* Determine the version of OpenSSL. */
277309
OSSL_version_t* OSSL_version;
278310
const char * openssl_version;
279-
int ossl_ver;
311+
jlong ossl_ver = 0;
280312

281313
/* Load OpenSSL Crypto library */
282314
crypto_library = load_crypto_library(trace);
@@ -310,7 +342,8 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
310342
} else {
311343
openssl_version = (*OSSL_version)(0); /* get OPENSSL_VERSION */
312344
/* Ensure the OpenSSL version is "OpenSSL 1.0.x" */
313-
if (0 != strncmp(openssl_version, OPENSSL_VERSION_1_0, strlen(OPENSSL_VERSION_1_0))) {
345+
ossl_ver = extractVersionToJlong(openssl_version);
346+
if (!((OPENSSL_VERSION_1_0_0 <= ossl_ver) && (ossl_ver < OPENSSL_VERSION_1_1_0))) {
314347
if (trace) {
315348
fprintf(stderr, "Error loading OpenSSL: Incompatible OpenSSL version found: %s\n", openssl_version);
316349
fflush(stderr);
@@ -319,13 +352,13 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
319352
crypto_library = NULL;
320353
return -1;
321354
}
322-
ossl_ver = 0;
323355
}
324356
} else {
325357
openssl_version = (*OSSL_version)(0); /* get OPENSSL_VERSION */
326358
/* Ensure the OpenSSL version is "OpenSSL 1.1.x" or "OpenSSL 3.x.x". */
327-
if ((0 != strncmp(openssl_version, OPENSSL_VERSION_1_1, strlen(OPENSSL_VERSION_1_1)))
328-
&& (0 != strncmp(openssl_version, OPENSSL_VERSION_3_X, strlen(OPENSSL_VERSION_3_X)))
359+
ossl_ver = extractVersionToJlong(openssl_version);
360+
if (!((OPENSSL_VERSION_1_1_0 <= ossl_ver) && (ossl_ver < OPENSSL_VERSION_2_0_0))
361+
&& !((OPENSSL_VERSION_3_0_0 <= ossl_ver) && (ossl_ver < OPENSSL_VERSION_4_0_0))
329362
) {
330363
if (trace) {
331364
fprintf(stderr, "Error loading OpenSSL: Incompatible OpenSSL version found: %s\n", openssl_version);
@@ -335,7 +368,6 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
335368
crypto_library = NULL;
336369
return -1;
337370
}
338-
ossl_ver = 1;
339371
}
340372

341373
/* Load the function symbols for OpenSSL errors. */
@@ -344,7 +376,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
344376
OSSL_get_error = (OSSL_get_error_t*)find_crypto_symbol(crypto_library, "ERR_get_error");
345377

346378
/* Load Threading routines for OpenSSL 1.0.2 */
347-
if (0 == ossl_ver) {
379+
if (ossl_ver < OPENSSL_VERSION_1_1_0) {
348380
OSSL_CRYPTO_num_locks = (OSSL_CRYPTO_num_locks_t*)find_crypto_symbol(crypto_library, "CRYPTO_num_locks");
349381
OSSL_CRYPTO_THREADID_set_numeric = (OSSL_CRYPTO_THREADID_set_numeric_t*)find_crypto_symbol(crypto_library, "CRYPTO_THREADID_set_numeric");
350382
OSSL_OPENSSL_malloc = (OSSL_OPENSSL_malloc_t*)find_crypto_symbol(crypto_library, "CRYPTO_malloc");
@@ -360,7 +392,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
360392
OSSL_sha384 = (OSSL_sha_t*)find_crypto_symbol(crypto_library, "EVP_sha384");
361393
OSSL_sha512 = (OSSL_sha_t*)find_crypto_symbol(crypto_library, "EVP_sha512");
362394

363-
if (1 == ossl_ver) {
395+
if (ossl_ver >= OPENSSL_VERSION_1_1_0) {
364396
OSSL_MD_CTX_new = (OSSL_MD_CTX_new_t*)find_crypto_symbol(crypto_library, "EVP_MD_CTX_new");
365397
OSSL_MD_CTX_reset = (OSSL_MD_CTX_reset_t*)find_crypto_symbol(crypto_library, "EVP_MD_CTX_reset");
366398
OSSL_MD_CTX_free = (OSSL_MD_CTX_free_t*)find_crypto_symbol(crypto_library, "EVP_MD_CTX_free");
@@ -394,7 +426,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
394426
OSSL_DecryptFinal = (OSSL_DecryptFinal_t*)find_crypto_symbol(crypto_library, "EVP_DecryptFinal");
395427

396428
/* Load the functions symbols for OpenSSL ChaCha20 algorithms. (Need OpenSSL 1.1.x or above) */
397-
if (1 == ossl_ver) {
429+
if (ossl_ver >= OPENSSL_VERSION_1_1_0) {
398430
OSSL_chacha20 = (OSSL_cipher_t*)find_crypto_symbol(crypto_library, "EVP_chacha20");
399431
OSSL_chacha20_poly1305 = (OSSL_cipher_t*)find_crypto_symbol(crypto_library, "EVP_chacha20_poly1305");
400432
} else {
@@ -405,7 +437,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
405437
/* Load the functions symbols for OpenSSL RSA algorithm. */
406438
OSSL_RSA_new = (OSSL_RSA_new_t*)find_crypto_symbol(crypto_library, "RSA_new");
407439

408-
if (1 == ossl_ver) {
440+
if (ossl_ver >= OPENSSL_VERSION_1_1_0) {
409441
OSSL_RSA_set0_key = (OSSL_RSA_set0_key_t*)find_crypto_symbol(crypto_library, "RSA_set0_key");
410442
OSSL_RSA_set0_factors = (OSSL_RSA_set0_factors_t*)find_crypto_symbol(crypto_library, "RSA_set0_factors");
411443
OSSL_RSA_set0_crt_params = (OSSL_RSA_set0_key_t*)find_crypto_symbol(crypto_library, "RSA_set0_crt_params");
@@ -524,14 +556,14 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
524556
(NULL == OSSL_EC_KEY_check_key) ||
525557
(NULL == OSSL_PKCS12_key_gen) ||
526558
/* Check symbols that are only available in OpenSSL 1.1.x and above */
527-
((1 == ossl_ver) && ((NULL == OSSL_chacha20) || (NULL == OSSL_chacha20_poly1305))) ||
559+
((ossl_ver >= OPENSSL_VERSION_1_1_0) && ((NULL == OSSL_chacha20) || (NULL == OSSL_chacha20_poly1305))) ||
528560
/* Check symbols that are only available in OpenSSL 1.0.x and above */
529-
((NULL == OSSL_CRYPTO_num_locks) && (0 == ossl_ver)) ||
530-
((NULL == OSSL_CRYPTO_THREADID_set_numeric) && (0 == ossl_ver)) ||
531-
((NULL == OSSL_OPENSSL_malloc) && (0 == ossl_ver)) ||
532-
((NULL == OSSL_OPENSSL_free) && (0 == ossl_ver)) ||
533-
((NULL == OSSL_CRYPTO_THREADID_set_callback) && (0 == ossl_ver)) ||
534-
((NULL == OSSL_CRYPTO_set_locking_callback) && (0 == ossl_ver))) {
561+
((NULL == OSSL_CRYPTO_num_locks) && (ossl_ver < OPENSSL_VERSION_1_1_0)) ||
562+
((NULL == OSSL_CRYPTO_THREADID_set_numeric) && (ossl_ver < OPENSSL_VERSION_1_1_0)) ||
563+
((NULL == OSSL_OPENSSL_malloc) && (ossl_ver < OPENSSL_VERSION_1_1_0)) ||
564+
((NULL == OSSL_OPENSSL_free) && (ossl_ver < OPENSSL_VERSION_1_1_0)) ||
565+
((NULL == OSSL_CRYPTO_THREADID_set_callback) && (ossl_ver < OPENSSL_VERSION_1_1_0)) ||
566+
((NULL == OSSL_CRYPTO_set_locking_callback) && (ossl_ver < OPENSSL_VERSION_1_1_0))) {
535567
if (trace) {
536568
fprintf(stderr, "Error loading OpenSSL: One or more of the required symbols are missing in the crypto library: %s\n", openssl_version);
537569
}
@@ -549,7 +581,7 @@ JNIEXPORT jint JNICALL Java_jdk_crypto_jniprovider_NativeCrypto_loadCrypto
549581
free(library_path);
550582
}
551583
}
552-
if (0 == ossl_ver) {
584+
if (ossl_ver < OPENSSL_VERSION_1_1_0) {
553585
if (0 != thread_setup()) {
554586
unload_crypto_library(crypto_library);
555587
crypto_library = NULL;

src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ void putEntries() {
336336
attrs.clear();
337337
attrs.put("SupportedKeyFormats", "RAW");
338338

339-
if (useNativeChaCha20Cipher && (NativeCrypto.getVersionIfAvailable() >= 1)) {
339+
if (useNativeChaCha20Cipher && (NativeCrypto.getVersionIfAvailable() >= NativeCrypto.OPENSSL_VERSION_1_1_0)) {
340340
ps("Cipher", "ChaCha20",
341341
"com.sun.crypto.provider.NativeChaCha20Cipher$ChaCha20Only",
342342
null, attrs);

0 commit comments

Comments
 (0)