Skip to content

Commit b887ef4

Browse files
authored
Merge pull request #468 from rhenium/ky/openssl-3.0.0-part1
Miscellaneous changes for OpenSSL 3.0 support
2 parents 9b4f761 + 7c2fc00 commit b887ef4

12 files changed

+168
-150
lines changed

ext/openssl/extconf.rb

+8-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def find_openssl_library
160160
have_func("TS_STATUS_INFO_get0_status")
161161
have_func("TS_STATUS_INFO_get0_text")
162162
have_func("TS_STATUS_INFO_get0_failure_info")
163-
have_func("TS_VERIFY_CTS_set_certs")
163+
have_func("TS_VERIFY_CTS_set_certs(NULL, NULL)", "openssl/ts.h")
164164
have_func("TS_VERIFY_CTX_set_store")
165165
have_func("TS_VERIFY_CTX_add_flags")
166166
have_func("TS_RESP_CTX_set_time_cb")
@@ -172,6 +172,13 @@ def find_openssl_library
172172

173173
# added in 3.0.0
174174
have_func("SSL_set0_tmp_dh_pkey")
175+
have_func("ERR_get_error_all")
176+
have_func("TS_VERIFY_CTX_set_certs(NULL, NULL)", "openssl/ts.h")
177+
have_func("SSL_CTX_load_verify_file")
178+
have_func("BN_check_prime")
179+
have_func("EVP_MD_CTX_get0_md")
180+
have_func("EVP_MD_CTX_get_pkey_ctx")
181+
have_func("EVP_PKEY_eq")
175182

176183
Logging::message "=== Checking done. ===\n"
177184

ext/openssl/openssl_missing.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
# define EVP_MD_CTX_free EVP_MD_CTX_destroy
2222
#endif
2323

24-
#if !defined(HAVE_EVP_MD_CTX_PKEY_CTX)
25-
# define EVP_MD_CTX_pkey_ctx(x) (x)->pctx
26-
#endif
27-
2824
#if !defined(HAVE_X509_STORE_GET_EX_DATA)
2925
# define X509_STORE_get_ex_data(x, idx) \
3026
CRYPTO_get_ex_data(&(x)->ex_data, (idx))
@@ -214,4 +210,29 @@ IMPL_PKEY_GETTER(EC_KEY, ec)
214210
} while (0)
215211
#endif
216212

213+
/* added in 3.0.0 */
214+
#if !defined(HAVE_TS_VERIFY_CTX_SET_CERTS)
215+
# define TS_VERIFY_CTX_set_certs(ctx, crts) TS_VERIFY_CTS_set_certs(ctx, crts)
216+
#endif
217+
218+
#ifndef HAVE_EVP_MD_CTX_GET0_MD
219+
# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx)
220+
#endif
221+
222+
/*
223+
* OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to
224+
* EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0.
225+
*/
226+
#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX
227+
# ifdef HAVE_EVP_MD_CTX_PKEY_CTX
228+
# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x)
229+
# else
230+
# define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
231+
# endif
232+
#endif
233+
234+
#ifndef HAVE_EVP_PKEY_EQ
235+
# define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b)
236+
#endif
237+
217238
#endif /* _OSSL_OPENSSL_MISSING_H_ */

ext/openssl/ossl.c

+23-19
Original file line numberDiff line numberDiff line change
@@ -313,27 +313,31 @@ void
313313
ossl_clear_error(void)
314314
{
315315
if (dOSSL == Qtrue) {
316-
unsigned long e;
317-
const char *file, *data, *errstr;
318-
int line, flags;
319-
320-
while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
321-
errstr = ERR_error_string(e, NULL);
322-
if (!errstr)
323-
errstr = "(null)";
324-
325-
if (flags & ERR_TXT_STRING) {
326-
if (!data)
327-
data = "(null)";
328-
rb_warn("error on stack: %s (%s)", errstr, data);
329-
}
330-
else {
331-
rb_warn("error on stack: %s", errstr);
332-
}
333-
}
316+
unsigned long e;
317+
const char *file, *data, *func, *lib, *reason;
318+
char append[256] = "";
319+
int line, flags;
320+
321+
#ifdef HAVE_ERR_GET_ERROR_ALL
322+
while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
323+
#else
324+
while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
325+
func = ERR_func_error_string(e);
326+
#endif
327+
lib = ERR_lib_error_string(e);
328+
reason = ERR_reason_error_string(e);
329+
330+
if (flags & ERR_TXT_STRING) {
331+
if (!data)
332+
data = "(null)";
333+
snprintf(append, sizeof(append), " (%s)", data);
334+
}
335+
rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
336+
func ? func : "", reason ? reason : "", append);
337+
}
334338
}
335339
else {
336-
ERR_clear_error();
340+
ERR_clear_error();
337341
}
338342
}
339343

ext/openssl/ossl.h

+12
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@
4242
#include <openssl/evp.h>
4343
#include <openssl/dh.h>
4444

45+
#ifndef LIBRESSL_VERSION_NUMBER
46+
# define OSSL_IS_LIBRESSL 0
47+
# define OSSL_OPENSSL_PREREQ(maj, min, pat) \
48+
(OPENSSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12))
49+
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0
50+
#else
51+
# define OSSL_IS_LIBRESSL 1
52+
# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0
53+
# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \
54+
(LIBRESSL_VERSION_NUMBER >= (maj << 28) | (min << 20) | (pat << 12))
55+
#endif
56+
4557
/*
4658
* Common Module
4759
*/

ext/openssl/ossl_bn.c

+72-114
Original file line numberDiff line numberDiff line change
@@ -792,78 +792,64 @@ BIGNUM_SELF_SHIFT(lshift)
792792
*/
793793
BIGNUM_SELF_SHIFT(rshift)
794794

795-
#define BIGNUM_RAND(func) \
796-
static VALUE \
797-
ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
798-
{ \
799-
BIGNUM *result; \
800-
int bottom = 0, top = 0, b; \
801-
VALUE bits, fill, odd, obj; \
802-
\
803-
switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
804-
case 3: \
805-
bottom = (odd == Qtrue) ? 1 : 0; \
806-
/* FALLTHROUGH */ \
807-
case 2: \
808-
top = NUM2INT(fill); \
809-
} \
810-
b = NUM2INT(bits); \
811-
obj = NewBN(klass); \
812-
if (!(result = BN_new())) { \
813-
ossl_raise(eBNError, NULL); \
814-
} \
815-
if (BN_##func(result, b, top, bottom) <= 0) { \
816-
BN_free(result); \
817-
ossl_raise(eBNError, NULL); \
818-
} \
819-
SetBN(obj, result); \
820-
return obj; \
821-
}
822-
823-
/*
824-
* Document-method: OpenSSL::BN.rand
825-
* BN.rand(bits [, fill [, odd]]) -> aBN
826-
*/
827-
BIGNUM_RAND(rand)
828-
829795
/*
830-
* Document-method: OpenSSL::BN.pseudo_rand
831-
* BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
832-
*/
833-
BIGNUM_RAND(pseudo_rand)
834-
835-
#define BIGNUM_RAND_RANGE(func) \
836-
static VALUE \
837-
ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
838-
{ \
839-
BIGNUM *bn = GetBNPtr(range), *result; \
840-
VALUE obj = NewBN(klass); \
841-
if (!(result = BN_new())) { \
842-
ossl_raise(eBNError, NULL); \
843-
} \
844-
if (BN_##func##_range(result, bn) <= 0) { \
845-
BN_free(result); \
846-
ossl_raise(eBNError, NULL); \
847-
} \
848-
SetBN(obj, result); \
849-
return obj; \
850-
}
851-
852-
/*
853-
* Document-method: OpenSSL::BN.rand_range
854796
* call-seq:
855-
* BN.rand_range(range) -> aBN
797+
* BN.rand(bits [, fill [, odd]]) -> aBN
798+
*
799+
* Generates a cryptographically strong pseudo-random number of +bits+.
856800
*
801+
* See also the man page BN_rand(3).
857802
*/
858-
BIGNUM_RAND_RANGE(rand)
803+
static VALUE
804+
ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass)
805+
{
806+
BIGNUM *result;
807+
int bottom = 0, top = 0, b;
808+
VALUE bits, fill, odd, obj;
809+
810+
switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) {
811+
case 3:
812+
bottom = (odd == Qtrue) ? 1 : 0;
813+
/* FALLTHROUGH */
814+
case 2:
815+
top = NUM2INT(fill);
816+
}
817+
b = NUM2INT(bits);
818+
obj = NewBN(klass);
819+
if (!(result = BN_new())) {
820+
ossl_raise(eBNError, "BN_new");
821+
}
822+
if (BN_rand(result, b, top, bottom) <= 0) {
823+
BN_free(result);
824+
ossl_raise(eBNError, "BN_rand");
825+
}
826+
SetBN(obj, result);
827+
return obj;
828+
}
859829

860830
/*
861-
* Document-method: OpenSSL::BN.pseudo_rand_range
862831
* call-seq:
863-
* BN.pseudo_rand_range(range) -> aBN
832+
* BN.rand_range(range) -> aBN
864833
*
834+
* Generates a cryptographically strong pseudo-random number in the range
835+
* 0...+range+.
836+
*
837+
* See also the man page BN_rand_range(3).
865838
*/
866-
BIGNUM_RAND_RANGE(pseudo_rand)
839+
static VALUE
840+
ossl_bn_s_rand_range(VALUE klass, VALUE range)
841+
{
842+
BIGNUM *bn = GetBNPtr(range), *result;
843+
VALUE obj = NewBN(klass);
844+
if (!(result = BN_new()))
845+
ossl_raise(eBNError, "BN_new");
846+
if (BN_rand_range(result, bn) <= 0) {
847+
BN_free(result);
848+
ossl_raise(eBNError, "BN_rand_range");
849+
}
850+
SetBN(obj, result);
851+
return obj;
852+
}
867853

868854
/*
869855
* call-seq:
@@ -1118,34 +1104,29 @@ ossl_bn_hash(VALUE self)
11181104
* bn.prime? => true | false
11191105
* bn.prime?(checks) => true | false
11201106
*
1121-
* Performs a Miller-Rabin probabilistic primality test with _checks_
1122-
* iterations. If _checks_ is not specified, a number of iterations is used
1123-
* that yields a false positive rate of at most 2^-80 for random input.
1107+
* Performs a Miller-Rabin probabilistic primality test for +bn+.
11241108
*
1125-
* === Parameters
1126-
* * _checks_ - integer
1109+
* <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect.
11271110
*/
11281111
static VALUE
11291112
ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
11301113
{
11311114
BIGNUM *bn;
1132-
VALUE vchecks;
1133-
int checks = BN_prime_checks;
1115+
int ret;
11341116

1135-
if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
1136-
checks = NUM2INT(vchecks);
1137-
}
1117+
rb_check_arity(argc, 0, 1);
11381118
GetBN(self, bn);
1139-
switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
1140-
case 1:
1141-
return Qtrue;
1142-
case 0:
1143-
return Qfalse;
1144-
default:
1145-
ossl_raise(eBNError, NULL);
1146-
}
1147-
/* not reachable */
1148-
return Qnil;
1119+
1120+
#ifdef HAVE_BN_CHECK_PRIME
1121+
ret = BN_check_prime(bn, ossl_bn_ctx, NULL);
1122+
if (ret < 0)
1123+
ossl_raise(eBNError, "BN_check_prime");
1124+
#else
1125+
ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL);
1126+
if (ret < 0)
1127+
ossl_raise(eBNError, "BN_is_prime_fasttest_ex");
1128+
#endif
1129+
return ret ? Qtrue : Qfalse;
11491130
}
11501131

11511132
/*
@@ -1154,40 +1135,17 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
11541135
* bn.prime_fasttest?(checks) => true | false
11551136
* bn.prime_fasttest?(checks, trial_div) => true | false
11561137
*
1157-
* Performs a Miller-Rabin primality test. This is same as #prime? except this
1158-
* first attempts trial divisions with some small primes.
1138+
* Performs a Miller-Rabin probabilistic primality test for +bn+.
11591139
*
1160-
* === Parameters
1161-
* * _checks_ - integer
1162-
* * _trial_div_ - boolean
1140+
* <b>Deprecated in version 3.0.</b> Use #prime? instead.
1141+
*
1142+
* +checks+ and +trial_div+ parameters no longer have any effect.
11631143
*/
11641144
static VALUE
11651145
ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
11661146
{
1167-
BIGNUM *bn;
1168-
VALUE vchecks, vtrivdiv;
1169-
int checks = BN_prime_checks, do_trial_division = 1;
1170-
1171-
rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1172-
1173-
if (!NIL_P(vchecks)) {
1174-
checks = NUM2INT(vchecks);
1175-
}
1176-
GetBN(self, bn);
1177-
/* handle true/false */
1178-
if (vtrivdiv == Qfalse) {
1179-
do_trial_division = 0;
1180-
}
1181-
switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
1182-
case 1:
1183-
return Qtrue;
1184-
case 0:
1185-
return Qfalse;
1186-
default:
1187-
ossl_raise(eBNError, NULL);
1188-
}
1189-
/* not reachable */
1190-
return Qnil;
1147+
rb_check_arity(argc, 0, 2);
1148+
return ossl_bn_is_prime(0, argv, self);
11911149
}
11921150

11931151
/*
@@ -1306,9 +1264,9 @@ Init_ossl_bn(void)
13061264
* get_word */
13071265

13081266
rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
1309-
rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
13101267
rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
1311-
rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
1268+
rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand");
1269+
rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range");
13121270

13131271
rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
13141272
rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);

ext/openssl/ossl_digest.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ ossl_evp_get_digestbyname(VALUE obj)
6363

6464
GetDigest(obj, ctx);
6565

66-
md = EVP_MD_CTX_md(ctx);
66+
md = EVP_MD_CTX_get0_md(ctx);
6767
}
6868

6969
return md;
@@ -176,7 +176,7 @@ ossl_digest_reset(VALUE self)
176176
EVP_MD_CTX *ctx;
177177

178178
GetDigest(self, ctx);
179-
if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) {
179+
if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) {
180180
ossl_raise(eDigestError, "Digest initialization failed.");
181181
}
182182

@@ -259,7 +259,7 @@ ossl_digest_name(VALUE self)
259259

260260
GetDigest(self, ctx);
261261

262-
return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx)));
262+
return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx)));
263263
}
264264

265265
/*

0 commit comments

Comments
 (0)