openssl 2.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|