openssl 2.1.1 → 2.2.1
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 +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
|
|