openssl 2.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +35 -45
- data/History.md +426 -0
- data/README.md +38 -21
- data/ext/openssl/extconf.rb +132 -72
- data/ext/openssl/openssl_missing.c +0 -66
- data/ext/openssl/openssl_missing.h +62 -46
- data/ext/openssl/ossl.c +177 -252
- data/ext/openssl/ossl.h +39 -17
- data/ext/openssl/ossl_asn1.c +53 -14
- data/ext/openssl/ossl_bn.c +288 -146
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +42 -32
- data/ext/openssl/ossl_config.c +412 -41
- data/ext/openssl/ossl_config.h +4 -7
- data/ext/openssl/ossl_digest.c +32 -63
- data/ext/openssl/ossl_engine.c +19 -28
- data/ext/openssl/ossl_hmac.c +61 -146
- data/ext/openssl/ossl_kdf.c +15 -23
- data/ext/openssl/ossl_ns_spki.c +2 -2
- data/ext/openssl/ossl_ocsp.c +17 -70
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +23 -4
- data/ext/openssl/ossl_pkcs7.c +49 -81
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +1508 -195
- data/ext/openssl/ossl_pkey.h +41 -78
- data/ext/openssl/ossl_pkey_dh.c +153 -348
- data/ext/openssl/ossl_pkey_dsa.c +157 -413
- data/ext/openssl/ossl_pkey_ec.c +257 -343
- data/ext/openssl/ossl_pkey_rsa.c +166 -490
- data/ext/openssl/ossl_provider.c +211 -0
- data/ext/openssl/ossl_provider.h +5 -0
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +666 -456
- data/ext/openssl/ossl_ssl_session.c +29 -30
- data/ext/openssl/ossl_ts.c +1539 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +86 -1
- data/ext/openssl/ossl_x509attr.c +1 -1
- data/ext/openssl/ossl_x509cert.c +170 -14
- data/ext/openssl/ossl_x509crl.c +14 -11
- data/ext/openssl/ossl_x509ext.c +29 -9
- data/ext/openssl/ossl_x509name.c +24 -12
- data/ext/openssl/ossl_x509req.c +14 -11
- data/ext/openssl/ossl_x509revoked.c +4 -4
- data/ext/openssl/ossl_x509store.c +205 -96
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +42 -20
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/digest.rb +10 -16
- data/lib/openssl/hmac.rb +78 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +447 -1
- data/lib/openssl/ssl.rb +68 -24
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +177 -1
- data/lib/openssl.rb +24 -9
- metadata +18 -71
- data/ext/openssl/deprecation.rb +0 -23
- data/ext/openssl/ossl_version.h +0 -15
- data/ext/openssl/ruby_missing.h +0 -24
- data/lib/openssl/config.rb +0 -474
data/ext/openssl/ossl.c
CHANGED
@@ -9,13 +9,19 @@
|
|
9
9
|
*/
|
10
10
|
#include "ossl.h"
|
11
11
|
#include <stdarg.h> /* for ossl_raise */
|
12
|
-
|
12
|
+
|
13
|
+
/* OpenSSL >= 1.1.0 and LibreSSL >= 2.9.0 */
|
14
|
+
#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER >= 0x10100000
|
15
|
+
# define HAVE_OPENSSL_110_THREADING_API
|
16
|
+
#else
|
17
|
+
# include <ruby/thread_native.h>
|
18
|
+
#endif
|
13
19
|
|
14
20
|
/*
|
15
21
|
* Data Conversion
|
16
22
|
*/
|
17
23
|
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
|
18
|
-
|
24
|
+
VALUE \
|
19
25
|
ossl_##name##_ary2sk0(VALUE ary) \
|
20
26
|
{ \
|
21
27
|
STACK_OF(type) *sk; \
|
@@ -37,7 +43,7 @@ ossl_##name##_ary2sk0(VALUE ary) \
|
|
37
43
|
x = dup(val); /* NEED TO DUP */ \
|
38
44
|
sk_##type##_push(sk, x); \
|
39
45
|
} \
|
40
|
-
return sk;
|
46
|
+
return (VALUE)sk; \
|
41
47
|
} \
|
42
48
|
\
|
43
49
|
STACK_OF(type) * \
|
@@ -201,7 +207,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_)
|
|
201
207
|
|
202
208
|
while (1) {
|
203
209
|
/*
|
204
|
-
* when the flag is nonzero, this
|
210
|
+
* when the flag is nonzero, this password
|
205
211
|
* will be used to perform encryption; otherwise it will
|
206
212
|
* be used to perform decryption.
|
207
213
|
*/
|
@@ -262,31 +268,32 @@ ossl_to_der_if_possible(VALUE obj)
|
|
262
268
|
/*
|
263
269
|
* Errors
|
264
270
|
*/
|
265
|
-
|
266
|
-
ossl_make_error(VALUE exc,
|
271
|
+
VALUE
|
272
|
+
ossl_make_error(VALUE exc, VALUE str)
|
267
273
|
{
|
268
|
-
VALUE str = Qnil;
|
269
274
|
unsigned long e;
|
275
|
+
const char *data;
|
276
|
+
int flags;
|
270
277
|
|
271
|
-
if (
|
272
|
-
|
273
|
-
|
274
|
-
|
278
|
+
if (NIL_P(str))
|
279
|
+
str = rb_str_new(NULL, 0);
|
280
|
+
|
281
|
+
#ifdef HAVE_ERR_GET_ERROR_ALL
|
282
|
+
e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags);
|
283
|
+
#else
|
284
|
+
e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags);
|
285
|
+
#endif
|
275
286
|
if (e) {
|
276
|
-
|
287
|
+
const char *msg = ERR_reason_error_string(e);
|
277
288
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
rb_str_cat2(str, msg ? msg : "(null)");
|
284
|
-
}
|
285
|
-
ossl_clear_error();
|
289
|
+
if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": ");
|
290
|
+
rb_str_cat_cstr(str, msg ? msg : "(null)");
|
291
|
+
if (flags & ERR_TXT_STRING && data)
|
292
|
+
rb_str_catf(str, " (%s)", data);
|
293
|
+
ossl_clear_error();
|
286
294
|
}
|
287
295
|
|
288
|
-
|
289
|
-
return rb_exc_new3(exc, str);
|
296
|
+
return rb_exc_new_str(exc, str);
|
290
297
|
}
|
291
298
|
|
292
299
|
void
|
@@ -294,37 +301,48 @@ ossl_raise(VALUE exc, const char *fmt, ...)
|
|
294
301
|
{
|
295
302
|
va_list args;
|
296
303
|
VALUE err;
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
304
|
+
|
305
|
+
if (fmt) {
|
306
|
+
va_start(args, fmt);
|
307
|
+
err = rb_vsprintf(fmt, args);
|
308
|
+
va_end(args);
|
309
|
+
}
|
310
|
+
else {
|
311
|
+
err = Qnil;
|
312
|
+
}
|
313
|
+
|
314
|
+
rb_exc_raise(ossl_make_error(exc, err));
|
301
315
|
}
|
302
316
|
|
303
317
|
void
|
304
318
|
ossl_clear_error(void)
|
305
319
|
{
|
306
320
|
if (dOSSL == Qtrue) {
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
321
|
+
unsigned long e;
|
322
|
+
const char *file, *data, *func, *lib, *reason;
|
323
|
+
char append[256] = "";
|
324
|
+
int line, flags;
|
325
|
+
|
326
|
+
#ifdef HAVE_ERR_GET_ERROR_ALL
|
327
|
+
while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) {
|
328
|
+
#else
|
329
|
+
while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) {
|
330
|
+
func = ERR_func_error_string(e);
|
331
|
+
#endif
|
332
|
+
lib = ERR_lib_error_string(e);
|
333
|
+
reason = ERR_reason_error_string(e);
|
334
|
+
|
335
|
+
if (flags & ERR_TXT_STRING) {
|
336
|
+
if (!data)
|
337
|
+
data = "(null)";
|
338
|
+
snprintf(append, sizeof(append), " (%s)", data);
|
339
|
+
}
|
340
|
+
rb_warn("error on stack: error:%08lX:%s:%s:%s%s", e, lib ? lib : "",
|
341
|
+
func ? func : "", reason ? reason : "", append);
|
342
|
+
}
|
325
343
|
}
|
326
344
|
else {
|
327
|
-
|
345
|
+
ERR_clear_error();
|
328
346
|
}
|
329
347
|
}
|
330
348
|
|
@@ -338,7 +356,7 @@ ossl_clear_error(void)
|
|
338
356
|
* implementation.
|
339
357
|
*/
|
340
358
|
VALUE
|
341
|
-
ossl_get_errors(
|
359
|
+
ossl_get_errors(VALUE _)
|
342
360
|
{
|
343
361
|
VALUE ary;
|
344
362
|
long e;
|
@@ -356,22 +374,6 @@ ossl_get_errors(void)
|
|
356
374
|
*/
|
357
375
|
VALUE dOSSL;
|
358
376
|
|
359
|
-
#if !defined(HAVE_VA_ARGS_MACRO)
|
360
|
-
void
|
361
|
-
ossl_debug(const char *fmt, ...)
|
362
|
-
{
|
363
|
-
va_list args;
|
364
|
-
|
365
|
-
if (dOSSL == Qtrue) {
|
366
|
-
fprintf(stderr, "OSSL_DEBUG: ");
|
367
|
-
va_start(args, fmt);
|
368
|
-
vfprintf(stderr, fmt, args);
|
369
|
-
va_end(args);
|
370
|
-
fprintf(stderr, " [CONTEXT N/A]\n");
|
371
|
-
}
|
372
|
-
}
|
373
|
-
#endif
|
374
|
-
|
375
377
|
/*
|
376
378
|
* call-seq:
|
377
379
|
* OpenSSL.debug -> true | false
|
@@ -386,7 +388,7 @@ ossl_debug_get(VALUE self)
|
|
386
388
|
* call-seq:
|
387
389
|
* OpenSSL.debug = boolean -> boolean
|
388
390
|
*
|
389
|
-
* Turns on or off debug mode. With debug mode, all
|
391
|
+
* Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
|
390
392
|
* error queue will be printed to stderr.
|
391
393
|
*/
|
392
394
|
static VALUE
|
@@ -398,14 +400,18 @@ ossl_debug_set(VALUE self, VALUE val)
|
|
398
400
|
}
|
399
401
|
|
400
402
|
/*
|
401
|
-
* call-seq
|
403
|
+
* call-seq:
|
402
404
|
* OpenSSL.fips_mode -> true | false
|
403
405
|
*/
|
404
406
|
static VALUE
|
405
407
|
ossl_fips_mode_get(VALUE self)
|
406
408
|
{
|
407
409
|
|
408
|
-
#
|
410
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
411
|
+
VALUE enabled;
|
412
|
+
enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
|
413
|
+
return enabled;
|
414
|
+
#elif defined(OPENSSL_FIPS)
|
409
415
|
VALUE enabled;
|
410
416
|
enabled = FIPS_mode() ? Qtrue : Qfalse;
|
411
417
|
return enabled;
|
@@ -429,8 +435,18 @@ ossl_fips_mode_get(VALUE self)
|
|
429
435
|
static VALUE
|
430
436
|
ossl_fips_mode_set(VALUE self, VALUE enabled)
|
431
437
|
{
|
432
|
-
|
433
|
-
|
438
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
439
|
+
if (RTEST(enabled)) {
|
440
|
+
if (!EVP_default_properties_enable_fips(NULL, 1)) {
|
441
|
+
ossl_raise(eOSSLError, "Turning on FIPS mode failed");
|
442
|
+
}
|
443
|
+
} else {
|
444
|
+
if (!EVP_default_properties_enable_fips(NULL, 0)) {
|
445
|
+
ossl_raise(eOSSLError, "Turning off FIPS mode failed");
|
446
|
+
}
|
447
|
+
}
|
448
|
+
return enabled;
|
449
|
+
#elif defined(OPENSSL_FIPS)
|
434
450
|
if (RTEST(enabled)) {
|
435
451
|
int mode = FIPS_mode();
|
436
452
|
if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
|
@@ -447,72 +463,6 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
|
|
447
463
|
#endif
|
448
464
|
}
|
449
465
|
|
450
|
-
#if defined(OSSL_DEBUG)
|
451
|
-
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
452
|
-
(OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
|
453
|
-
defined(CRYPTO_malloc_debug_init))
|
454
|
-
/*
|
455
|
-
* call-seq:
|
456
|
-
* OpenSSL.mem_check_start -> nil
|
457
|
-
*
|
458
|
-
* Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory
|
459
|
-
* allocations. See also OpenSSL.print_mem_leaks.
|
460
|
-
*
|
461
|
-
* This is available only when built with a capable OpenSSL and --enable-debug
|
462
|
-
* configure option.
|
463
|
-
*/
|
464
|
-
static VALUE
|
465
|
-
mem_check_start(VALUE self)
|
466
|
-
{
|
467
|
-
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
|
468
|
-
return Qnil;
|
469
|
-
}
|
470
|
-
|
471
|
-
/*
|
472
|
-
* call-seq:
|
473
|
-
* OpenSSL.print_mem_leaks -> true | false
|
474
|
-
*
|
475
|
-
* For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr).
|
476
|
-
* Prints detected memory leaks to standard error. This cleans the global state
|
477
|
-
* up thus you cannot use any methods of the library after calling this.
|
478
|
-
*
|
479
|
-
* Returns +true+ if leaks detected, +false+ otherwise.
|
480
|
-
*
|
481
|
-
* This is available only when built with a capable OpenSSL and --enable-debug
|
482
|
-
* configure option.
|
483
|
-
*
|
484
|
-
* === Example
|
485
|
-
* OpenSSL.mem_check_start
|
486
|
-
* NOT_GCED = OpenSSL::PKey::RSA.new(256)
|
487
|
-
*
|
488
|
-
* END {
|
489
|
-
* GC.start
|
490
|
-
* OpenSSL.print_mem_leaks # will print the leakage
|
491
|
-
* }
|
492
|
-
*/
|
493
|
-
static VALUE
|
494
|
-
print_mem_leaks(VALUE self)
|
495
|
-
{
|
496
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
497
|
-
int ret;
|
498
|
-
#endif
|
499
|
-
|
500
|
-
BN_CTX_free(ossl_bn_ctx);
|
501
|
-
ossl_bn_ctx = NULL;
|
502
|
-
|
503
|
-
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
504
|
-
ret = CRYPTO_mem_leaks_fp(stderr);
|
505
|
-
if (ret < 0)
|
506
|
-
ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp");
|
507
|
-
return ret ? Qfalse : Qtrue;
|
508
|
-
#else
|
509
|
-
CRYPTO_mem_leaks_fp(stderr);
|
510
|
-
return Qnil;
|
511
|
-
#endif
|
512
|
-
}
|
513
|
-
#endif
|
514
|
-
#endif
|
515
|
-
|
516
466
|
#if !defined(HAVE_OPENSSL_110_THREADING_API)
|
517
467
|
/**
|
518
468
|
* Stores locks needed for OpenSSL thread safety
|
@@ -604,6 +554,35 @@ static void Init_ossl_locks(void)
|
|
604
554
|
}
|
605
555
|
#endif /* !HAVE_OPENSSL_110_THREADING_API */
|
606
556
|
|
557
|
+
/*
|
558
|
+
* call-seq:
|
559
|
+
* OpenSSL.fixed_length_secure_compare(string, string) -> boolean
|
560
|
+
*
|
561
|
+
* Constant time memory comparison for fixed length strings, such as results
|
562
|
+
* of HMAC calculations.
|
563
|
+
*
|
564
|
+
* Returns +true+ if the strings are identical, +false+ if they are of the same
|
565
|
+
* length but not identical. If the length is different, +ArgumentError+ is
|
566
|
+
* raised.
|
567
|
+
*/
|
568
|
+
static VALUE
|
569
|
+
ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
|
570
|
+
{
|
571
|
+
const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
|
572
|
+
const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
|
573
|
+
long len1 = RSTRING_LEN(str1);
|
574
|
+
long len2 = RSTRING_LEN(str2);
|
575
|
+
|
576
|
+
if (len1 != len2) {
|
577
|
+
ossl_raise(rb_eArgError, "inputs must be of equal length");
|
578
|
+
}
|
579
|
+
|
580
|
+
switch (CRYPTO_memcmp(p1, p2, len1)) {
|
581
|
+
case 0: return Qtrue;
|
582
|
+
default: return Qfalse;
|
583
|
+
}
|
584
|
+
}
|
585
|
+
|
607
586
|
/*
|
608
587
|
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
|
609
588
|
* OpenSSL[https://www.openssl.org/] library.
|
@@ -626,23 +605,21 @@ static void Init_ossl_locks(void)
|
|
626
605
|
*
|
627
606
|
* key = OpenSSL::PKey::RSA.new 2048
|
628
607
|
*
|
629
|
-
*
|
630
|
-
*
|
608
|
+
* File.write 'private_key.pem', key.private_to_pem
|
609
|
+
* File.write 'public_key.pem', key.public_to_pem
|
631
610
|
*
|
632
611
|
* === Exporting a Key
|
633
612
|
*
|
634
613
|
* Keys saved to disk without encryption are not secure as anyone who gets
|
635
614
|
* ahold of the key may use it unless it is encrypted. In order to securely
|
636
|
-
* export a key you may export it with a
|
615
|
+
* export a key you may export it with a password.
|
637
616
|
*
|
638
|
-
* cipher = OpenSSL::Cipher.new '
|
639
|
-
*
|
617
|
+
* cipher = OpenSSL::Cipher.new 'aes-256-cbc'
|
618
|
+
* password = 'my secure password goes here'
|
640
619
|
*
|
641
|
-
* key_secure = key.
|
620
|
+
* key_secure = key.private_to_pem cipher, password
|
642
621
|
*
|
643
|
-
*
|
644
|
-
* io.write key_secure
|
645
|
-
* end
|
622
|
+
* File.write 'private.secure.pem', key_secure
|
646
623
|
*
|
647
624
|
* OpenSSL::Cipher.ciphers returns a list of available ciphers.
|
648
625
|
*
|
@@ -650,25 +627,25 @@ static void Init_ossl_locks(void)
|
|
650
627
|
*
|
651
628
|
* A key can also be loaded from a file.
|
652
629
|
*
|
653
|
-
* key2 = OpenSSL::PKey
|
630
|
+
* key2 = OpenSSL::PKey.read File.read 'private_key.pem'
|
654
631
|
* key2.public? # => true
|
655
632
|
* key2.private? # => true
|
656
633
|
*
|
657
634
|
* or
|
658
635
|
*
|
659
|
-
* key3 = OpenSSL::PKey
|
636
|
+
* key3 = OpenSSL::PKey.read File.read 'public_key.pem'
|
660
637
|
* key3.public? # => true
|
661
638
|
* key3.private? # => false
|
662
639
|
*
|
663
640
|
* === Loading an Encrypted Key
|
664
641
|
*
|
665
|
-
* OpenSSL will prompt you for your
|
666
|
-
* If you will not be able to type in the
|
642
|
+
* OpenSSL will prompt you for your password when loading an encrypted key.
|
643
|
+
* If you will not be able to type in the password you may provide it when
|
667
644
|
* loading the key:
|
668
645
|
*
|
669
646
|
* key4_pem = File.read 'private.secure.pem'
|
670
|
-
*
|
671
|
-
* key4 = OpenSSL::PKey
|
647
|
+
* password = 'my secure password goes here'
|
648
|
+
* key4 = OpenSSL::PKey.read key4_pem, password
|
672
649
|
*
|
673
650
|
* == RSA Encryption
|
674
651
|
*
|
@@ -710,16 +687,14 @@ static void Init_ossl_locks(void)
|
|
710
687
|
* To sign a document, a cryptographically secure hash of the document is
|
711
688
|
* computed first, which is then signed using the private key.
|
712
689
|
*
|
713
|
-
*
|
714
|
-
* signature = key.sign digest, document
|
690
|
+
* signature = key.sign 'SHA256', document
|
715
691
|
*
|
716
692
|
* To validate the signature, again a hash of the document is computed and
|
717
693
|
* the signature is decrypted using the public key. The result is then
|
718
694
|
* compared to the hash just computed, if they are equal the signature was
|
719
695
|
* valid.
|
720
696
|
*
|
721
|
-
*
|
722
|
-
* if key.verify digest, signature, document
|
697
|
+
* if key.verify 'SHA256', signature, document
|
723
698
|
* puts 'Valid'
|
724
699
|
* else
|
725
700
|
* puts 'Invalid'
|
@@ -745,7 +720,7 @@ static void Init_ossl_locks(void)
|
|
745
720
|
* using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
|
746
721
|
* the number of iterations largely depends on the hardware being used.
|
747
722
|
*
|
748
|
-
* cipher = OpenSSL::Cipher.new '
|
723
|
+
* cipher = OpenSSL::Cipher.new 'aes-256-cbc'
|
749
724
|
* cipher.encrypt
|
750
725
|
* iv = cipher.random_iv
|
751
726
|
*
|
@@ -753,7 +728,7 @@ static void Init_ossl_locks(void)
|
|
753
728
|
* salt = OpenSSL::Random.random_bytes 16
|
754
729
|
* iter = 20000
|
755
730
|
* key_len = cipher.key_len
|
756
|
-
* digest = OpenSSL::Digest
|
731
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
757
732
|
*
|
758
733
|
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
|
759
734
|
* cipher.key = key
|
@@ -768,7 +743,7 @@ static void Init_ossl_locks(void)
|
|
768
743
|
* Use the same steps as before to derive the symmetric AES key, this time
|
769
744
|
* setting the Cipher up for decryption.
|
770
745
|
*
|
771
|
-
* cipher = OpenSSL::Cipher.new '
|
746
|
+
* cipher = OpenSSL::Cipher.new 'aes-256-cbc'
|
772
747
|
* cipher.decrypt
|
773
748
|
* cipher.iv = iv # the one generated with #random_iv
|
774
749
|
*
|
@@ -776,7 +751,7 @@ static void Init_ossl_locks(void)
|
|
776
751
|
* salt = ... # the one generated above
|
777
752
|
* iter = 20000
|
778
753
|
* key_len = cipher.key_len
|
779
|
-
* digest = OpenSSL::Digest
|
754
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
780
755
|
*
|
781
756
|
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
|
782
757
|
* cipher.key = key
|
@@ -786,45 +761,6 @@ static void Init_ossl_locks(void)
|
|
786
761
|
* decrypted = cipher.update encrypted
|
787
762
|
* decrypted << cipher.final
|
788
763
|
*
|
789
|
-
* == PKCS #5 Password-based Encryption
|
790
|
-
*
|
791
|
-
* PKCS #5 is a password-based encryption standard documented at
|
792
|
-
* RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
|
793
|
-
* passphrase to be used to create a secure encryption key. If possible, PBKDF2
|
794
|
-
* as described above should be used if the circumstances allow it.
|
795
|
-
*
|
796
|
-
* PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
|
797
|
-
* key.
|
798
|
-
*
|
799
|
-
* pass_phrase = 'my secure pass phrase goes here'
|
800
|
-
* salt = '8 octets'
|
801
|
-
*
|
802
|
-
* === Encryption
|
803
|
-
*
|
804
|
-
* First set up the cipher for encryption
|
805
|
-
*
|
806
|
-
* encryptor = OpenSSL::Cipher.new 'AES-128-CBC'
|
807
|
-
* encryptor.encrypt
|
808
|
-
* encryptor.pkcs5_keyivgen pass_phrase, salt
|
809
|
-
*
|
810
|
-
* Then pass the data you want to encrypt through
|
811
|
-
*
|
812
|
-
* encrypted = encryptor.update 'top secret document'
|
813
|
-
* encrypted << encryptor.final
|
814
|
-
*
|
815
|
-
* === Decryption
|
816
|
-
*
|
817
|
-
* Use a new Cipher instance set up for decryption
|
818
|
-
*
|
819
|
-
* decryptor = OpenSSL::Cipher.new 'AES-128-CBC'
|
820
|
-
* decryptor.decrypt
|
821
|
-
* decryptor.pkcs5_keyivgen pass_phrase, salt
|
822
|
-
*
|
823
|
-
* Then pass the data you want to decrypt through
|
824
|
-
*
|
825
|
-
* plain = decryptor.update encrypted
|
826
|
-
* plain << decryptor.final
|
827
|
-
*
|
828
764
|
* == X509 Certificates
|
829
765
|
*
|
830
766
|
* === Creating a Certificate
|
@@ -833,7 +769,7 @@ static void Init_ossl_locks(void)
|
|
833
769
|
* signature.
|
834
770
|
*
|
835
771
|
* key = OpenSSL::PKey::RSA.new 2048
|
836
|
-
* name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
|
772
|
+
* name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
|
837
773
|
*
|
838
774
|
* cert = OpenSSL::X509::Certificate.new
|
839
775
|
* cert.version = 2
|
@@ -872,7 +808,7 @@ static void Init_ossl_locks(void)
|
|
872
808
|
* certificate.
|
873
809
|
*
|
874
810
|
* cert.issuer = name
|
875
|
-
* cert.sign key, OpenSSL::Digest
|
811
|
+
* cert.sign key, OpenSSL::Digest.new('SHA1')
|
876
812
|
*
|
877
813
|
* open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
|
878
814
|
*
|
@@ -902,12 +838,12 @@ static void Init_ossl_locks(void)
|
|
902
838
|
* not readable by other users.
|
903
839
|
*
|
904
840
|
* ca_key = OpenSSL::PKey::RSA.new 2048
|
905
|
-
*
|
841
|
+
* password = 'my secure password goes here'
|
906
842
|
*
|
907
|
-
* cipher =
|
843
|
+
* cipher = 'aes-256-cbc'
|
908
844
|
*
|
909
845
|
* open 'ca_key.pem', 'w', 0400 do |io|
|
910
|
-
* io.write ca_key.
|
846
|
+
* io.write ca_key.private_to_pem(cipher, password)
|
911
847
|
* end
|
912
848
|
*
|
913
849
|
* === CA Certificate
|
@@ -915,7 +851,7 @@ static void Init_ossl_locks(void)
|
|
915
851
|
* A CA certificate is created the same way we created a certificate above, but
|
916
852
|
* with different extensions.
|
917
853
|
*
|
918
|
-
* ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
|
854
|
+
* ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
|
919
855
|
*
|
920
856
|
* ca_cert = OpenSSL::X509::Certificate.new
|
921
857
|
* ca_cert.serial = 0
|
@@ -948,7 +884,7 @@ static void Init_ossl_locks(void)
|
|
948
884
|
*
|
949
885
|
* Root CA certificates are self-signed.
|
950
886
|
*
|
951
|
-
* ca_cert.sign ca_key, OpenSSL::Digest
|
887
|
+
* ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
|
952
888
|
*
|
953
889
|
* The CA certificate is saved to disk so it may be distributed to all the
|
954
890
|
* users of the keys this CA will sign.
|
@@ -966,7 +902,7 @@ static void Init_ossl_locks(void)
|
|
966
902
|
* csr.version = 0
|
967
903
|
* csr.subject = name
|
968
904
|
* csr.public_key = key.public_key
|
969
|
-
* csr.sign key, OpenSSL::Digest
|
905
|
+
* csr.sign key, OpenSSL::Digest.new('SHA1')
|
970
906
|
*
|
971
907
|
* A CSR is saved to disk and sent to the CA for signing.
|
972
908
|
*
|
@@ -1010,7 +946,7 @@ static void Init_ossl_locks(void)
|
|
1010
946
|
* csr_cert.add_extension \
|
1011
947
|
* extension_factory.create_extension('subjectKeyIdentifier', 'hash')
|
1012
948
|
*
|
1013
|
-
* csr_cert.sign ca_key, OpenSSL::Digest
|
949
|
+
* csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
|
1014
950
|
*
|
1015
951
|
* open 'csr_cert.pem', 'w' do |io|
|
1016
952
|
* io.write csr_cert.to_pem
|
@@ -1042,13 +978,13 @@ static void Init_ossl_locks(void)
|
|
1042
978
|
* loop do
|
1043
979
|
* ssl_connection = ssl_server.accept
|
1044
980
|
*
|
1045
|
-
* data =
|
981
|
+
* data = ssl_connection.gets
|
1046
982
|
*
|
1047
983
|
* response = "I got #{data.dump}"
|
1048
984
|
* puts response
|
1049
985
|
*
|
1050
|
-
*
|
1051
|
-
*
|
986
|
+
* ssl_connection.puts "I got #{data.dump}"
|
987
|
+
* ssl_connection.close
|
1052
988
|
* end
|
1053
989
|
*
|
1054
990
|
* === SSL client
|
@@ -1099,6 +1035,11 @@ static void Init_ossl_locks(void)
|
|
1099
1035
|
void
|
1100
1036
|
Init_openssl(void)
|
1101
1037
|
{
|
1038
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
1039
|
+
rb_ext_ractor_safe(true);
|
1040
|
+
#endif
|
1041
|
+
|
1042
|
+
#undef rb_intern
|
1102
1043
|
/*
|
1103
1044
|
* Init timezone info
|
1104
1045
|
*/
|
@@ -1122,13 +1063,9 @@ Init_openssl(void)
|
|
1122
1063
|
/*
|
1123
1064
|
* Init main module
|
1124
1065
|
*/
|
1125
|
-
mOSSL = rb_define_module("OpenSSL");
|
1126
1066
|
rb_global_variable(&mOSSL);
|
1127
|
-
|
1128
|
-
|
1129
|
-
* OpenSSL ruby extension version
|
1130
|
-
*/
|
1131
|
-
rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
|
1067
|
+
mOSSL = rb_define_module("OpenSSL");
|
1068
|
+
rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
|
1132
1069
|
|
1133
1070
|
/*
|
1134
1071
|
* Version of OpenSSL the ruby OpenSSL extension was built with
|
@@ -1146,15 +1083,35 @@ Init_openssl(void)
|
|
1146
1083
|
|
1147
1084
|
/*
|
1148
1085
|
* Version number of OpenSSL the ruby OpenSSL extension was built with
|
1149
|
-
* (base 16)
|
1086
|
+
* (base 16). The formats are below.
|
1087
|
+
*
|
1088
|
+
* [OpenSSL 3] <tt>0xMNN00PP0 (major minor 00 patch 0)</tt>
|
1089
|
+
* [OpenSSL before 3] <tt>0xMNNFFPPS (major minor fix patch status)</tt>
|
1090
|
+
* [LibreSSL] <tt>0x20000000 (fixed value)</tt>
|
1091
|
+
*
|
1092
|
+
* See also the man page OPENSSL_VERSION_NUMBER(3).
|
1150
1093
|
*/
|
1151
1094
|
rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
|
1152
1095
|
|
1096
|
+
#if defined(LIBRESSL_VERSION_NUMBER)
|
1097
|
+
/*
|
1098
|
+
* Version number of LibreSSL the ruby OpenSSL extension was built with
|
1099
|
+
* (base 16). The format is <tt>0xMNNFF00f (major minor fix 00
|
1100
|
+
* status)</tt>. This constant is only defined in LibreSSL cases.
|
1101
|
+
*
|
1102
|
+
* See also the man page LIBRESSL_VERSION_NUMBER(3).
|
1103
|
+
*/
|
1104
|
+
rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER));
|
1105
|
+
#endif
|
1106
|
+
|
1153
1107
|
/*
|
1154
1108
|
* Boolean indicating whether OpenSSL is FIPS-capable or not
|
1155
1109
|
*/
|
1156
1110
|
rb_define_const(mOSSL, "OPENSSL_FIPS",
|
1157
|
-
|
1111
|
+
/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */
|
1112
|
+
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
|
1113
|
+
Qtrue
|
1114
|
+
#elif defined(OPENSSL_FIPS)
|
1158
1115
|
Qtrue
|
1159
1116
|
#else
|
1160
1117
|
Qfalse
|
@@ -1164,12 +1121,12 @@ Init_openssl(void)
|
|
1164
1121
|
rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0);
|
1165
1122
|
rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
|
1166
1123
|
|
1124
|
+
rb_global_variable(&eOSSLError);
|
1167
1125
|
/*
|
1168
1126
|
* Generic error,
|
1169
1127
|
* common for all classes under OpenSSL module
|
1170
1128
|
*/
|
1171
1129
|
eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
|
1172
|
-
rb_global_variable(&eOSSLError);
|
1173
1130
|
|
1174
1131
|
/*
|
1175
1132
|
* Init debug core
|
@@ -1204,45 +1161,13 @@ Init_openssl(void)
|
|
1204
1161
|
Init_ossl_pkey();
|
1205
1162
|
Init_ossl_rand();
|
1206
1163
|
Init_ossl_ssl();
|
1164
|
+
#ifndef OPENSSL_NO_TS
|
1165
|
+
Init_ossl_ts();
|
1166
|
+
#endif
|
1207
1167
|
Init_ossl_x509();
|
1208
1168
|
Init_ossl_ocsp();
|
1209
1169
|
Init_ossl_engine();
|
1170
|
+
Init_ossl_provider();
|
1210
1171
|
Init_ossl_asn1();
|
1211
1172
|
Init_ossl_kdf();
|
1212
|
-
|
1213
|
-
#if defined(OSSL_DEBUG)
|
1214
|
-
/*
|
1215
|
-
* For debugging Ruby/OpenSSL. Enable only when built with --enable-debug
|
1216
|
-
*/
|
1217
|
-
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
1218
|
-
(OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \
|
1219
|
-
defined(CRYPTO_malloc_debug_init))
|
1220
|
-
rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0);
|
1221
|
-
rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0);
|
1222
|
-
|
1223
|
-
#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */
|
1224
|
-
CRYPTO_malloc_debug_init();
|
1225
|
-
#endif
|
1226
|
-
|
1227
|
-
#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */
|
1228
|
-
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
|
1229
|
-
#endif
|
1230
|
-
|
1231
|
-
#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */
|
1232
|
-
{
|
1233
|
-
int i;
|
1234
|
-
/*
|
1235
|
-
* See crypto/ex_data.c; call def_get_class() immediately to avoid
|
1236
|
-
* allocations. 15 is the maximum number that is used as the class index
|
1237
|
-
* in OpenSSL 1.0.2.
|
1238
|
-
*/
|
1239
|
-
for (i = 0; i <= 15; i++) {
|
1240
|
-
if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0)
|
1241
|
-
rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for "
|
1242
|
-
"class index %d failed", i);
|
1243
|
-
}
|
1244
|
-
}
|
1245
|
-
#endif
|
1246
|
-
#endif
|
1247
|
-
#endif
|
1248
1173
|
}
|