Skip to content

Commit 5880083

Browse files
authored
Merge pull request #985 from rhenium/ky/freeze-string-constants
Freeze more constants for Ractor compatibility
2 parents 2a6f41e + b0de8ba commit 5880083

File tree

7 files changed

+91
-54
lines changed

7 files changed

+91
-54
lines changed

ext/openssl/ossl.c

Lines changed: 70 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,14 @@ osslerror_detailed_message(int argc, VALUE *argv, VALUE self)
388388
* call-seq:
389389
* OpenSSL.errors -> [String...]
390390
*
391-
* See any remaining errors held in queue.
391+
* Returns any remaining errors held in the \OpenSSL thread-local error queue
392+
* and clears the queue. This should normally return an empty array.
392393
*
393-
* Any errors you see here are probably due to a bug in Ruby's OpenSSL
394-
* implementation.
394+
* This is intended for debugging Ruby/OpenSSL. If you see any errors here,
395+
* it likely indicates a bug in the extension. Please file an issue at
396+
* https://github.com/ruby/openssl.
397+
*
398+
* For debugging your program, OpenSSL.debug= may be useful.
395399
*/
396400
static VALUE
397401
ossl_get_errors(VALUE _)
@@ -415,6 +419,8 @@ VALUE dOSSL;
415419
/*
416420
* call-seq:
417421
* OpenSSL.debug -> true | false
422+
*
423+
* Returns whether Ruby/OpenSSL's debug mode is currently enabled.
418424
*/
419425
static VALUE
420426
ossl_debug_get(VALUE self)
@@ -424,9 +430,9 @@ ossl_debug_get(VALUE self)
424430

425431
/*
426432
* call-seq:
427-
* OpenSSL.debug = boolean -> boolean
433+
* OpenSSL.debug = boolean
428434
*
429-
* Turns on or off debug mode. With debug mode, all errors added to the OpenSSL
435+
* Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL
430436
* error queue will be printed to stderr.
431437
*/
432438
static VALUE
@@ -440,6 +446,8 @@ ossl_debug_set(VALUE self, VALUE val)
440446
/*
441447
* call-seq:
442448
* OpenSSL.fips_mode -> true | false
449+
*
450+
* Returns whether the FIPS mode is currently enabled.
443451
*/
444452
static VALUE
445453
ossl_fips_mode_get(VALUE self)
@@ -460,10 +468,10 @@ ossl_fips_mode_get(VALUE self)
460468

461469
/*
462470
* call-seq:
463-
* OpenSSL.fips_mode = boolean -> boolean
471+
* OpenSSL.fips_mode = boolean
464472
*
465473
* Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an
466-
* effect for FIPS-capable installations of the OpenSSL library. Trying to do
474+
* effect for FIPS-capable installations of the \OpenSSL library. Trying to do
467475
* so otherwise will result in an error.
468476
*
469477
* === Examples
@@ -503,13 +511,13 @@ ossl_fips_mode_set(VALUE self, VALUE enabled)
503511

504512
/*
505513
* call-seq:
506-
* OpenSSL.fixed_length_secure_compare(string, string) -> boolean
514+
* OpenSSL.fixed_length_secure_compare(string, string) -> true or false
507515
*
508516
* Constant time memory comparison for fixed length strings, such as results
509-
* of HMAC calculations.
517+
* of \HMAC calculations.
510518
*
511519
* Returns +true+ if the strings are identical, +false+ if they are of the same
512-
* length but not identical. If the length is different, +ArgumentError+ is
520+
* length but not identical. If the length is different, ArgumentError is
513521
* raised.
514522
*/
515523
static VALUE
@@ -531,7 +539,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
531539
}
532540

533541
/*
534-
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
542+
* OpenSSL provides \SSL, TLS and general purpose cryptography. It wraps the
535543
* OpenSSL[https://www.openssl.org/] library.
536544
*
537545
* = Examples
@@ -586,7 +594,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
586594
*
587595
* === Loading an Encrypted Key
588596
*
589-
* OpenSSL will prompt you for your password when loading an encrypted key.
597+
* \OpenSSL will prompt you for your password when loading an encrypted key.
590598
* If you will not be able to type in the password you may provide it when
591599
* loading the key:
592600
*
@@ -649,7 +657,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
649657
*
650658
* == PBKDF2 Password-based Encryption
651659
*
652-
* If supported by the underlying OpenSSL version used, Password-based
660+
* If supported by the underlying \OpenSSL version used, Password-based
653661
* Encryption should use the features of PKCS5. If not supported or if
654662
* required by legacy applications, the older, less secure methods specified
655663
* in RFC 2898 are also supported (see below).
@@ -708,7 +716,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
708716
* decrypted = cipher.update encrypted
709717
* decrypted << cipher.final
710718
*
711-
* == X509 Certificates
719+
* == \X509 Certificates
712720
*
713721
* === Creating a Certificate
714722
*
@@ -745,7 +753,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
745753
* extension_factory.create_extension('subjectKeyIdentifier', 'hash')
746754
*
747755
* The list of supported extensions (and in some cases their possible values)
748-
* can be derived from the "objects.h" file in the OpenSSL source code.
756+
* can be derived from the "objects.h" file in the \OpenSSL source code.
749757
*
750758
* === Signing a Certificate
751759
*
@@ -899,23 +907,23 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
899907
* io.write csr_cert.to_pem
900908
* end
901909
*
902-
* == SSL and TLS Connections
910+
* == \SSL and TLS Connections
903911
*
904-
* Using our created key and certificate we can create an SSL or TLS connection.
905-
* An SSLContext is used to set up an SSL session.
912+
* Using our created key and certificate we can create an \SSL or TLS
913+
* connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session.
906914
*
907915
* context = OpenSSL::SSL::SSLContext.new
908916
*
909-
* === SSL Server
917+
* === \SSL Server
910918
*
911-
* An SSL server requires the certificate and private key to communicate
919+
* An \SSL server requires the certificate and private key to communicate
912920
* securely with its clients:
913921
*
914922
* context.cert = cert
915923
* context.key = key
916924
*
917-
* Then create an SSLServer with a TCP server socket and the context. Use the
918-
* SSLServer like an ordinary TCP server.
925+
* Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the
926+
* context. Use the SSLServer like an ordinary TCP server.
919927
*
920928
* require 'socket'
921929
*
@@ -934,14 +942,15 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
934942
* ssl_connection.close
935943
* end
936944
*
937-
* === SSL client
945+
* === \SSL client
938946
*
939-
* An SSL client is created with a TCP socket and the context.
940-
* SSLSocket#connect must be called to initiate the SSL handshake and start
941-
* encryption. A key and certificate are not required for the client socket.
947+
* An \SSL client is created with a TCP socket and the context.
948+
* OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake
949+
* and start encryption. A key and certificate are not required for the client
950+
* socket.
942951
*
943-
* Note that SSLSocket#close doesn't close the underlying socket by default. Set
944-
* SSLSocket#sync_close to true if you want.
952+
* Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket
953+
* by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want.
945954
*
946955
* require 'socket'
947956
*
@@ -957,7 +966,7 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
957966
*
958967
* === Peer Verification
959968
*
960-
* An unverified SSL connection does not provide much security. For enhanced
969+
* An unverified \SSL connection does not provide much security. For enhanced
961970
* security the client or server can verify the certificate of its peer.
962971
*
963972
* The client can be modified to verify the server's certificate against the
@@ -1008,40 +1017,59 @@ Init_openssl(void)
10081017
rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2);
10091018

10101019
/*
1011-
* Version of OpenSSL the ruby OpenSSL extension was built with
1020+
* \OpenSSL library version string used to compile the Ruby/OpenSSL
1021+
* extension. This may differ from the version used at runtime.
10121022
*/
1013-
rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
1023+
rb_define_const(mOSSL, "OPENSSL_VERSION",
1024+
rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT)));
10141025

10151026
/*
1016-
* Version of OpenSSL the ruby OpenSSL extension is running with
1027+
* \OpenSSL library version string currently used at runtime.
10171028
*/
1018-
rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
1029+
rb_define_const(
1030+
mOSSL,
1031+
"OPENSSL_LIBRARY_VERSION",
1032+
rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION)))
1033+
);
10191034

10201035
/*
1021-
* Version number of OpenSSL the ruby OpenSSL extension was built with
1022-
* (base 16). The formats are below.
1036+
* \OpenSSL library version number used to compile the Ruby/OpenSSL
1037+
* extension. This may differ from the version used at runtime.
10231038
*
1024-
* [OpenSSL 3] <tt>0xMNN00PP0 (major minor 00 patch 0)</tt>
1025-
* [OpenSSL before 3] <tt>0xMNNFFPPS (major minor fix patch status)</tt>
1026-
* [LibreSSL] <tt>0x20000000 (fixed value)</tt>
1039+
* The version number is encoded into a single integer value. The number
1040+
* follows the format:
1041+
*
1042+
* [\OpenSSL 3.0.0 or later]
1043+
* <tt>0xMNN00PP0</tt> (major minor 00 patch 0)
1044+
* [\OpenSSL 1.1.1 or earlier]
1045+
* <tt>0xMNNFFPPS</tt> (major minor fix patch status)
1046+
* [LibreSSL]
1047+
* <tt>0x20000000</tt> (a fixed value)
10271048
*
10281049
* See also the man page OPENSSL_VERSION_NUMBER(3).
10291050
*/
10301051
rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
10311052

10321053
#if defined(LIBRESSL_VERSION_NUMBER)
10331054
/*
1034-
* Version number of LibreSSL the ruby OpenSSL extension was built with
1035-
* (base 16). The format is <tt>0xMNNFF00f (major minor fix 00
1036-
* status)</tt>. This constant is only defined in LibreSSL cases.
1055+
* LibreSSL library version number used to compile the Ruby/OpenSSL
1056+
* extension. This may differ from the version used at runtime.
1057+
*
1058+
* This constant is only defined if the extension was compiled against
1059+
* LibreSSL. The number follows the format:
1060+
* <tt>0xMNNFF00f</tt> (major minor fix 00 status).
10371061
*
10381062
* See also the man page LIBRESSL_VERSION_NUMBER(3).
10391063
*/
10401064
rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER));
10411065
#endif
10421066

10431067
/*
1044-
* Boolean indicating whether OpenSSL is FIPS-capable or not
1068+
* Boolean indicating whether the \OpenSSL library is FIPS-capable or not.
1069+
* Always <tt>true</tt> for \OpenSSL 3.0 and later.
1070+
*
1071+
* This is obsolete and will be removed in the future.
1072+
* See also OpenSSL.fips_mode.
10451073
*/
10461074
rb_define_const(mOSSL, "OPENSSL_FIPS",
10471075
/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */

ext/openssl/ossl_asn1.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,8 +1397,6 @@ void
13971397
Init_ossl_asn1(void)
13981398
{
13991399
#undef rb_intern
1400-
VALUE ary;
1401-
int i;
14021400

14031401
sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL"));
14041402
sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC"));
@@ -1548,17 +1546,20 @@ Init_ossl_asn1(void)
15481546
rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1);
15491547
rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1);
15501548
rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1);
1551-
ary = rb_ary_new();
15521549

1550+
VALUE ary = rb_ary_new_capa(ossl_asn1_info_size);
1551+
for (int i = 0; i < ossl_asn1_info_size; i++) {
1552+
const char *name = ossl_asn1_info[i].name;
1553+
if (name[0] == '[')
1554+
continue;
1555+
rb_define_const(mASN1, name, INT2NUM(i));
1556+
rb_ary_store(ary, i, rb_obj_freeze(rb_str_new_cstr(name)));
1557+
}
1558+
rb_obj_freeze(ary);
15531559
/*
15541560
* Array storing tag names at the tag's index.
15551561
*/
15561562
rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary);
1557-
for(i = 0; i < ossl_asn1_info_size; i++){
1558-
if(ossl_asn1_info[i].name[0] == '[') continue;
1559-
rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i));
1560-
rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name));
1561-
}
15621563

15631564
/* Document-class: OpenSSL::ASN1::ASN1Data
15641565
*
@@ -1880,6 +1881,7 @@ do{\
18801881
rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING));
18811882
rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING));
18821883
rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING));
1884+
rb_obj_freeze(class_tag_map);
18831885

18841886
id_each = rb_intern_const("each");
18851887
}

ext/openssl/ossl_x509.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ VALUE mX509;
1313

1414
#define DefX509Const(x) rb_define_const(mX509, #x, INT2NUM(X509_##x))
1515
#define DefX509Default(x,i) \
16-
rb_define_const(mX509, "DEFAULT_" #x, rb_str_new2(X509_get_default_##i()))
16+
rb_define_const(mX509, "DEFAULT_" #x, \
17+
rb_obj_freeze(rb_str_new_cstr(X509_get_default_##i())))
1718

1819
ASN1_TIME *
1920
ossl_x509_time_adjust(ASN1_TIME *s, VALUE time)

ext/openssl/ossl_x509name.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ Init_ossl_x509name(void)
534534
rb_hash_aset(hash, rb_str_new2("DC"), ia5str);
535535
rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str);
536536
rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str);
537+
rb_obj_freeze(hash);
537538

538539
/*
539540
* The default object type template for name entries.

lib/openssl.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@
2323
require_relative 'openssl/x509'
2424

2525
module OpenSSL
26-
# call-seq:
27-
# OpenSSL.secure_compare(string, string) -> boolean
26+
# :call-seq:
27+
# OpenSSL.secure_compare(string, string) -> true or false
2828
#
2929
# Constant time memory comparison. Inputs are hashed using SHA-256 to mask
3030
# the length of the secret. Returns +true+ if the strings are identical,
3131
# +false+ otherwise.
32+
#
33+
# This method is expensive due to the SHA-256 hashing. In most cases, where
34+
# the input lengths are known to be equal or are not sensitive,
35+
# OpenSSL.fixed_length_secure_compare should be used instead.
3236
def self.secure_compare(a, b)
3337
hashed_a = OpenSSL::Digest.digest('SHA256', a)
3438
hashed_b = OpenSSL::Digest.digest('SHA256', b)

lib/openssl/digest.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Digest < Digest; end # :nodoc:
5757
# OpenSSL::Digest("MD5")
5858
# # => OpenSSL::Digest::MD5
5959
#
60-
# Digest("Foo")
60+
# OpenSSL::Digest("Foo")
6161
# # => NameError: wrong constant name Foo
6262

6363
def Digest(name)

lib/openssl/version.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

33
module OpenSSL
4+
# The version string of Ruby/OpenSSL.
45
VERSION = "4.0.0.pre"
56
end

0 commit comments

Comments
 (0)