openssl 2.1.1 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +9 -7
- data/History.md +165 -0
- data/README.md +2 -2
- data/ext/openssl/extconf.rb +51 -27
- data/ext/openssl/openssl_missing.h +39 -4
- data/ext/openssl/ossl.c +61 -27
- data/ext/openssl/ossl.h +8 -5
- data/ext/openssl/ossl_asn1.c +27 -1
- data/ext/openssl/ossl_bn.c +92 -24
- data/ext/openssl/ossl_bn.h +2 -1
- data/ext/openssl/ossl_cipher.c +33 -24
- data/ext/openssl/ossl_digest.c +22 -53
- data/ext/openssl/ossl_engine.c +2 -12
- data/ext/openssl/ossl_hmac.c +5 -11
- data/ext/openssl/ossl_kdf.c +3 -19
- data/ext/openssl/ossl_ns_spki.c +1 -1
- data/ext/openssl/ossl_ocsp.c +6 -11
- data/ext/openssl/ossl_ocsp.h +3 -3
- data/ext/openssl/ossl_pkcs12.c +1 -0
- data/ext/openssl/ossl_pkcs7.c +4 -19
- data/ext/openssl/ossl_pkcs7.h +16 -0
- data/ext/openssl/ossl_pkey.c +206 -17
- data/ext/openssl/ossl_pkey.h +6 -6
- data/ext/openssl/ossl_pkey_dh.c +1 -1
- data/ext/openssl/ossl_pkey_dsa.c +2 -2
- data/ext/openssl/ossl_pkey_ec.c +38 -8
- data/ext/openssl/ossl_pkey_rsa.c +17 -9
- data/ext/openssl/ossl_rand.c +2 -40
- data/ext/openssl/ossl_ssl.c +205 -75
- data/ext/openssl/ossl_ts.c +1524 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +91 -0
- data/ext/openssl/ossl_x509cert.c +2 -2
- data/ext/openssl/ossl_x509ext.c +15 -0
- data/ext/openssl/ossl_x509name.c +15 -10
- data/ext/openssl/ossl_x509store.c +40 -22
- data/lib/openssl/bn.rb +1 -1
- data/lib/openssl/buffering.rb +33 -17
- data/lib/openssl/cipher.rb +1 -1
- data/lib/openssl/config.rb +53 -26
- data/lib/openssl/digest.rb +10 -12
- data/lib/openssl/hmac.rb +13 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +1 -1
- data/lib/openssl/pkey.rb +18 -1
- data/lib/openssl/ssl.rb +46 -7
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +155 -1
- data/lib/openssl.rb +25 -9
- metadata +25 -9
- data/ext/openssl/deprecation.rb +0 -23
- data/ext/openssl/ossl_version.h +0 -15
data/ext/openssl/ossl.c
CHANGED
@@ -338,7 +338,7 @@ ossl_clear_error(void)
|
|
338
338
|
* implementation.
|
339
339
|
*/
|
340
340
|
VALUE
|
341
|
-
ossl_get_errors(
|
341
|
+
ossl_get_errors(VALUE _)
|
342
342
|
{
|
343
343
|
VALUE ary;
|
344
344
|
long e;
|
@@ -398,7 +398,7 @@ ossl_debug_set(VALUE self, VALUE val)
|
|
398
398
|
}
|
399
399
|
|
400
400
|
/*
|
401
|
-
* call-seq
|
401
|
+
* call-seq:
|
402
402
|
* OpenSSL.fips_mode -> true | false
|
403
403
|
*/
|
404
404
|
static VALUE
|
@@ -497,8 +497,11 @@ print_mem_leaks(VALUE self)
|
|
497
497
|
int ret;
|
498
498
|
#endif
|
499
499
|
|
500
|
-
|
501
|
-
|
500
|
+
#ifndef HAVE_RB_EXT_RACTOR_SAFE
|
501
|
+
// for Ruby 2.x
|
502
|
+
void ossl_bn_ctx_free(void); // ossl_bn.c
|
503
|
+
ossl_bn_ctx_free();
|
504
|
+
#endif
|
502
505
|
|
503
506
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000
|
504
507
|
ret = CRYPTO_mem_leaks_fp(stderr);
|
@@ -604,6 +607,35 @@ static void Init_ossl_locks(void)
|
|
604
607
|
}
|
605
608
|
#endif /* !HAVE_OPENSSL_110_THREADING_API */
|
606
609
|
|
610
|
+
/*
|
611
|
+
* call-seq:
|
612
|
+
* OpenSSL.fixed_length_secure_compare(string, string) -> boolean
|
613
|
+
*
|
614
|
+
* Constant time memory comparison for fixed length strings, such as results
|
615
|
+
* of HMAC calculations.
|
616
|
+
*
|
617
|
+
* Returns +true+ if the strings are identical, +false+ if they are of the same
|
618
|
+
* length but not identical. If the length is different, +ArgumentError+ is
|
619
|
+
* raised.
|
620
|
+
*/
|
621
|
+
static VALUE
|
622
|
+
ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
|
623
|
+
{
|
624
|
+
const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
|
625
|
+
const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
|
626
|
+
long len1 = RSTRING_LEN(str1);
|
627
|
+
long len2 = RSTRING_LEN(str2);
|
628
|
+
|
629
|
+
if (len1 != len2) {
|
630
|
+
ossl_raise(rb_eArgError, "inputs must be of equal length");
|
631
|
+
}
|
632
|
+
|
633
|
+
switch (CRYPTO_memcmp(p1, p2, len1)) {
|
634
|
+
case 0: return Qtrue;
|
635
|
+
default: return Qfalse;
|
636
|
+
}
|
637
|
+
}
|
638
|
+
|
607
639
|
/*
|
608
640
|
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
|
609
641
|
* OpenSSL[https://www.openssl.org/] library.
|
@@ -635,7 +667,7 @@ static void Init_ossl_locks(void)
|
|
635
667
|
* ahold of the key may use it unless it is encrypted. In order to securely
|
636
668
|
* export a key you may export it with a pass phrase.
|
637
669
|
*
|
638
|
-
* cipher = OpenSSL::Cipher.new 'AES-
|
670
|
+
* cipher = OpenSSL::Cipher.new 'AES-256-CBC'
|
639
671
|
* pass_phrase = 'my secure pass phrase goes here'
|
640
672
|
*
|
641
673
|
* key_secure = key.export cipher, pass_phrase
|
@@ -710,16 +742,14 @@ static void Init_ossl_locks(void)
|
|
710
742
|
* To sign a document, a cryptographically secure hash of the document is
|
711
743
|
* computed first, which is then signed using the private key.
|
712
744
|
*
|
713
|
-
*
|
714
|
-
* signature = key.sign digest, document
|
745
|
+
* signature = key.sign 'SHA256', document
|
715
746
|
*
|
716
747
|
* To validate the signature, again a hash of the document is computed and
|
717
748
|
* the signature is decrypted using the public key. The result is then
|
718
749
|
* compared to the hash just computed, if they are equal the signature was
|
719
750
|
* valid.
|
720
751
|
*
|
721
|
-
*
|
722
|
-
* if key.verify digest, signature, document
|
752
|
+
* if key.verify 'SHA256', signature, document
|
723
753
|
* puts 'Valid'
|
724
754
|
* else
|
725
755
|
* puts 'Invalid'
|
@@ -745,7 +775,7 @@ static void Init_ossl_locks(void)
|
|
745
775
|
* using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
|
746
776
|
* the number of iterations largely depends on the hardware being used.
|
747
777
|
*
|
748
|
-
* cipher = OpenSSL::Cipher.new 'AES-
|
778
|
+
* cipher = OpenSSL::Cipher.new 'AES-256-CBC'
|
749
779
|
* cipher.encrypt
|
750
780
|
* iv = cipher.random_iv
|
751
781
|
*
|
@@ -753,7 +783,7 @@ static void Init_ossl_locks(void)
|
|
753
783
|
* salt = OpenSSL::Random.random_bytes 16
|
754
784
|
* iter = 20000
|
755
785
|
* key_len = cipher.key_len
|
756
|
-
* digest = OpenSSL::Digest
|
786
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
757
787
|
*
|
758
788
|
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
|
759
789
|
* cipher.key = key
|
@@ -768,7 +798,7 @@ static void Init_ossl_locks(void)
|
|
768
798
|
* Use the same steps as before to derive the symmetric AES key, this time
|
769
799
|
* setting the Cipher up for decryption.
|
770
800
|
*
|
771
|
-
* cipher = OpenSSL::Cipher.new 'AES-
|
801
|
+
* cipher = OpenSSL::Cipher.new 'AES-256-CBC'
|
772
802
|
* cipher.decrypt
|
773
803
|
* cipher.iv = iv # the one generated with #random_iv
|
774
804
|
*
|
@@ -776,7 +806,7 @@ static void Init_ossl_locks(void)
|
|
776
806
|
* salt = ... # the one generated above
|
777
807
|
* iter = 20000
|
778
808
|
* key_len = cipher.key_len
|
779
|
-
* digest = OpenSSL::Digest
|
809
|
+
* digest = OpenSSL::Digest.new('SHA256')
|
780
810
|
*
|
781
811
|
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
|
782
812
|
* cipher.key = key
|
@@ -803,7 +833,7 @@ static void Init_ossl_locks(void)
|
|
803
833
|
*
|
804
834
|
* First set up the cipher for encryption
|
805
835
|
*
|
806
|
-
* encryptor = OpenSSL::Cipher.new 'AES-
|
836
|
+
* encryptor = OpenSSL::Cipher.new 'AES-256-CBC'
|
807
837
|
* encryptor.encrypt
|
808
838
|
* encryptor.pkcs5_keyivgen pass_phrase, salt
|
809
839
|
*
|
@@ -816,7 +846,7 @@ static void Init_ossl_locks(void)
|
|
816
846
|
*
|
817
847
|
* Use a new Cipher instance set up for decryption
|
818
848
|
*
|
819
|
-
* decryptor = OpenSSL::Cipher.new 'AES-
|
849
|
+
* decryptor = OpenSSL::Cipher.new 'AES-256-CBC'
|
820
850
|
* decryptor.decrypt
|
821
851
|
* decryptor.pkcs5_keyivgen pass_phrase, salt
|
822
852
|
*
|
@@ -833,7 +863,7 @@ static void Init_ossl_locks(void)
|
|
833
863
|
* signature.
|
834
864
|
*
|
835
865
|
* key = OpenSSL::PKey::RSA.new 2048
|
836
|
-
* name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
|
866
|
+
* name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example'
|
837
867
|
*
|
838
868
|
* cert = OpenSSL::X509::Certificate.new
|
839
869
|
* cert.version = 2
|
@@ -872,7 +902,7 @@ static void Init_ossl_locks(void)
|
|
872
902
|
* certificate.
|
873
903
|
*
|
874
904
|
* cert.issuer = name
|
875
|
-
* cert.sign key, OpenSSL::Digest
|
905
|
+
* cert.sign key, OpenSSL::Digest.new('SHA1')
|
876
906
|
*
|
877
907
|
* open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
|
878
908
|
*
|
@@ -904,7 +934,7 @@ static void Init_ossl_locks(void)
|
|
904
934
|
* ca_key = OpenSSL::PKey::RSA.new 2048
|
905
935
|
* pass_phrase = 'my secure pass phrase goes here'
|
906
936
|
*
|
907
|
-
* cipher = OpenSSL::Cipher.new 'AES-
|
937
|
+
* cipher = OpenSSL::Cipher.new 'AES-256-CBC'
|
908
938
|
*
|
909
939
|
* open 'ca_key.pem', 'w', 0400 do |io|
|
910
940
|
* io.write ca_key.export(cipher, pass_phrase)
|
@@ -915,7 +945,7 @@ static void Init_ossl_locks(void)
|
|
915
945
|
* A CA certificate is created the same way we created a certificate above, but
|
916
946
|
* with different extensions.
|
917
947
|
*
|
918
|
-
* ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
|
948
|
+
* ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example'
|
919
949
|
*
|
920
950
|
* ca_cert = OpenSSL::X509::Certificate.new
|
921
951
|
* ca_cert.serial = 0
|
@@ -948,7 +978,7 @@ static void Init_ossl_locks(void)
|
|
948
978
|
*
|
949
979
|
* Root CA certificates are self-signed.
|
950
980
|
*
|
951
|
-
* ca_cert.sign ca_key, OpenSSL::Digest
|
981
|
+
* ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
|
952
982
|
*
|
953
983
|
* The CA certificate is saved to disk so it may be distributed to all the
|
954
984
|
* users of the keys this CA will sign.
|
@@ -966,7 +996,7 @@ static void Init_ossl_locks(void)
|
|
966
996
|
* csr.version = 0
|
967
997
|
* csr.subject = name
|
968
998
|
* csr.public_key = key.public_key
|
969
|
-
* csr.sign key, OpenSSL::Digest
|
999
|
+
* csr.sign key, OpenSSL::Digest.new('SHA1')
|
970
1000
|
*
|
971
1001
|
* A CSR is saved to disk and sent to the CA for signing.
|
972
1002
|
*
|
@@ -1010,7 +1040,7 @@ static void Init_ossl_locks(void)
|
|
1010
1040
|
* csr_cert.add_extension \
|
1011
1041
|
* extension_factory.create_extension('subjectKeyIdentifier', 'hash')
|
1012
1042
|
*
|
1013
|
-
* csr_cert.sign ca_key, OpenSSL::Digest
|
1043
|
+
* csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
|
1014
1044
|
*
|
1015
1045
|
* open 'csr_cert.pem', 'w' do |io|
|
1016
1046
|
* io.write csr_cert.to_pem
|
@@ -1099,6 +1129,11 @@ static void Init_ossl_locks(void)
|
|
1099
1129
|
void
|
1100
1130
|
Init_openssl(void)
|
1101
1131
|
{
|
1132
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
1133
|
+
rb_ext_ractor_safe(true);
|
1134
|
+
#endif
|
1135
|
+
|
1136
|
+
#undef rb_intern
|
1102
1137
|
/*
|
1103
1138
|
* Init timezone info
|
1104
1139
|
*/
|
@@ -1124,11 +1159,7 @@ Init_openssl(void)
|
|
1124
1159
|
*/
|
1125
1160
|
mOSSL = rb_define_module("OpenSSL");
|
1126
1161
|
rb_global_variable(&mOSSL);
|
1127
|
-
|
1128
|
-
/*
|
1129
|
-
* OpenSSL ruby extension version
|
1130
|
-
*/
|
1131
|
-
rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
|
1162
|
+
rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
|
1132
1163
|
|
1133
1164
|
/*
|
1134
1165
|
* Version of OpenSSL the ruby OpenSSL extension was built with
|
@@ -1204,6 +1235,9 @@ Init_openssl(void)
|
|
1204
1235
|
Init_ossl_pkey();
|
1205
1236
|
Init_ossl_rand();
|
1206
1237
|
Init_ossl_ssl();
|
1238
|
+
#ifndef OPENSSL_NO_TS
|
1239
|
+
Init_ossl_ts();
|
1240
|
+
#endif
|
1207
1241
|
Init_ossl_x509();
|
1208
1242
|
Init_ossl_ocsp();
|
1209
1243
|
Init_ossl_engine();
|
data/ext/openssl/ossl.h
CHANGED
@@ -13,8 +13,8 @@
|
|
13
13
|
#include RUBY_EXTCONF_H
|
14
14
|
|
15
15
|
#include <assert.h>
|
16
|
-
#include <errno.h>
|
17
16
|
#include <ruby.h>
|
17
|
+
#include <errno.h>
|
18
18
|
#include <ruby/io.h>
|
19
19
|
#include <ruby/thread.h>
|
20
20
|
#include <openssl/opensslv.h>
|
@@ -27,7 +27,9 @@
|
|
27
27
|
#include <openssl/hmac.h>
|
28
28
|
#include <openssl/rand.h>
|
29
29
|
#include <openssl/conf.h>
|
30
|
-
#
|
30
|
+
#ifndef OPENSSL_NO_TS
|
31
|
+
#include <openssl/ts.h>
|
32
|
+
#endif
|
31
33
|
#include <openssl/crypto.h>
|
32
34
|
#if !defined(OPENSSL_NO_ENGINE)
|
33
35
|
# include <openssl/engine.h>
|
@@ -86,9 +88,8 @@ VALUE ossl_buf2str(char *buf, int len);
|
|
86
88
|
VALUE ossl_str_new(const char *, long, int *);
|
87
89
|
#define ossl_str_adjust(str, p) \
|
88
90
|
do{\
|
89
|
-
long len = RSTRING_LEN(str);\
|
90
91
|
long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\
|
91
|
-
assert(newlen <=
|
92
|
+
assert(newlen <= RSTRING_LEN(str));\
|
92
93
|
rb_str_set_len((str), newlen);\
|
93
94
|
}while(0)
|
94
95
|
/*
|
@@ -168,7 +169,9 @@ void ossl_debug(const char *, ...);
|
|
168
169
|
#include "ossl_pkey.h"
|
169
170
|
#include "ossl_rand.h"
|
170
171
|
#include "ossl_ssl.h"
|
171
|
-
#
|
172
|
+
#ifndef OPENSSL_NO_TS
|
173
|
+
#include "ossl_ts.h"
|
174
|
+
#endif
|
172
175
|
#include "ossl_x509.h"
|
173
176
|
#include "ossl_engine.h"
|
174
177
|
#include "ossl_kdf.h"
|
data/ext/openssl/ossl_asn1.c
CHANGED
@@ -1285,6 +1285,30 @@ ossl_asn1obj_get_ln(VALUE self)
|
|
1285
1285
|
return ret;
|
1286
1286
|
}
|
1287
1287
|
|
1288
|
+
/*
|
1289
|
+
* call-seq:
|
1290
|
+
* oid == other_oid => true or false
|
1291
|
+
*
|
1292
|
+
* Returns +true+ if _other_oid_ is the same as _oid_
|
1293
|
+
*/
|
1294
|
+
static VALUE
|
1295
|
+
ossl_asn1obj_eq(VALUE self, VALUE other)
|
1296
|
+
{
|
1297
|
+
VALUE valSelf, valOther;
|
1298
|
+
int nidSelf, nidOther;
|
1299
|
+
|
1300
|
+
valSelf = ossl_asn1_get_value(self);
|
1301
|
+
valOther = ossl_asn1_get_value(other);
|
1302
|
+
|
1303
|
+
if ((nidSelf = OBJ_txt2nid(StringValueCStr(valSelf))) == NID_undef)
|
1304
|
+
ossl_raise(eASN1Error, "OBJ_txt2nid");
|
1305
|
+
|
1306
|
+
if ((nidOther = OBJ_txt2nid(StringValueCStr(valOther))) == NID_undef)
|
1307
|
+
ossl_raise(eASN1Error, "OBJ_txt2nid");
|
1308
|
+
|
1309
|
+
return nidSelf == nidOther ? Qtrue : Qfalse;
|
1310
|
+
}
|
1311
|
+
|
1288
1312
|
static VALUE
|
1289
1313
|
asn1obj_get_oid_i(VALUE vobj)
|
1290
1314
|
{
|
@@ -1360,6 +1384,7 @@ OSSL_ASN1_IMPL_FACTORY_METHOD(EndOfContent)
|
|
1360
1384
|
void
|
1361
1385
|
Init_ossl_asn1(void)
|
1362
1386
|
{
|
1387
|
+
#undef rb_intern
|
1363
1388
|
VALUE ary;
|
1364
1389
|
int i;
|
1365
1390
|
|
@@ -1817,12 +1842,14 @@ do{\
|
|
1817
1842
|
rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0);
|
1818
1843
|
rb_define_alias(cASN1ObjectId, "short_name", "sn");
|
1819
1844
|
rb_define_alias(cASN1ObjectId, "long_name", "ln");
|
1845
|
+
rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1);
|
1820
1846
|
rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0);
|
1821
1847
|
|
1822
1848
|
rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0);
|
1823
1849
|
rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0);
|
1824
1850
|
|
1825
1851
|
class_tag_map = rb_hash_new();
|
1852
|
+
rb_gc_register_mark_object(class_tag_map);
|
1826
1853
|
rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC));
|
1827
1854
|
rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN));
|
1828
1855
|
rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER));
|
@@ -1846,7 +1873,6 @@ do{\
|
|
1846
1873
|
rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
|
1847
1874
|
rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
|
1848
1875
|
rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
|
1849
|
-
rb_global_variable(&class_tag_map);
|
1850
1876
|
|
1851
1877
|
id_each = rb_intern_const("each");
|
1852
1878
|
}
|
data/ext/openssl/ossl_bn.c
CHANGED
@@ -10,6 +10,10 @@
|
|
10
10
|
/* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
|
11
11
|
#include "ossl.h"
|
12
12
|
|
13
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
14
|
+
#include <ruby/ractor.h>
|
15
|
+
#endif
|
16
|
+
|
13
17
|
#define NewBN(klass) \
|
14
18
|
TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
|
15
19
|
#define SetBN(obj, bn) do { \
|
@@ -150,12 +154,58 @@ ossl_bn_value_ptr(volatile VALUE *ptr)
|
|
150
154
|
/*
|
151
155
|
* Private
|
152
156
|
*/
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
*
|
157
|
-
|
158
|
-
BN_CTX *
|
157
|
+
|
158
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
159
|
+
void
|
160
|
+
ossl_bn_ctx_free(void *ptr)
|
161
|
+
{
|
162
|
+
BN_CTX *ctx = (BN_CTX *)ptr;
|
163
|
+
BN_CTX_free(ctx);
|
164
|
+
}
|
165
|
+
|
166
|
+
struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
|
167
|
+
NULL, // mark
|
168
|
+
ossl_bn_ctx_free,
|
169
|
+
};
|
170
|
+
|
171
|
+
rb_ractor_local_key_t ossl_bn_ctx_key;
|
172
|
+
|
173
|
+
BN_CTX *
|
174
|
+
ossl_bn_ctx_get(void)
|
175
|
+
{
|
176
|
+
// stored in ractor local storage
|
177
|
+
|
178
|
+
BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
|
179
|
+
if (!ctx) {
|
180
|
+
if (!(ctx = BN_CTX_new())) {
|
181
|
+
ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
|
182
|
+
}
|
183
|
+
rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
|
184
|
+
}
|
185
|
+
return ctx;
|
186
|
+
}
|
187
|
+
#else
|
188
|
+
// for ruby 2.x
|
189
|
+
static BN_CTX *gv_ossl_bn_ctx;
|
190
|
+
|
191
|
+
BN_CTX *
|
192
|
+
ossl_bn_ctx_get(void)
|
193
|
+
{
|
194
|
+
if (gv_ossl_bn_ctx == NULL) {
|
195
|
+
if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
|
196
|
+
ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
|
197
|
+
}
|
198
|
+
}
|
199
|
+
return gv_ossl_bn_ctx;
|
200
|
+
}
|
201
|
+
|
202
|
+
void
|
203
|
+
ossl_bn_ctx_free(void)
|
204
|
+
{
|
205
|
+
BN_CTX_free(gv_ossl_bn_ctx);
|
206
|
+
gv_ossl_bn_ctx = NULL;
|
207
|
+
}
|
208
|
+
#endif
|
159
209
|
|
160
210
|
static VALUE
|
161
211
|
ossl_bn_alloc(VALUE klass)
|
@@ -173,7 +223,6 @@ ossl_bn_alloc(VALUE klass)
|
|
173
223
|
|
174
224
|
/*
|
175
225
|
* call-seq:
|
176
|
-
* OpenSSL::BN.new => aBN
|
177
226
|
* OpenSSL::BN.new(bn) => aBN
|
178
227
|
* OpenSSL::BN.new(integer) => aBN
|
179
228
|
* OpenSSL::BN.new(string) => aBN
|
@@ -187,11 +236,16 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
|
|
187
236
|
BIGNUM *bn;
|
188
237
|
VALUE str, bs;
|
189
238
|
int base = 10;
|
239
|
+
char *ptr;
|
190
240
|
|
191
241
|
if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
|
192
242
|
base = NUM2INT(bs);
|
193
243
|
}
|
194
244
|
|
245
|
+
if (NIL_P(str)) {
|
246
|
+
ossl_raise(rb_eArgError, "invalid argument");
|
247
|
+
}
|
248
|
+
|
195
249
|
if (RB_INTEGER_TYPE_P(str)) {
|
196
250
|
GetBN(self, bn);
|
197
251
|
integer_to_bnptr(str, bn);
|
@@ -213,12 +267,14 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
|
|
213
267
|
GetBN(self, bn);
|
214
268
|
switch (base) {
|
215
269
|
case 0:
|
216
|
-
|
270
|
+
ptr = StringValuePtr(str);
|
271
|
+
if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
|
217
272
|
ossl_raise(eBNError, NULL);
|
218
273
|
}
|
219
274
|
break;
|
220
275
|
case 2:
|
221
|
-
|
276
|
+
ptr = StringValuePtr(str);
|
277
|
+
if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
|
222
278
|
ossl_raise(eBNError, NULL);
|
223
279
|
}
|
224
280
|
break;
|
@@ -397,7 +453,7 @@ ossl_bn_is_negative(VALUE self)
|
|
397
453
|
if (!(result = BN_new())) { \
|
398
454
|
ossl_raise(eBNError, NULL); \
|
399
455
|
} \
|
400
|
-
if (
|
456
|
+
if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
|
401
457
|
BN_free(result); \
|
402
458
|
ossl_raise(eBNError, NULL); \
|
403
459
|
} \
|
@@ -423,7 +479,7 @@ BIGNUM_1c(sqr)
|
|
423
479
|
if (!(result = BN_new())) { \
|
424
480
|
ossl_raise(eBNError, NULL); \
|
425
481
|
} \
|
426
|
-
if (
|
482
|
+
if (BN_##func(result, bn1, bn2) <= 0) { \
|
427
483
|
BN_free(result); \
|
428
484
|
ossl_raise(eBNError, NULL); \
|
429
485
|
} \
|
@@ -456,7 +512,7 @@ BIGNUM_2(sub)
|
|
456
512
|
if (!(result = BN_new())) { \
|
457
513
|
ossl_raise(eBNError, NULL); \
|
458
514
|
} \
|
459
|
-
if (
|
515
|
+
if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
|
460
516
|
BN_free(result); \
|
461
517
|
ossl_raise(eBNError, NULL); \
|
462
518
|
} \
|
@@ -500,11 +556,21 @@ BIGNUM_2c(gcd)
|
|
500
556
|
BIGNUM_2c(mod_sqr)
|
501
557
|
|
502
558
|
/*
|
503
|
-
* Document-method: OpenSSL::BN#mod_inverse
|
504
559
|
* call-seq:
|
505
|
-
*
|
560
|
+
* bn.mod_inverse(bn2) => aBN
|
506
561
|
*/
|
507
|
-
|
562
|
+
static VALUE
|
563
|
+
ossl_bn_mod_inverse(VALUE self, VALUE other)
|
564
|
+
{
|
565
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
|
566
|
+
VALUE obj;
|
567
|
+
GetBN(self, bn1);
|
568
|
+
obj = NewBN(rb_obj_class(self));
|
569
|
+
if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
|
570
|
+
ossl_raise(eBNError, "BN_mod_inverse");
|
571
|
+
SetBN(obj, result);
|
572
|
+
return obj;
|
573
|
+
}
|
508
574
|
|
509
575
|
/*
|
510
576
|
* call-seq:
|
@@ -553,7 +619,7 @@ ossl_bn_div(VALUE self, VALUE other)
|
|
553
619
|
if (!(result = BN_new())) { \
|
554
620
|
ossl_raise(eBNError, NULL); \
|
555
621
|
} \
|
556
|
-
if (
|
622
|
+
if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
|
557
623
|
BN_free(result); \
|
558
624
|
ossl_raise(eBNError, NULL); \
|
559
625
|
} \
|
@@ -595,7 +661,7 @@ BIGNUM_3c(mod_exp)
|
|
595
661
|
{ \
|
596
662
|
BIGNUM *bn; \
|
597
663
|
GetBN(self, bn); \
|
598
|
-
if (
|
664
|
+
if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
|
599
665
|
ossl_raise(eBNError, NULL); \
|
600
666
|
} \
|
601
667
|
return self; \
|
@@ -655,7 +721,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
|
|
655
721
|
if (!(result = BN_new())) { \
|
656
722
|
ossl_raise(eBNError, NULL); \
|
657
723
|
} \
|
658
|
-
if (
|
724
|
+
if (BN_##func(result, bn, b) <= 0) { \
|
659
725
|
BN_free(result); \
|
660
726
|
ossl_raise(eBNError, NULL); \
|
661
727
|
} \
|
@@ -685,7 +751,7 @@ BIGNUM_SHIFT(rshift)
|
|
685
751
|
int b; \
|
686
752
|
b = NUM2INT(bits); \
|
687
753
|
GetBN(self, bn); \
|
688
|
-
if (
|
754
|
+
if (BN_##func(bn, bn, b) <= 0) \
|
689
755
|
ossl_raise(eBNError, NULL); \
|
690
756
|
return self; \
|
691
757
|
}
|
@@ -724,7 +790,7 @@ BIGNUM_SELF_SHIFT(rshift)
|
|
724
790
|
if (!(result = BN_new())) { \
|
725
791
|
ossl_raise(eBNError, NULL); \
|
726
792
|
} \
|
727
|
-
if (
|
793
|
+
if (BN_##func(result, b, top, bottom) <= 0) { \
|
728
794
|
BN_free(result); \
|
729
795
|
ossl_raise(eBNError, NULL); \
|
730
796
|
} \
|
@@ -753,7 +819,7 @@ BIGNUM_RAND(pseudo_rand)
|
|
753
819
|
if (!(result = BN_new())) { \
|
754
820
|
ossl_raise(eBNError, NULL); \
|
755
821
|
} \
|
756
|
-
if (
|
822
|
+
if (BN_##func##_range(result, bn) <= 0) { \
|
757
823
|
BN_free(result); \
|
758
824
|
ossl_raise(eBNError, NULL); \
|
759
825
|
} \
|
@@ -1086,9 +1152,11 @@ Init_ossl_bn(void)
|
|
1086
1152
|
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
1087
1153
|
#endif
|
1088
1154
|
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1155
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
1156
|
+
ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
|
1157
|
+
#else
|
1158
|
+
ossl_bn_ctx_get();
|
1159
|
+
#endif
|
1092
1160
|
|
1093
1161
|
eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
|
1094
1162
|
|