openssl 2.1.3 → 2.2.0

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 +71 -30
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +42 -40
  6. data/ext/openssl/openssl_missing.h +36 -1
  7. data/ext/openssl/ossl.c +49 -23
  8. data/ext/openssl/ossl.h +7 -4
  9. data/ext/openssl/ossl_asn1.c +25 -0
  10. data/ext/openssl/ossl_bn.c +16 -23
  11. data/ext/openssl/ossl_cipher.c +33 -24
  12. data/ext/openssl/ossl_digest.c +18 -57
  13. data/ext/openssl/ossl_engine.c +2 -12
  14. data/ext/openssl/ossl_hmac.c +5 -11
  15. data/ext/openssl/ossl_kdf.c +3 -19
  16. data/ext/openssl/ossl_ns_spki.c +1 -1
  17. data/ext/openssl/ossl_ocsp.c +6 -11
  18. data/ext/openssl/ossl_ocsp.h +3 -3
  19. data/ext/openssl/ossl_pkcs7.c +3 -19
  20. data/ext/openssl/ossl_pkcs7.h +16 -0
  21. data/ext/openssl/ossl_pkey.c +180 -14
  22. data/ext/openssl/ossl_pkey_dsa.c +2 -2
  23. data/ext/openssl/ossl_pkey_ec.c +37 -8
  24. data/ext/openssl/ossl_pkey_rsa.c +17 -9
  25. data/ext/openssl/ossl_rand.c +2 -32
  26. data/ext/openssl/ossl_ssl.c +78 -72
  27. data/ext/openssl/ossl_ts.c +1514 -0
  28. data/ext/openssl/ossl_ts.h +16 -0
  29. data/ext/openssl/ossl_x509cert.c +2 -2
  30. data/ext/openssl/ossl_x509ext.c +14 -0
  31. data/ext/openssl/ossl_x509name.c +7 -3
  32. data/ext/openssl/ossl_x509store.c +20 -39
  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 +11 -22
  47. data/ext/openssl/deprecation.rb +0 -27
  48. data/ext/openssl/ossl_version.h +0 -15
@@ -167,21 +167,27 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
167
167
  pass = ossl_pem_passwd_value(pass);
168
168
 
169
169
  bio = ossl_obj2bio(&data);
170
- if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
171
- OSSL_BIO_reset(bio);
172
- if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) {
173
- OSSL_BIO_reset(bio);
174
- if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
175
- OSSL_BIO_reset(bio);
176
- pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass);
177
- }
178
- }
179
- }
170
+ if ((pkey = d2i_PrivateKey_bio(bio, NULL)))
171
+ goto ok;
172
+ OSSL_BIO_reset(bio);
173
+ if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
174
+ goto ok;
175
+ OSSL_BIO_reset(bio);
176
+ if ((pkey = d2i_PUBKEY_bio(bio, NULL)))
177
+ goto ok;
178
+ OSSL_BIO_reset(bio);
179
+ /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
180
+ if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass)))
181
+ goto ok;
182
+ OSSL_BIO_reset(bio);
183
+ if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL)))
184
+ goto ok;
180
185
 
181
186
  BIO_free(bio);
182
- if (!pkey)
183
- ossl_raise(ePKeyError, "Could not parse PKey");
187
+ ossl_raise(ePKeyError, "Could not parse PKey");
184
188
 
189
+ ok:
190
+ BIO_free(bio);
185
191
  return ossl_pkey_new(pkey);
186
192
  }
187
193
 
@@ -293,6 +299,160 @@ ossl_pkey_initialize(VALUE self)
293
299
  return self;
294
300
  }
295
301
 
302
+ /*
303
+ * call-seq:
304
+ * pkey.oid -> string
305
+ *
306
+ * Returns the short name of the OID associated with _pkey_.
307
+ */
308
+ static VALUE
309
+ ossl_pkey_oid(VALUE self)
310
+ {
311
+ EVP_PKEY *pkey;
312
+ int nid;
313
+
314
+ GetPKey(self, pkey);
315
+ nid = EVP_PKEY_id(pkey);
316
+ return rb_str_new_cstr(OBJ_nid2sn(nid));
317
+ }
318
+
319
+ /*
320
+ * call-seq:
321
+ * pkey.inspect -> string
322
+ *
323
+ * Returns a string describing the PKey object.
324
+ */
325
+ static VALUE
326
+ ossl_pkey_inspect(VALUE self)
327
+ {
328
+ EVP_PKEY *pkey;
329
+ int nid;
330
+
331
+ GetPKey(self, pkey);
332
+ nid = EVP_PKEY_id(pkey);
333
+ return rb_sprintf("#<%"PRIsVALUE":%p oid=%s>",
334
+ rb_class_name(CLASS_OF(self)), (void *)self,
335
+ OBJ_nid2sn(nid));
336
+ }
337
+
338
+ static VALUE
339
+ do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der)
340
+ {
341
+ EVP_PKEY *pkey;
342
+ VALUE cipher, pass;
343
+ const EVP_CIPHER *enc = NULL;
344
+ BIO *bio;
345
+
346
+ GetPKey(self, pkey);
347
+ rb_scan_args(argc, argv, "02", &cipher, &pass);
348
+ if (argc > 0) {
349
+ /*
350
+ * TODO: EncryptedPrivateKeyInfo actually has more options.
351
+ * Should they be exposed?
352
+ */
353
+ enc = ossl_evp_get_cipherbyname(cipher);
354
+ pass = ossl_pem_passwd_value(pass);
355
+ }
356
+
357
+ bio = BIO_new(BIO_s_mem());
358
+ if (!bio)
359
+ ossl_raise(ePKeyError, "BIO_new");
360
+ if (to_der) {
361
+ if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0,
362
+ ossl_pem_passwd_cb, (void *)pass)) {
363
+ BIO_free(bio);
364
+ ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio");
365
+ }
366
+ }
367
+ else {
368
+ if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0,
369
+ ossl_pem_passwd_cb, (void *)pass)) {
370
+ BIO_free(bio);
371
+ ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey");
372
+ }
373
+ }
374
+ return ossl_membio2str(bio);
375
+ }
376
+
377
+ /*
378
+ * call-seq:
379
+ * pkey.private_to_der -> string
380
+ * pkey.private_to_der(cipher, password) -> string
381
+ *
382
+ * Serializes the private key to DER-encoded PKCS #8 format. If called without
383
+ * arguments, unencrypted PKCS #8 PrivateKeyInfo format is used. If called with
384
+ * a cipher name and a password, PKCS #8 EncryptedPrivateKeyInfo format with
385
+ * PBES2 encryption scheme is used.
386
+ */
387
+ static VALUE
388
+ ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self)
389
+ {
390
+ return do_pkcs8_export(argc, argv, self, 1);
391
+ }
392
+
393
+ /*
394
+ * call-seq:
395
+ * pkey.private_to_pem -> string
396
+ * pkey.private_to_pem(cipher, password) -> string
397
+ *
398
+ * Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der
399
+ * for more details.
400
+ */
401
+ static VALUE
402
+ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
403
+ {
404
+ return do_pkcs8_export(argc, argv, self, 0);
405
+ }
406
+
407
+ static VALUE
408
+ do_spki_export(VALUE self, int to_der)
409
+ {
410
+ EVP_PKEY *pkey;
411
+ BIO *bio;
412
+
413
+ GetPKey(self, pkey);
414
+ bio = BIO_new(BIO_s_mem());
415
+ if (!bio)
416
+ ossl_raise(ePKeyError, "BIO_new");
417
+ if (to_der) {
418
+ if (!i2d_PUBKEY_bio(bio, pkey)) {
419
+ BIO_free(bio);
420
+ ossl_raise(ePKeyError, "i2d_PUBKEY_bio");
421
+ }
422
+ }
423
+ else {
424
+ if (!PEM_write_bio_PUBKEY(bio, pkey)) {
425
+ BIO_free(bio);
426
+ ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY");
427
+ }
428
+ }
429
+ return ossl_membio2str(bio);
430
+ }
431
+
432
+ /*
433
+ * call-seq:
434
+ * pkey.public_to_der -> string
435
+ *
436
+ * Serializes the public key to DER-encoded X.509 SubjectPublicKeyInfo format.
437
+ */
438
+ static VALUE
439
+ ossl_pkey_public_to_der(VALUE self)
440
+ {
441
+ return do_spki_export(self, 1);
442
+ }
443
+
444
+ /*
445
+ * call-seq:
446
+ * pkey.public_to_pem -> string
447
+ *
448
+ * Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format.
449
+ */
450
+ static VALUE
451
+ ossl_pkey_public_to_pem(VALUE self)
452
+ {
453
+ return do_spki_export(self, 0);
454
+ }
455
+
296
456
  /*
297
457
  * call-seq:
298
458
  * pkey.sign(digest, data) -> String
@@ -306,7 +466,7 @@ ossl_pkey_initialize(VALUE self)
306
466
  *
307
467
  * == Example
308
468
  * data = 'Sign me!'
309
- * digest = OpenSSL::Digest::SHA256.new
469
+ * digest = OpenSSL::Digest.new('SHA256')
310
470
  * pkey = OpenSSL::PKey::RSA.new(2048)
311
471
  * signature = pkey.sign(digest, data)
312
472
  */
@@ -360,7 +520,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
360
520
  *
361
521
  * == Example
362
522
  * data = 'Sign me!'
363
- * digest = OpenSSL::Digest::SHA256.new
523
+ * digest = OpenSSL::Digest.new('SHA256')
364
524
  * pkey = OpenSSL::PKey::RSA.new(2048)
365
525
  * signature = pkey.sign(digest, data)
366
526
  * pub_key = pkey.public_key
@@ -491,6 +651,12 @@ Init_ossl_pkey(void)
491
651
 
492
652
  rb_define_alloc_func(cPKey, ossl_pkey_alloc);
493
653
  rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
654
+ rb_define_method(cPKey, "oid", ossl_pkey_oid, 0);
655
+ rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0);
656
+ rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1);
657
+ rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1);
658
+ rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0);
659
+ rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0);
494
660
 
495
661
  rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
496
662
  rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
@@ -513,7 +513,7 @@ ossl_dsa_to_public_key(VALUE self)
513
513
  * === Example
514
514
  * dsa = OpenSSL::PKey::DSA.new(2048)
515
515
  * doc = "Sign me"
516
- * digest = OpenSSL::Digest::SHA1.digest(doc)
516
+ * digest = OpenSSL::Digest.digest('SHA1', doc)
517
517
  * sig = dsa.syssign(digest)
518
518
  *
519
519
  *
@@ -558,7 +558,7 @@ ossl_dsa_sign(VALUE self, VALUE data)
558
558
  * === Example
559
559
  * dsa = OpenSSL::PKey::DSA.new(2048)
560
560
  * doc = "Sign me"
561
- * digest = OpenSSL::Digest::SHA1.digest(doc)
561
+ * digest = OpenSSL::Digest.digest('SHA1', doc)
562
562
  * sig = dsa.syssign(digest)
563
563
  * puts dsa.sysverify(digest, sig) # => true
564
564
  *
@@ -653,15 +653,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
653
653
  StringValue(data);
654
654
  StringValue(sig);
655
655
 
656
- switch (ECDSA_verify(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
657
- (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), ec)) {
658
- case 1:
659
- return Qtrue;
660
- case 0:
661
- return Qfalse;
662
- default:
663
- ossl_raise(eECError, "ECDSA_verify");
656
+ switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
657
+ case 1: return Qtrue;
658
+ case 0: return Qfalse;
659
+ default: break;
664
660
  }
661
+
662
+ ossl_raise(eECError, "ECDSA_verify");
663
+
664
+ UNREACHABLE;
665
665
  }
666
666
 
667
667
  /*
@@ -1562,6 +1562,34 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form)
1562
1562
  return str;
1563
1563
  }
1564
1564
 
1565
+ /*
1566
+ * call-seq:
1567
+ * point.add(point) => point
1568
+ *
1569
+ * Performs elliptic curve point addition.
1570
+ */
1571
+ static VALUE ossl_ec_point_add(VALUE self, VALUE other)
1572
+ {
1573
+ EC_POINT *point_self, *point_other, *point_result;
1574
+ const EC_GROUP *group;
1575
+ VALUE group_v = rb_attr_get(self, id_i_group);
1576
+ VALUE result;
1577
+
1578
+ GetECPoint(self, point_self);
1579
+ GetECPoint(other, point_other);
1580
+ GetECGroup(group_v, group);
1581
+
1582
+ result = rb_obj_alloc(cEC_POINT);
1583
+ ossl_ec_point_initialize(1, &group_v, result);
1584
+ GetECPoint(result, point_result);
1585
+
1586
+ if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) {
1587
+ ossl_raise(eEC_POINT, "EC_POINT_add");
1588
+ }
1589
+
1590
+ return result;
1591
+ }
1592
+
1565
1593
  /*
1566
1594
  * call-seq:
1567
1595
  * point.mul(bn1 [, bn2]) => point
@@ -1786,6 +1814,7 @@ void Init_ossl_ec(void)
1786
1814
  /* all the other methods */
1787
1815
 
1788
1816
  rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1);
1817
+ rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1);
1789
1818
  rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
1790
1819
 
1791
1820
  id_i_group = rb_intern("@group");
@@ -26,10 +26,10 @@
26
26
  static inline int
27
27
  RSA_HAS_PRIVATE(RSA *rsa)
28
28
  {
29
- const BIGNUM *p, *q;
29
+ const BIGNUM *e, *d;
30
30
 
31
- RSA_get0_factors(rsa, &p, &q);
32
- return p && q; /* d? why? */
31
+ RSA_get0_key(rsa, NULL, &e, &d);
32
+ return e && d;
33
33
  }
34
34
 
35
35
  static inline int
@@ -341,6 +341,7 @@ static VALUE
341
341
  ossl_rsa_export(int argc, VALUE *argv, VALUE self)
342
342
  {
343
343
  RSA *rsa;
344
+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
344
345
  BIO *out;
345
346
  const EVP_CIPHER *ciph = NULL;
346
347
  VALUE cipher, pass, str;
@@ -356,7 +357,10 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
356
357
  if (!(out = BIO_new(BIO_s_mem()))) {
357
358
  ossl_raise(eRSAError, NULL);
358
359
  }
359
- if (RSA_HAS_PRIVATE(rsa)) {
360
+ RSA_get0_key(rsa, &n, &e, &d);
361
+ RSA_get0_factors(rsa, &p, &q);
362
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
363
+ if (n && e && d && p && q && dmp1 && dmq1 && iqmp) {
360
364
  if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
361
365
  ossl_pem_passwd_cb, (void *)pass)) {
362
366
  BIO_free(out);
@@ -383,23 +387,27 @@ static VALUE
383
387
  ossl_rsa_to_der(VALUE self)
384
388
  {
385
389
  RSA *rsa;
390
+ const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp;
386
391
  int (*i2d_func)(const RSA *, unsigned char **);
387
- unsigned char *p;
392
+ unsigned char *ptr;
388
393
  long len;
389
394
  VALUE str;
390
395
 
391
396
  GetRSA(self, rsa);
392
- if (RSA_HAS_PRIVATE(rsa))
397
+ RSA_get0_key(rsa, &n, &e, &d);
398
+ RSA_get0_factors(rsa, &p, &q);
399
+ RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
400
+ if (n && e && d && p && q && dmp1 && dmq1 && iqmp)
393
401
  i2d_func = i2d_RSAPrivateKey;
394
402
  else
395
403
  i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY;
396
404
  if((len = i2d_func(rsa, NULL)) <= 0)
397
405
  ossl_raise(eRSAError, NULL);
398
406
  str = rb_str_new(0, len);
399
- p = (unsigned char *)RSTRING_PTR(str);
400
- if(i2d_func(rsa, &p) < 0)
407
+ ptr = (unsigned char *)RSTRING_PTR(str);
408
+ if(i2d_func(rsa, &ptr) < 0)
401
409
  ossl_raise(eRSAError, NULL);
402
- ossl_str_adjust(str, p);
410
+ ossl_str_adjust(str, ptr);
403
411
 
404
412
  return str;
405
413
  }
@@ -120,36 +120,6 @@ ossl_rand_bytes(VALUE self, VALUE len)
120
120
  return str;
121
121
  }
122
122
 
123
- #if defined(HAVE_RAND_PSEUDO_BYTES)
124
- /*
125
- * call-seq:
126
- * pseudo_bytes(length) -> string
127
- *
128
- * Generates a String with _length_ number of pseudo-random bytes.
129
- *
130
- * Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if
131
- * they are of sufficient length, but are not necessarily unpredictable.
132
- *
133
- * === Example
134
- *
135
- * OpenSSL::Random.pseudo_bytes(12)
136
- * #=> "..."
137
- */
138
- static VALUE
139
- ossl_rand_pseudo_bytes(VALUE self, VALUE len)
140
- {
141
- VALUE str;
142
- int n = NUM2INT(len);
143
-
144
- str = rb_str_new(0, n);
145
- if (RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n) < 1) {
146
- ossl_raise(eRandomError, NULL);
147
- }
148
-
149
- return str;
150
- }
151
- #endif
152
-
153
123
  #ifdef HAVE_RAND_EGD
154
124
  /*
155
125
  * call-seq:
@@ -219,8 +189,8 @@ Init_ossl_rand(void)
219
189
  rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1);
220
190
  rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1);
221
191
  rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1);
222
- #if defined(HAVE_RAND_PSEUDO_BYTES)
223
- rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1);
192
+ #if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER)
193
+ rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes");
224
194
  #endif
225
195
  #ifdef HAVE_RAND_EGD
226
196
  rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1);