openssl 2.1.4 → 2.2.2

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +9 -7
  3. data/History.md +100 -0
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +24 -15
  6. data/ext/openssl/openssl_missing.h +36 -1
  7. data/ext/openssl/ossl.c +58 -25
  8. data/ext/openssl/ossl.h +7 -4
  9. data/ext/openssl/ossl_asn1.c +25 -0
  10. data/ext/openssl/ossl_bn.c +65 -10
  11. data/ext/openssl/ossl_bn.h +2 -1
  12. data/ext/openssl/ossl_cipher.c +33 -24
  13. data/ext/openssl/ossl_digest.c +16 -51
  14. data/ext/openssl/ossl_engine.c +2 -12
  15. data/ext/openssl/ossl_hmac.c +5 -11
  16. data/ext/openssl/ossl_kdf.c +3 -19
  17. data/ext/openssl/ossl_ns_spki.c +1 -1
  18. data/ext/openssl/ossl_ocsp.c +6 -11
  19. data/ext/openssl/ossl_ocsp.h +3 -3
  20. data/ext/openssl/ossl_pkcs7.c +3 -19
  21. data/ext/openssl/ossl_pkcs7.h +16 -0
  22. data/ext/openssl/ossl_pkey.c +180 -14
  23. data/ext/openssl/ossl_pkey_dsa.c +2 -2
  24. data/ext/openssl/ossl_pkey_ec.c +29 -0
  25. data/ext/openssl/ossl_pkey_rsa.c +17 -9
  26. data/ext/openssl/ossl_rand.c +2 -32
  27. data/ext/openssl/ossl_ssl.c +94 -42
  28. data/ext/openssl/ossl_ts.c +1524 -0
  29. data/ext/openssl/ossl_ts.h +16 -0
  30. data/ext/openssl/ossl_x509cert.c +2 -2
  31. data/ext/openssl/ossl_x509ext.c +14 -0
  32. data/ext/openssl/ossl_x509name.c +7 -3
  33. data/lib/openssl/bn.rb +1 -1
  34. data/lib/openssl/buffering.rb +28 -5
  35. data/lib/openssl/cipher.rb +1 -1
  36. data/lib/openssl/config.rb +17 -8
  37. data/lib/openssl/digest.rb +10 -12
  38. data/lib/openssl/hmac.rb +13 -0
  39. data/lib/openssl/marshal.rb +30 -0
  40. data/lib/openssl/pkcs5.rb +1 -1
  41. data/lib/openssl/pkey.rb +18 -1
  42. data/lib/openssl/ssl.rb +40 -2
  43. data/lib/openssl/version.rb +5 -0
  44. data/lib/openssl/x509.rb +155 -1
  45. data/lib/openssl.rb +25 -9
  46. metadata +6 -3
  47. data/ext/openssl/deprecation.rb +0 -27
  48. data/ext/openssl/ossl_version.h +0 -15
@@ -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
- * BN_CTX - is used in more difficult math. ops
155
- * (Why just 1? Because Ruby itself isn't thread safe,
156
- * we don't need to care about threads)
157
- */
158
- BN_CTX *ossl_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
@@ -193,6 +242,10 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
193
242
  base = NUM2INT(bs);
194
243
  }
195
244
 
245
+ if (NIL_P(str)) {
246
+ ossl_raise(rb_eArgError, "invalid argument");
247
+ }
248
+
196
249
  if (RB_INTEGER_TYPE_P(str)) {
197
250
  GetBN(self, bn);
198
251
  integer_to_bnptr(str, bn);
@@ -1099,9 +1152,11 @@ Init_ossl_bn(void)
1099
1152
  eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1100
1153
  #endif
1101
1154
 
1102
- if (!(ossl_bn_ctx = BN_CTX_new())) {
1103
- ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
1104
- }
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
1105
1160
 
1106
1161
  eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1107
1162
 
@@ -13,7 +13,8 @@
13
13
  extern VALUE cBN;
14
14
  extern VALUE eBNError;
15
15
 
16
- extern BN_CTX *ossl_bn_ctx;
16
+ BN_CTX *ossl_bn_ctx_get(void);
17
+ #define ossl_bn_ctx ossl_bn_ctx_get()
17
18
 
18
19
  #define GetBNPtr(obj) ossl_bn_value_ptr(&(obj))
19
20
 
@@ -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 be a valid cipher name like "AES-128-CBC" or "3DES".
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
  */
@@ -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
- if (p_key)
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
  }
@@ -814,6 +813,31 @@ ossl_cipher_block_size(VALUE self)
814
813
  return INT2NUM(EVP_CIPHER_CTX_block_size(ctx));
815
814
  }
816
815
 
816
+ /*
817
+ * call-seq:
818
+ * cipher.ccm_data_len = integer -> integer
819
+ *
820
+ * Sets the length of the plaintext / ciphertext message that will be
821
+ * processed in CCM mode. Make sure to call this method after #key= and
822
+ * #iv= have been set, and before #auth_data=.
823
+ *
824
+ * Only call this method after calling Cipher#encrypt or Cipher#decrypt.
825
+ */
826
+ static VALUE
827
+ ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len)
828
+ {
829
+ int in_len, out_len;
830
+ EVP_CIPHER_CTX *ctx;
831
+
832
+ in_len = NUM2INT(data_len);
833
+
834
+ GetCipher(self, ctx);
835
+ if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1)
836
+ ossl_raise(eCipherError, NULL);
837
+
838
+ return data_len;
839
+ }
840
+
817
841
  /*
818
842
  * INIT
819
843
  */
@@ -852,22 +876,6 @@ Init_ossl_cipher(void)
852
876
  *
853
877
  * cipher = OpenSSL::Cipher.new('AES-128-CBC')
854
878
  *
855
- * For each algorithm supported, there is a class defined under the
856
- * Cipher class that goes by the name of the cipher, e.g. to obtain an
857
- * instance of AES, you could also use
858
- *
859
- * # these are equivalent
860
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
861
- * cipher = OpenSSL::Cipher::AES.new(128, 'CBC')
862
- * cipher = OpenSSL::Cipher::AES.new('128-CBC')
863
- *
864
- * Finally, due to its wide-spread use, there are also extra classes
865
- * defined for the different key sizes of AES
866
- *
867
- * cipher = OpenSSL::Cipher::AES128.new(:CBC)
868
- * cipher = OpenSSL::Cipher::AES192.new(:CBC)
869
- * cipher = OpenSSL::Cipher::AES256.new(:CBC)
870
- *
871
879
  * === Choosing either encryption or decryption mode
872
880
  *
873
881
  * Encryption and decryption are often very similar operations for
@@ -896,7 +904,7 @@ Init_ossl_cipher(void)
896
904
  * without processing the password further. A simple and secure way to
897
905
  * create a key for a particular Cipher is
898
906
  *
899
- * cipher = OpenSSL::AES256.new(:CFB)
907
+ * cipher = OpenSSL::Cipher.new('AES-256-CFB')
900
908
  * cipher.encrypt
901
909
  * key = cipher.random_key # also sets the generated key on the Cipher
902
910
  *
@@ -964,14 +972,14 @@ Init_ossl_cipher(void)
964
972
  *
965
973
  * data = "Very, very confidential data"
966
974
  *
967
- * cipher = OpenSSL::Cipher::AES.new(128, :CBC)
975
+ * cipher = OpenSSL::Cipher.new('AES-128-CBC')
968
976
  * cipher.encrypt
969
977
  * key = cipher.random_key
970
978
  * iv = cipher.random_iv
971
979
  *
972
980
  * encrypted = cipher.update(data) + cipher.final
973
981
  * ...
974
- * decipher = OpenSSL::Cipher::AES.new(128, :CBC)
982
+ * decipher = OpenSSL::Cipher.new('AES-128-CBC')
975
983
  * decipher.decrypt
976
984
  * decipher.key = key
977
985
  * decipher.iv = iv
@@ -1007,7 +1015,7 @@ Init_ossl_cipher(void)
1007
1015
  * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the
1008
1016
  * security guarantees of GCM mode.
1009
1017
  *
1010
- * cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt
1018
+ * cipher = OpenSSL::Cipher.new('AES-128-GCM').encrypt
1011
1019
  * cipher.key = key
1012
1020
  * cipher.iv = nonce
1013
1021
  * cipher.auth_data = auth_data
@@ -1023,7 +1031,7 @@ Init_ossl_cipher(void)
1023
1031
  * ciphertext with a probability of 1/256.
1024
1032
  *
1025
1033
  * raise "tag is truncated!" unless tag.bytesize == 16
1026
- * decipher = OpenSSL::Cipher::AES.new(128, :GCM).decrypt
1034
+ * decipher = OpenSSL::Cipher.new('AES-128-GCM').decrypt
1027
1035
  * decipher.key = key
1028
1036
  * decipher.iv = nonce
1029
1037
  * decipher.auth_tag = tag
@@ -1060,6 +1068,7 @@ Init_ossl_cipher(void)
1060
1068
  rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
1061
1069
  rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
1062
1070
  rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
1071
+ rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1);
1063
1072
 
1064
1073
  id_auth_tag_len = rb_intern_const("auth_tag_len");
1065
1074
  id_key_set = rb_intern_const("key_set");
@@ -192,7 +192,7 @@ ossl_digest_reset(VALUE self)
192
192
  * be passed individually to the Digest instance.
193
193
  *
194
194
  * === Example
195
- * digest = OpenSSL::Digest::SHA256.new
195
+ * digest = OpenSSL::Digest.new('SHA256')
196
196
  * digest.update('First input')
197
197
  * digest << 'Second input' # equivalent to digest.update('Second input')
198
198
  * result = digest.digest
@@ -248,7 +248,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
248
248
  * Returns the sn of this Digest algorithm.
249
249
  *
250
250
  * === Example
251
- * digest = OpenSSL::Digest::SHA512.new
251
+ * digest = OpenSSL::Digest.new('SHA512')
252
252
  * puts digest.name # => SHA512
253
253
  *
254
254
  */
@@ -270,7 +270,7 @@ ossl_digest_name(VALUE self)
270
270
  * final message digest result.
271
271
  *
272
272
  * === Example
273
- * digest = OpenSSL::Digest::SHA1.new
273
+ * digest = OpenSSL::Digest.new('SHA1')
274
274
  * puts digest.digest_length # => 20
275
275
  *
276
276
  */
@@ -294,7 +294,7 @@ ossl_digest_size(VALUE self)
294
294
  * consecutively.
295
295
  *
296
296
  * === Example
297
- * digest = OpenSSL::Digest::SHA1.new
297
+ * digest = OpenSSL::Digest.new('SHA1')
298
298
  * puts digest.block_length # => 64
299
299
  */
300
300
  static VALUE
@@ -346,54 +346,19 @@ Init_ossl_digest(void)
346
346
  * the integrity of a signed document, it suffices to re-compute the hash
347
347
  * and verify that it is equal to that in the signature.
348
348
  *
349
- * Among the supported message digest algorithms are:
350
- * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512
351
- * * MD2, MD4, MDC2 and MD5
352
- * * RIPEMD160
353
- * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is
354
- * equal to SHA and DSS1 is equal to SHA1)
349
+ * You can get a list of all digest algorithms supported on your system by
350
+ * running this command in your terminal:
355
351
  *
356
- * For each of these algorithms, there is a sub-class of Digest that
357
- * can be instantiated as simply as e.g.
352
+ * openssl list -digest-algorithms
358
353
  *
359
- * digest = OpenSSL::Digest::SHA1.new
354
+ * Among the OpenSSL 1.1.1 supported message digest algorithms are:
355
+ * * SHA224, SHA256, SHA384, SHA512, SHA512-224 and SHA512-256
356
+ * * SHA3-224, SHA3-256, SHA3-384 and SHA3-512
357
+ * * BLAKE2s256 and BLAKE2b512
360
358
  *
361
- * === Mapping between Digest class and sn/ln
359
+ * Each of these algorithms can be instantiated using the name:
362
360
  *
363
- * The sn (short names) and ln (long names) are defined in
364
- * <openssl/object.h> and <openssl/obj_mac.h>. They are textual
365
- * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest
366
- * algorithm has an OBJECT IDENTIFIER associated to it and those again
367
- * have short/long names assigned to them.
368
- * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its
369
- * sn is "SHA1" and its ln is "sha1".
370
- * ==== MD2
371
- * * sn: MD2
372
- * * ln: md2
373
- * ==== MD4
374
- * * sn: MD4
375
- * * ln: md4
376
- * ==== MD5
377
- * * sn: MD5
378
- * * ln: md5
379
- * ==== SHA
380
- * * sn: SHA
381
- * * ln: SHA
382
- * ==== SHA-1
383
- * * sn: SHA1
384
- * * ln: sha1
385
- * ==== SHA-224
386
- * * sn: SHA224
387
- * * ln: sha224
388
- * ==== SHA-256
389
- * * sn: SHA256
390
- * * ln: sha256
391
- * ==== SHA-384
392
- * * sn: SHA384
393
- * * ln: sha384
394
- * ==== SHA-512
395
- * * sn: SHA512
396
- * * ln: sha512
361
+ * digest = OpenSSL::Digest.new('SHA256')
397
362
  *
398
363
  * "Breaking" a message digest algorithm means defying its one-way
399
364
  * function characteristics, i.e. producing a collision or finding a way
@@ -406,7 +371,7 @@ Init_ossl_digest(void)
406
371
  * === Hashing a file
407
372
  *
408
373
  * data = File.read('document')
409
- * sha256 = OpenSSL::Digest::SHA256.new
374
+ * sha256 = OpenSSL::Digest.new('SHA256')
410
375
  * digest = sha256.digest(data)
411
376
  *
412
377
  * === Hashing several pieces of data at once
@@ -414,7 +379,7 @@ Init_ossl_digest(void)
414
379
  * data1 = File.read('file1')
415
380
  * data2 = File.read('file2')
416
381
  * data3 = File.read('file3')
417
- * sha256 = OpenSSL::Digest::SHA256.new
382
+ * sha256 = OpenSSL::Digest.new('SHA256')
418
383
  * sha256 << data1
419
384
  * sha256 << data2
420
385
  * sha256 << data3
@@ -423,7 +388,7 @@ Init_ossl_digest(void)
423
388
  * === Reuse a Digest instance
424
389
  *
425
390
  * data1 = File.read('file1')
426
- * sha256 = OpenSSL::Digest::SHA256.new
391
+ * sha256 = OpenSSL::Digest.new('SHA256')
427
392
  * digest1 = sha256.digest(data1)
428
393
  *
429
394
  * data2 = File.read('file2')
@@ -93,9 +93,6 @@ static const rb_data_type_t ossl_engine_type = {
93
93
  static VALUE
94
94
  ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
95
95
  {
96
- #if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)
97
- return Qnil;
98
- #else
99
96
  VALUE name;
100
97
 
101
98
  rb_scan_args(argc, argv, "01", &name);
@@ -104,10 +101,10 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
104
101
  return Qtrue;
105
102
  }
106
103
  StringValueCStr(name);
107
- #ifndef OPENSSL_NO_STATIC_ENGINE
108
104
  #if HAVE_ENGINE_LOAD_DYNAMIC
109
105
  OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC);
110
106
  #endif
107
+ #ifndef OPENSSL_NO_STATIC_ENGINE
111
108
  #if HAVE_ENGINE_LOAD_4758CCA
112
109
  OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA);
113
110
  #endif
@@ -144,20 +141,13 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
144
141
  #if HAVE_ENGINE_LOAD_GOST
145
142
  OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST);
146
143
  #endif
144
+ #endif
147
145
  #if HAVE_ENGINE_LOAD_CRYPTODEV
148
146
  OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV);
149
- #endif
150
- #if HAVE_ENGINE_LOAD_AESNI
151
- OSSL_ENGINE_LOAD_IF_MATCH(aesni, AESNI);
152
- #endif
153
- #endif
154
- #ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
155
- OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto, OPENBSD_DEV_CRYPTO);
156
147
  #endif
157
148
  OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL);
158
149
  rb_warning("no such builtin loader for `%"PRIsVALUE"'", name);
159
150
  return Qnil;
160
- #endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
161
151
  }
162
152
 
163
153
  /*
@@ -84,18 +84,12 @@ ossl_hmac_alloc(VALUE klass)
84
84
  *
85
85
  * === A note about comparisons
86
86
  *
87
- * Two instances won't be equal when they're compared, even if they have the
88
- * same value. Use #to_s or #hexdigest to return the authentication code that
89
- * the instance represents. For example:
87
+ * Two instances can be securely compared with #== in constant time:
90
88
  *
91
89
  * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1'))
92
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
93
- * instance
94
- * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
95
- * instance == other_instance
96
- * #=> false
97
- * instance.to_s == other_instance.to_s
98
- * #=> true
90
+ * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f
91
+ * instance == other_instance
92
+ * #=> true
99
93
  *
100
94
  */
101
95
  static VALUE
@@ -359,7 +353,7 @@ Init_ossl_hmac(void)
359
353
  * data1 = File.read("file1")
360
354
  * data2 = File.read("file2")
361
355
  * key = "key"
362
- * digest = OpenSSL::Digest::SHA256.new
356
+ * digest = OpenSSL::Digest.new('SHA256')
363
357
  * hmac = OpenSSL::HMAC.new(key, digest)
364
358
  * hmac << data1
365
359
  * hmac << data2
@@ -272,7 +272,7 @@ Init_ossl_kdf(void)
272
272
  * # store this with the generated value
273
273
  * salt = OpenSSL::Random.random_bytes(16)
274
274
  * iter = 20_000
275
- * hash = OpenSSL::Digest::SHA256.new
275
+ * hash = OpenSSL::Digest.new('SHA256')
276
276
  * len = hash.digest_length
277
277
  * # the final value to be stored
278
278
  * value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter,
@@ -284,24 +284,8 @@ Init_ossl_kdf(void)
284
284
  * Typically, "==" short-circuits on evaluation, and is therefore
285
285
  * vulnerable to timing attacks. The proper way is to use a method that
286
286
  * always takes the same amount of time when comparing two values, thus
287
- * not leaking any information to potential attackers. To compare two
288
- * values, the following could be used:
289
- *
290
- * def eql_time_cmp(a, b)
291
- * unless a.length == b.length
292
- * return false
293
- * end
294
- * cmp = b.bytes
295
- * result = 0
296
- * a.bytes.each_with_index {|c,i|
297
- * result |= c ^ cmp[i]
298
- * }
299
- * result == 0
300
- * end
301
- *
302
- * Please note that the premature return in case of differing lengths
303
- * typically does not leak valuable information - when using PBKDF2, the
304
- * length of the values to be compared is of fixed size.
287
+ * not leaking any information to potential attackers. To do this, use
288
+ * +OpenSSL.fixed_length_secure_compare+.
305
289
  */
306
290
  mKDF = rb_define_module_under(mOSSL, "KDF");
307
291
  /*
@@ -350,7 +350,7 @@ ossl_spki_verify(VALUE self, VALUE key)
350
350
  * spki = OpenSSL::Netscape::SPKI.new
351
351
  * spki.challenge = "RandomChallenge"
352
352
  * spki.public_key = key.public_key
353
- * spki.sign(key, OpenSSL::Digest::SHA256.new)
353
+ * spki.sign(key, OpenSSL::Digest.new('SHA256'))
354
354
  * #send a request containing this to a server generating a certificate
355
355
  * === Verifying an SPKI request
356
356
  * request = #...
@@ -1489,13 +1489,15 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other)
1489
1489
  * call-seq:
1490
1490
  * OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id
1491
1491
  * OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id
1492
+ * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id
1492
1493
  *
1493
1494
  * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and
1494
1495
  * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used
1495
1496
  * to compute the hash values. This defaults to SHA-1.
1496
1497
  *
1497
1498
  * If only one argument is given, decodes it as DER representation of a
1498
- * certificate ID.
1499
+ * certificate ID or generates certificate ID from the object that responds to
1500
+ * the to_der method.
1499
1501
  */
1500
1502
  static VALUE
1501
1503
  ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self)
@@ -1717,7 +1719,7 @@ Init_ossl_ocsp(void)
1717
1719
  * subject certificate so the CA knows which certificate we are asking
1718
1720
  * about:
1719
1721
  *
1720
- * digest = OpenSSL::Digest::SHA1.new
1722
+ * digest = OpenSSL::Digest.new('SHA1')
1721
1723
  * certificate_id =
1722
1724
  * OpenSSL::OCSP::CertificateId.new subject, issuer, digest
1723
1725
  *
@@ -1734,18 +1736,11 @@ Init_ossl_ocsp(void)
1734
1736
  * To submit the request to the CA for verification we need to extract the
1735
1737
  * OCSP URI from the subject certificate:
1736
1738
  *
1737
- * authority_info_access = subject.extensions.find do |extension|
1738
- * extension.oid == 'authorityInfoAccess'
1739
- * end
1740
- *
1741
- * descriptions = authority_info_access.value.split "\n"
1742
- * ocsp = descriptions.find do |description|
1743
- * description.start_with? 'OCSP'
1744
- * end
1739
+ * ocsp_uris = subject.ocsp_uris
1745
1740
  *
1746
1741
  * require 'uri'
1747
1742
  *
1748
- * ocsp_uri = URI ocsp[/URI:(.*)/, 1]
1743
+ * ocsp_uri = URI ocsp_uris[0]
1749
1744
  *
1750
1745
  * To submit the request we'll POST the request to the OCSP URI (per RFC
1751
1746
  * 2560). Note that we only handle HTTP requests and don't handle any
@@ -13,9 +13,9 @@
13
13
 
14
14
  #if !defined(OPENSSL_NO_OCSP)
15
15
  extern VALUE mOCSP;
16
- extern VALUE cOPCSReq;
17
- extern VALUE cOPCSRes;
18
- extern VALUE cOPCSBasicRes;
16
+ extern VALUE cOCSPReq;
17
+ extern VALUE cOCSPRes;
18
+ extern VALUE cOCSPBasicRes;
19
19
  #endif
20
20
 
21
21
  void Init_ossl_ocsp(void);
@@ -9,21 +9,6 @@
9
9
  */
10
10
  #include "ossl.h"
11
11
 
12
- #define NewPKCS7(klass) \
13
- TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
14
- #define SetPKCS7(obj, pkcs7) do { \
15
- if (!(pkcs7)) { \
16
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
17
- } \
18
- RTYPEDDATA_DATA(obj) = (pkcs7); \
19
- } while (0)
20
- #define GetPKCS7(obj, pkcs7) do { \
21
- TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
22
- if (!(pkcs7)) { \
23
- ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
24
- } \
25
- } while (0)
26
-
27
12
  #define NewPKCS7si(klass) \
28
13
  TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0)
29
14
  #define SetPKCS7si(obj, p7si) do { \
@@ -75,7 +60,7 @@ ossl_pkcs7_free(void *ptr)
75
60
  PKCS7_free(ptr);
76
61
  }
77
62
 
78
- static const rb_data_type_t ossl_pkcs7_type = {
63
+ const rb_data_type_t ossl_pkcs7_type = {
79
64
  "OpenSSL/PKCS7",
80
65
  {
81
66
  0, ossl_pkcs7_free,
@@ -803,9 +788,9 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self)
803
788
  BIO *out;
804
789
  VALUE str;
805
790
 
806
- rb_scan_args(argc, argv, "21", &pkey, &cert, &flags);
791
+ rb_scan_args(argc, argv, "12", &pkey, &cert, &flags);
807
792
  key = GetPrivPKeyPtr(pkey); /* NO NEED TO DUP */
808
- x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */
793
+ x509 = NIL_P(cert) ? NULL : GetX509CertPtr(cert); /* NO NEED TO DUP */
809
794
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
810
795
  GetPKCS7(self, p7);
811
796
  if(!(out = BIO_new(BIO_s_mem())))
@@ -1088,7 +1073,6 @@ Init_ossl_pkcs7(void)
1088
1073
  rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc);
1089
1074
  rb_define_method(cPKCS7Signer, "initialize", ossl_pkcs7si_initialize,3);
1090
1075
  rb_define_method(cPKCS7Signer, "issuer", ossl_pkcs7si_get_issuer, 0);
1091
- rb_define_alias(cPKCS7Signer, "name", "issuer");
1092
1076
  rb_define_method(cPKCS7Signer, "serial", ossl_pkcs7si_get_serial,0);
1093
1077
  rb_define_method(cPKCS7Signer,"signed_time",ossl_pkcs7si_get_signed_time,0);
1094
1078
 
@@ -10,6 +10,22 @@
10
10
  #if !defined(_OSSL_PKCS7_H_)
11
11
  #define _OSSL_PKCS7_H_
12
12
 
13
+ #define NewPKCS7(klass) \
14
+ TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0)
15
+ #define SetPKCS7(obj, pkcs7) do { \
16
+ if (!(pkcs7)) { \
17
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
18
+ } \
19
+ RTYPEDDATA_DATA(obj) = (pkcs7); \
20
+ } while (0)
21
+ #define GetPKCS7(obj, pkcs7) do { \
22
+ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \
23
+ if (!(pkcs7)) { \
24
+ ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
25
+ } \
26
+ } while (0)
27
+
28
+ extern const rb_data_type_t ossl_pkcs7_type;
13
29
  extern VALUE cPKCS7;
14
30
  extern VALUE cPKCS7Signer;
15
31
  extern VALUE cPKCS7Recipient;