openssl 2.1.4 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +9 -7
  3. data/History.md +68 -37
  4. data/README.md +2 -2
  5. data/ext/openssl/extconf.rb +43 -41
  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 +13 -24
  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);