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_cipher.c
CHANGED
@@ -42,7 +42,7 @@ static const rb_data_type_t ossl_cipher_type = {
|
|
42
42
|
{
|
43
43
|
0, ossl_cipher_free,
|
44
44
|
},
|
45
|
-
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
45
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
46
46
|
};
|
47
47
|
|
48
48
|
/*
|
@@ -104,7 +104,7 @@ ossl_cipher_alloc(VALUE klass)
|
|
104
104
|
* call-seq:
|
105
105
|
* Cipher.new(string) -> cipher
|
106
106
|
*
|
107
|
-
* The string must
|
107
|
+
* The string must contain a valid cipher name like "aes-256-cbc".
|
108
108
|
*
|
109
109
|
* A list of cipher names is available by calling OpenSSL::Cipher.ciphers.
|
110
110
|
*/
|
@@ -149,11 +149,11 @@ ossl_cipher_copy(VALUE self, VALUE other)
|
|
149
149
|
return self;
|
150
150
|
}
|
151
151
|
|
152
|
-
static void
|
153
|
-
add_cipher_name_to_ary(const OBJ_NAME *name,
|
152
|
+
static void
|
153
|
+
add_cipher_name_to_ary(const OBJ_NAME *name, void *arg)
|
154
154
|
{
|
155
|
+
VALUE ary = (VALUE)arg;
|
155
156
|
rb_ary_push(ary, rb_str_new2(name->name));
|
156
|
-
return NULL;
|
157
157
|
}
|
158
158
|
|
159
159
|
/*
|
@@ -169,7 +169,7 @@ ossl_s_ciphers(VALUE self)
|
|
169
169
|
|
170
170
|
ary = rb_ary_new();
|
171
171
|
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
|
172
|
-
|
172
|
+
add_cipher_name_to_ary,
|
173
173
|
(void*)ary);
|
174
174
|
|
175
175
|
return ary;
|
@@ -237,8 +237,7 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
|
|
237
237
|
ossl_raise(eCipherError, NULL);
|
238
238
|
}
|
239
239
|
|
240
|
-
|
241
|
-
rb_ivar_set(self, id_key_set, Qtrue);
|
240
|
+
rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
|
242
241
|
|
243
242
|
return self;
|
244
243
|
}
|
@@ -317,6 +316,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
|
|
317
316
|
salt = (unsigned char *)RSTRING_PTR(vsalt);
|
318
317
|
}
|
319
318
|
iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
|
319
|
+
if (iter <= 0)
|
320
|
+
rb_raise(rb_eArgError, "iterations must be a positive integer");
|
320
321
|
digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest);
|
321
322
|
GetCipher(self, ctx);
|
322
323
|
EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
|
@@ -383,8 +384,7 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
|
|
383
384
|
|
384
385
|
StringValue(data);
|
385
386
|
in = (unsigned char *)RSTRING_PTR(data);
|
386
|
-
|
387
|
-
ossl_raise(rb_eArgError, "data must not be empty");
|
387
|
+
in_len = RSTRING_LEN(data);
|
388
388
|
GetCipher(self, ctx);
|
389
389
|
out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);
|
390
390
|
if (out_len <= 0) {
|
@@ -812,6 +812,31 @@ ossl_cipher_block_size(VALUE self)
|
|
812
812
|
return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
|
813
813
|
}
|
814
814
|
|
815
|
+
/*
|
816
|
+
* call-seq:
|
817
|
+
* cipher.ccm_data_len = integer -> integer
|
818
|
+
*
|
819
|
+
* Sets the length of the plaintext / ciphertext message that will be
|
820
|
+
* processed in CCM mode. Make sure to call this method after #key= and
|
821
|
+
* #iv= have been set, and before #auth_data=.
|
822
|
+
*
|
823
|
+
* Only call this method after calling Cipher#encrypt or Cipher#decrypt.
|
824
|
+
*/
|
825
|
+
static VALUE
|
826
|
+
ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
|
827
|
+
{
|
828
|
+
int in_len, out_len;
|
829
|
+
EVP_CIPHER_CTX *ctx;
|
830
|
+
|
831
|
+
in_len = NUM2INT(data_len);
|
832
|
+
|
833
|
+
GetCipher(self, ctx);
|
834
|
+
if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
|
835
|
+
ossl_raise(eCipherError, NULL);
|
836
|
+
|
837
|
+
return data_len;
|
838
|
+
}
|
839
|
+
|
815
840
|
/*
|
816
841
|
* INIT
|
817
842
|
*/
|
@@ -848,23 +873,7 @@ Init_ossl_cipher(void)
|
|
848
873
|
* individual components name, key length and mode. Either all uppercase
|
849
874
|
* or all lowercase strings may be used, for example:
|
850
875
|
*
|
851
|
-
* cipher = OpenSSL::Cipher.new('
|
852
|
-
*
|
853
|
-
* For each algorithm supported, there is a class defined under the
|
854
|
-
* Cipher class that goes by the name of the cipher, e.g. to obtain an
|
855
|
-
* instance of AES, you could also use
|
856
|
-
*
|
857
|
-
* # these are equivalent
|
858
|
-
* cipher = OpenSSL::Cipher::AES.new(128, :CBC)
|
859
|
-
* cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
|
860
|
-
* cipher = OpenSSL::Cipher::AES.new('128-CBC')
|
861
|
-
*
|
862
|
-
* Finally, due to its wide-spread use, there are also extra classes
|
863
|
-
* defined for the different key sizes of AES
|
864
|
-
*
|
865
|
-
* cipher = OpenSSL::Cipher::AES128.new(:CBC)
|
866
|
-
* cipher = OpenSSL::Cipher::AES192.new(:CBC)
|
867
|
-
* cipher = OpenSSL::Cipher::AES256.new(:CBC)
|
876
|
+
* cipher = OpenSSL::Cipher.new('aes-128-cbc')
|
868
877
|
*
|
869
878
|
* === Choosing either encryption or decryption mode
|
870
879
|
*
|
@@ -894,7 +903,7 @@ Init_ossl_cipher(void)
|
|
894
903
|
* without processing the password further. A simple and secure way to
|
895
904
|
* create a key for a particular Cipher is
|
896
905
|
*
|
897
|
-
* cipher = OpenSSL::
|
906
|
+
* cipher = OpenSSL::Cipher.new('aes-256-cfb')
|
898
907
|
* cipher.encrypt
|
899
908
|
* key = cipher.random_key # also sets the generated key on the Cipher
|
900
909
|
*
|
@@ -962,14 +971,14 @@ Init_ossl_cipher(void)
|
|
962
971
|
*
|
963
972
|
* data = "Very, very confidential data"
|
964
973
|
*
|
965
|
-
* cipher = OpenSSL::Cipher
|
974
|
+
* cipher = OpenSSL::Cipher.new('aes-128-cbc')
|
966
975
|
* cipher.encrypt
|
967
976
|
* key = cipher.random_key
|
968
977
|
* iv = cipher.random_iv
|
969
978
|
*
|
970
979
|
* encrypted = cipher.update(data) + cipher.final
|
971
980
|
* ...
|
972
|
-
* decipher = OpenSSL::Cipher
|
981
|
+
* decipher = OpenSSL::Cipher.new('aes-128-cbc')
|
973
982
|
* decipher.decrypt
|
974
983
|
* decipher.key = key
|
975
984
|
* decipher.iv = iv
|
@@ -1005,7 +1014,7 @@ Init_ossl_cipher(void)
|
|
1005
1014
|
* not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
|
1006
1015
|
* security guarantees of GCM mode.
|
1007
1016
|
*
|
1008
|
-
* cipher = OpenSSL::Cipher
|
1017
|
+
* cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt
|
1009
1018
|
* cipher.key = key
|
1010
1019
|
* cipher.iv = nonce
|
1011
1020
|
* cipher.auth_data = auth_data
|
@@ -1021,7 +1030,7 @@ Init_ossl_cipher(void)
|
|
1021
1030
|
* ciphertext with a probability of 1/256.
|
1022
1031
|
*
|
1023
1032
|
* raise "tag is truncated!" unless tag.bytesize == 16
|
1024
|
-
* decipher = OpenSSL::Cipher
|
1033
|
+
* decipher = OpenSSL::Cipher.new('aes-128-gcm').decrypt
|
1025
1034
|
* decipher.key = key
|
1026
1035
|
* decipher.iv = nonce
|
1027
1036
|
* decipher.auth_tag = tag
|
@@ -1058,6 +1067,7 @@ Init_ossl_cipher(void)
|
|
1058
1067
|
rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
|
1059
1068
|
rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
|
1060
1069
|
rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
|
1070
|
+
rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
|
1061
1071
|
|
1062
1072
|
id_auth_tag_len = rb_intern_const("auth_tag_len");
|
1063
1073
|
id_key_set = rb_intern_const("key_set");
|
data/ext/openssl/ossl_config.c
CHANGED
@@ -9,81 +9,452 @@
|
|
9
9
|
*/
|
10
10
|
#include "ossl.h"
|
11
11
|
|
12
|
+
static VALUE cConfig, eConfigError;
|
13
|
+
|
14
|
+
static void
|
15
|
+
nconf_free(void *conf)
|
16
|
+
{
|
17
|
+
NCONF_free(conf);
|
18
|
+
}
|
19
|
+
|
20
|
+
static const rb_data_type_t ossl_config_type = {
|
21
|
+
"OpenSSL/CONF",
|
22
|
+
{
|
23
|
+
0, nconf_free,
|
24
|
+
},
|
25
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
26
|
+
};
|
27
|
+
|
28
|
+
CONF *
|
29
|
+
GetConfig(VALUE obj)
|
30
|
+
{
|
31
|
+
CONF *conf;
|
32
|
+
|
33
|
+
TypedData_Get_Struct(obj, CONF, &ossl_config_type, conf);
|
34
|
+
if (!conf)
|
35
|
+
rb_raise(rb_eRuntimeError, "CONF is not initialized");
|
36
|
+
return conf;
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE
|
40
|
+
config_s_alloc(VALUE klass)
|
41
|
+
{
|
42
|
+
VALUE obj;
|
43
|
+
CONF *conf;
|
44
|
+
|
45
|
+
obj = TypedData_Wrap_Struct(klass, &ossl_config_type, 0);
|
46
|
+
conf = NCONF_new(NULL);
|
47
|
+
if (!conf)
|
48
|
+
ossl_raise(eConfigError, "NCONF_new");
|
49
|
+
RTYPEDDATA_DATA(obj) = conf;
|
50
|
+
return obj;
|
51
|
+
}
|
52
|
+
|
53
|
+
static void
|
54
|
+
config_load_bio(CONF *conf, BIO *bio)
|
55
|
+
{
|
56
|
+
long eline = -1;
|
57
|
+
|
58
|
+
if (!NCONF_load_bio(conf, bio, &eline)) {
|
59
|
+
BIO_free(bio);
|
60
|
+
if (eline <= 0)
|
61
|
+
ossl_raise(eConfigError, "wrong config format");
|
62
|
+
else
|
63
|
+
ossl_raise(eConfigError, "error in line %ld", eline);
|
64
|
+
}
|
65
|
+
BIO_free(bio);
|
66
|
+
|
67
|
+
/*
|
68
|
+
* Clear the error queue even if it is parsed successfully.
|
69
|
+
* Particularly, when the .include directive refers to a non-existent file,
|
70
|
+
* it is only reported in the error queue.
|
71
|
+
*/
|
72
|
+
ossl_clear_error();
|
73
|
+
}
|
12
74
|
|
13
75
|
/*
|
14
|
-
*
|
15
|
-
|
16
|
-
VALUE cConfig;
|
17
|
-
/* Document-class: OpenSSL::ConfigError
|
76
|
+
* call-seq:
|
77
|
+
* Config.parse(string) -> OpenSSL::Config
|
18
78
|
*
|
19
|
-
*
|
20
|
-
* parsing errors, etc.
|
79
|
+
* Parses a given _string_ as a blob that contains configuration for OpenSSL.
|
21
80
|
*/
|
22
|
-
VALUE
|
81
|
+
static VALUE
|
82
|
+
config_s_parse(VALUE klass, VALUE str)
|
83
|
+
{
|
84
|
+
VALUE obj = config_s_alloc(klass);
|
85
|
+
CONF *conf = GetConfig(obj);
|
86
|
+
BIO *bio;
|
87
|
+
|
88
|
+
bio = ossl_obj2bio(&str);
|
89
|
+
config_load_bio(conf, bio); /* Consumes BIO */
|
90
|
+
return obj;
|
91
|
+
}
|
92
|
+
|
93
|
+
static VALUE config_get_sections(VALUE self);
|
94
|
+
static VALUE config_get_section(VALUE self, VALUE section);
|
23
95
|
|
24
96
|
/*
|
25
|
-
*
|
97
|
+
* call-seq:
|
98
|
+
* Config.parse_config(io) -> hash
|
99
|
+
*
|
100
|
+
* Parses the configuration data read from _io_ and returns the whole content
|
101
|
+
* as a Hash.
|
26
102
|
*/
|
103
|
+
static VALUE
|
104
|
+
config_s_parse_config(VALUE klass, VALUE io)
|
105
|
+
{
|
106
|
+
VALUE obj, sections, ret;
|
107
|
+
long i;
|
108
|
+
|
109
|
+
obj = config_s_parse(klass, io);
|
110
|
+
sections = config_get_sections(obj);
|
111
|
+
ret = rb_hash_new();
|
112
|
+
for (i = 0; i < RARRAY_LEN(sections); i++) {
|
113
|
+
VALUE section = rb_ary_entry(sections, i);
|
114
|
+
rb_hash_aset(ret, section, config_get_section(obj, section));
|
115
|
+
}
|
116
|
+
return ret;
|
117
|
+
}
|
27
118
|
|
28
119
|
/*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
*
|
32
|
-
*
|
120
|
+
* call-seq:
|
121
|
+
* Config.new(filename) -> OpenSSL::Config
|
122
|
+
*
|
123
|
+
* Creates an instance of OpenSSL::Config from the content of the file
|
124
|
+
* specified by _filename_.
|
125
|
+
*
|
126
|
+
* This can be used in contexts like OpenSSL::X509::ExtensionFactory.config=
|
127
|
+
*
|
128
|
+
* This can raise IO exceptions based on the access, or availability of the
|
129
|
+
* file. A ConfigError exception may be raised depending on the validity of
|
130
|
+
* the data being configured.
|
33
131
|
*/
|
34
|
-
|
35
|
-
|
132
|
+
static VALUE
|
133
|
+
config_initialize(int argc, VALUE *argv, VALUE self)
|
36
134
|
{
|
37
|
-
CONF *conf;
|
135
|
+
CONF *conf = GetConfig(self);
|
136
|
+
VALUE filename;
|
137
|
+
|
138
|
+
/* 0-arguments call has no use-case, but is kept for compatibility */
|
139
|
+
rb_scan_args(argc, argv, "01", &filename);
|
140
|
+
rb_check_frozen(self);
|
141
|
+
if (!NIL_P(filename)) {
|
142
|
+
BIO *bio = BIO_new_file(StringValueCStr(filename), "rb");
|
143
|
+
if (!bio)
|
144
|
+
ossl_raise(eConfigError, "BIO_new_file");
|
145
|
+
config_load_bio(conf, bio); /* Consumes BIO */
|
146
|
+
}
|
147
|
+
return self;
|
148
|
+
}
|
149
|
+
|
150
|
+
static VALUE
|
151
|
+
config_initialize_copy(VALUE self, VALUE other)
|
152
|
+
{
|
153
|
+
CONF *conf = GetConfig(self);
|
38
154
|
VALUE str;
|
39
155
|
BIO *bio;
|
40
|
-
long eline = -1;
|
41
156
|
|
42
|
-
|
43
|
-
|
157
|
+
str = rb_funcall(other, rb_intern("to_s"), 0);
|
158
|
+
rb_check_frozen(self);
|
44
159
|
bio = ossl_obj2bio(&str);
|
45
|
-
conf
|
46
|
-
|
47
|
-
|
48
|
-
|
160
|
+
config_load_bio(conf, bio); /* Consumes BIO */
|
161
|
+
return self;
|
162
|
+
}
|
163
|
+
|
164
|
+
/*
|
165
|
+
* call-seq:
|
166
|
+
* config.get_value(section, key) -> string
|
167
|
+
*
|
168
|
+
* Gets the value of _key_ from the given _section_.
|
169
|
+
*
|
170
|
+
* Given the following configurating file being loaded:
|
171
|
+
*
|
172
|
+
* config = OpenSSL::Config.load('foo.cnf')
|
173
|
+
* #=> #<OpenSSL::Config sections=["default"]>
|
174
|
+
* puts config.to_s
|
175
|
+
* #=> [ default ]
|
176
|
+
* # foo=bar
|
177
|
+
*
|
178
|
+
* You can get a specific value from the config if you know the _section_
|
179
|
+
* and _key_ like so:
|
180
|
+
*
|
181
|
+
* config.get_value('default','foo')
|
182
|
+
* #=> "bar"
|
183
|
+
*/
|
184
|
+
static VALUE
|
185
|
+
config_get_value(VALUE self, VALUE section, VALUE key)
|
186
|
+
{
|
187
|
+
CONF *conf = GetConfig(self);
|
188
|
+
const char *str, *sectionp;
|
189
|
+
|
190
|
+
StringValueCStr(section);
|
191
|
+
StringValueCStr(key);
|
192
|
+
/* For compatibility; NULL means "default". */
|
193
|
+
sectionp = RSTRING_LEN(section) ? RSTRING_PTR(section) : NULL;
|
194
|
+
str = NCONF_get_string(conf, sectionp, RSTRING_PTR(key));
|
195
|
+
if (!str) {
|
196
|
+
ossl_clear_error();
|
197
|
+
return Qnil;
|
198
|
+
}
|
199
|
+
return rb_str_new_cstr(str);
|
200
|
+
}
|
201
|
+
|
202
|
+
/*
|
203
|
+
* call-seq:
|
204
|
+
* config[section] -> hash
|
205
|
+
*
|
206
|
+
* Gets all key-value pairs in a specific _section_ from the current
|
207
|
+
* configuration.
|
208
|
+
*
|
209
|
+
* Given the following configurating file being loaded:
|
210
|
+
*
|
211
|
+
* config = OpenSSL::Config.load('foo.cnf')
|
212
|
+
* #=> #<OpenSSL::Config sections=["default"]>
|
213
|
+
* puts config.to_s
|
214
|
+
* #=> [ default ]
|
215
|
+
* # foo=bar
|
216
|
+
*
|
217
|
+
* You can get a hash of the specific section like so:
|
218
|
+
*
|
219
|
+
* config['default']
|
220
|
+
* #=> {"foo"=>"bar"}
|
221
|
+
*
|
222
|
+
*/
|
223
|
+
static VALUE
|
224
|
+
config_get_section(VALUE self, VALUE section)
|
225
|
+
{
|
226
|
+
CONF *conf = GetConfig(self);
|
227
|
+
STACK_OF(CONF_VALUE) *sk;
|
228
|
+
int i, entries;
|
229
|
+
VALUE hash;
|
230
|
+
|
231
|
+
hash = rb_hash_new();
|
232
|
+
StringValueCStr(section);
|
233
|
+
if (!(sk = NCONF_get_section(conf, RSTRING_PTR(section)))) {
|
234
|
+
ossl_clear_error();
|
235
|
+
return hash;
|
49
236
|
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
else
|
56
|
-
ossl_raise(eConfigError, "error in line %d", eline);
|
237
|
+
entries = sk_CONF_VALUE_num(sk);
|
238
|
+
for (i = 0; i < entries; i++) {
|
239
|
+
CONF_VALUE *entry = sk_CONF_VALUE_value(sk, i);
|
240
|
+
rb_hash_aset(hash, rb_str_new_cstr(entry->name),
|
241
|
+
rb_str_new_cstr(entry->value));
|
57
242
|
}
|
58
|
-
|
243
|
+
return hash;
|
244
|
+
}
|
59
245
|
|
60
|
-
|
246
|
+
static void
|
247
|
+
get_conf_section_doall_arg(CONF_VALUE *cv, VALUE *aryp)
|
248
|
+
{
|
249
|
+
if (cv->name)
|
250
|
+
return;
|
251
|
+
rb_ary_push(*aryp, rb_str_new_cstr(cv->section));
|
61
252
|
}
|
62
253
|
|
63
|
-
/*
|
254
|
+
/* IMPLEMENT_LHASH_DOALL_ARG_CONST() requires >= OpenSSL 1.1.0 */
|
255
|
+
static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE, VALUE)
|
256
|
+
|
257
|
+
/*
|
258
|
+
* call-seq:
|
259
|
+
* config.sections -> array of string
|
64
260
|
*
|
65
|
-
*
|
261
|
+
* Get the names of all sections in the current configuration.
|
66
262
|
*/
|
263
|
+
static VALUE
|
264
|
+
config_get_sections(VALUE self)
|
265
|
+
{
|
266
|
+
CONF *conf = GetConfig(self);
|
267
|
+
VALUE ary;
|
268
|
+
|
269
|
+
ary = rb_ary_new();
|
270
|
+
lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(get_conf_section),
|
271
|
+
&ary);
|
272
|
+
return ary;
|
273
|
+
}
|
274
|
+
|
275
|
+
static void
|
276
|
+
dump_conf_value_doall_arg(CONF_VALUE *cv, VALUE *strp)
|
277
|
+
{
|
278
|
+
VALUE str = *strp;
|
279
|
+
STACK_OF(CONF_VALUE) *sk;
|
280
|
+
int i, num;
|
281
|
+
|
282
|
+
if (cv->name)
|
283
|
+
return;
|
284
|
+
sk = (STACK_OF(CONF_VALUE) *)cv->value;
|
285
|
+
num = sk_CONF_VALUE_num(sk);
|
286
|
+
rb_str_cat_cstr(str, "[ ");
|
287
|
+
rb_str_cat_cstr(str, cv->section);
|
288
|
+
rb_str_cat_cstr(str, " ]\n");
|
289
|
+
for (i = 0; i < num; i++){
|
290
|
+
CONF_VALUE *v = sk_CONF_VALUE_value(sk, i);
|
291
|
+
rb_str_cat_cstr(str, v->name ? v->name : "None");
|
292
|
+
rb_str_cat_cstr(str, "=");
|
293
|
+
rb_str_cat_cstr(str, v->value ? v->value : "None");
|
294
|
+
rb_str_cat_cstr(str, "\n");
|
295
|
+
}
|
296
|
+
rb_str_cat_cstr(str, "\n");
|
297
|
+
}
|
298
|
+
|
299
|
+
static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, VALUE)
|
67
300
|
|
68
301
|
/*
|
69
|
-
*
|
302
|
+
* call-seq:
|
303
|
+
* config.to_s -> string
|
304
|
+
*
|
305
|
+
*
|
306
|
+
* Gets the parsable form of the current configuration.
|
307
|
+
*
|
308
|
+
* Given the following configuration being created:
|
309
|
+
*
|
310
|
+
* config = OpenSSL::Config.new
|
311
|
+
* #=> #<OpenSSL::Config sections=[]>
|
312
|
+
* config['default'] = {"foo"=>"bar","baz"=>"buz"}
|
313
|
+
* #=> {"foo"=>"bar", "baz"=>"buz"}
|
314
|
+
* puts config.to_s
|
315
|
+
* #=> [ default ]
|
316
|
+
* # foo=bar
|
317
|
+
* # baz=buz
|
318
|
+
*
|
319
|
+
* You can parse get the serialized configuration using #to_s and then parse
|
320
|
+
* it later:
|
321
|
+
*
|
322
|
+
* serialized_config = config.to_s
|
323
|
+
* # much later...
|
324
|
+
* new_config = OpenSSL::Config.parse(serialized_config)
|
325
|
+
* #=> #<OpenSSL::Config sections=["default"]>
|
326
|
+
* puts new_config
|
327
|
+
* #=> [ default ]
|
328
|
+
* foo=bar
|
329
|
+
* baz=buz
|
70
330
|
*/
|
331
|
+
static VALUE
|
332
|
+
config_to_s(VALUE self)
|
333
|
+
{
|
334
|
+
CONF *conf = GetConfig(self);
|
335
|
+
VALUE str;
|
336
|
+
|
337
|
+
str = rb_str_new(NULL, 0);
|
338
|
+
lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(dump_conf_value),
|
339
|
+
&str);
|
340
|
+
return str;
|
341
|
+
}
|
342
|
+
|
343
|
+
static void
|
344
|
+
each_conf_value_doall_arg(CONF_VALUE *cv, void *unused)
|
345
|
+
{
|
346
|
+
STACK_OF(CONF_VALUE) *sk;
|
347
|
+
VALUE section;
|
348
|
+
int i, num;
|
349
|
+
|
350
|
+
if (cv->name)
|
351
|
+
return;
|
352
|
+
sk = (STACK_OF(CONF_VALUE) *)cv->value;
|
353
|
+
num = sk_CONF_VALUE_num(sk);
|
354
|
+
section = rb_str_new_cstr(cv->section);
|
355
|
+
for (i = 0; i < num; i++){
|
356
|
+
CONF_VALUE *v = sk_CONF_VALUE_value(sk, i);
|
357
|
+
VALUE name = v->name ? rb_str_new_cstr(v->name) : Qnil;
|
358
|
+
VALUE value = v->value ? rb_str_new_cstr(v->value) : Qnil;
|
359
|
+
rb_yield(rb_ary_new3(3, section, name, value));
|
360
|
+
}
|
361
|
+
}
|
362
|
+
|
363
|
+
static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE, void)
|
364
|
+
|
365
|
+
/*
|
366
|
+
* call-seq:
|
367
|
+
* config.each { |section, key, value| }
|
368
|
+
*
|
369
|
+
* Retrieves the section and its pairs for the current configuration.
|
370
|
+
*
|
371
|
+
* config.each do |section, key, value|
|
372
|
+
* # ...
|
373
|
+
* end
|
374
|
+
*/
|
375
|
+
static VALUE
|
376
|
+
config_each(VALUE self)
|
377
|
+
{
|
378
|
+
CONF *conf = GetConfig(self);
|
379
|
+
|
380
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
381
|
+
|
382
|
+
lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(each_conf_value),
|
383
|
+
NULL);
|
384
|
+
return self;
|
385
|
+
}
|
386
|
+
|
387
|
+
/*
|
388
|
+
* call-seq:
|
389
|
+
* config.inspect -> string
|
390
|
+
*
|
391
|
+
* String representation of this configuration object, including the class
|
392
|
+
* name and its sections.
|
393
|
+
*/
|
394
|
+
static VALUE
|
395
|
+
config_inspect(VALUE self)
|
396
|
+
{
|
397
|
+
VALUE str, ary = config_get_sections(self);
|
398
|
+
const char *cname = rb_class2name(rb_obj_class(self));
|
399
|
+
|
400
|
+
str = rb_str_new_cstr("#<");
|
401
|
+
rb_str_cat_cstr(str, cname);
|
402
|
+
rb_str_cat_cstr(str, " sections=");
|
403
|
+
rb_str_append(str, rb_inspect(ary));
|
404
|
+
rb_str_cat_cstr(str, ">");
|
405
|
+
|
406
|
+
return str;
|
407
|
+
}
|
408
|
+
|
71
409
|
void
|
72
410
|
Init_ossl_config(void)
|
73
411
|
{
|
74
|
-
char *
|
412
|
+
char *path;
|
413
|
+
VALUE path_str;
|
75
414
|
|
76
415
|
#if 0
|
77
416
|
mOSSL = rb_define_module("OpenSSL");
|
78
417
|
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
79
418
|
#endif
|
80
419
|
|
81
|
-
|
420
|
+
/* Document-class: OpenSSL::Config
|
421
|
+
*
|
422
|
+
* Configuration for the openssl library.
|
423
|
+
*
|
424
|
+
* Many system's installation of openssl library will depend on your system
|
425
|
+
* configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for
|
426
|
+
* the location of the file for your host.
|
427
|
+
*
|
428
|
+
* See also http://www.openssl.org/docs/apps/config.html
|
429
|
+
*/
|
82
430
|
cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject);
|
83
431
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
432
|
+
/* Document-class: OpenSSL::ConfigError
|
433
|
+
*
|
434
|
+
* General error for openssl library configuration files. Including formatting,
|
435
|
+
* parsing errors, etc.
|
436
|
+
*/
|
437
|
+
eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError);
|
438
|
+
|
439
|
+
rb_include_module(cConfig, rb_mEnumerable);
|
440
|
+
rb_define_singleton_method(cConfig, "parse", config_s_parse, 1);
|
441
|
+
rb_define_singleton_method(cConfig, "parse_config", config_s_parse_config, 1);
|
442
|
+
rb_define_alias(CLASS_OF(cConfig), "load", "new");
|
443
|
+
rb_define_alloc_func(cConfig, config_s_alloc);
|
444
|
+
rb_define_method(cConfig, "initialize", config_initialize, -1);
|
445
|
+
rb_define_method(cConfig, "initialize_copy", config_initialize_copy, 1);
|
446
|
+
rb_define_method(cConfig, "get_value", config_get_value, 2);
|
447
|
+
rb_define_method(cConfig, "[]", config_get_section, 1);
|
448
|
+
rb_define_method(cConfig, "sections", config_get_sections, 0);
|
449
|
+
rb_define_method(cConfig, "to_s", config_to_s, 0);
|
450
|
+
rb_define_method(cConfig, "each", config_each, 0);
|
451
|
+
rb_define_method(cConfig, "inspect", config_inspect, 0);
|
452
|
+
|
453
|
+
/* Document-const: DEFAULT_CONFIG_FILE
|
454
|
+
*
|
455
|
+
* The default system configuration file for OpenSSL.
|
456
|
+
*/
|
457
|
+
path = CONF_get1_default_config_file();
|
458
|
+
path_str = ossl_buf2str(path, rb_long2int(strlen(path)));
|
459
|
+
rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", path_str);
|
89
460
|
}
|
data/ext/openssl/ossl_config.h
CHANGED
@@ -7,13 +7,10 @@
|
|
7
7
|
* This program is licensed under the same licence as Ruby.
|
8
8
|
* (See the file 'LICENCE'.)
|
9
9
|
*/
|
10
|
-
#
|
11
|
-
#define
|
10
|
+
#ifndef OSSL_CONFIG_H
|
11
|
+
#define OSSL_CONFIG_H
|
12
12
|
|
13
|
-
|
14
|
-
extern VALUE eConfigError;
|
15
|
-
|
16
|
-
CONF* DupConfigPtr(VALUE obj);
|
13
|
+
CONF *GetConfig(VALUE obj);
|
17
14
|
void Init_ossl_config(void);
|
18
15
|
|
19
|
-
#endif /*
|
16
|
+
#endif /* OSSL_CONFIG_H */
|