rubysl-openssl 2.8.0 → 2.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 19d9a8d2e82e570750764173c6e7e693d066876f
4
- data.tar.gz: ab7845b7a5181cb1b27d0ed567da460e972824fc
3
+ metadata.gz: 13acecc541e3c578d87adc0933287a23cf2cde35
4
+ data.tar.gz: 50cbbb8481c72db5eb8253c58bcb44a562fc9ebb
5
5
  SHA512:
6
- metadata.gz: 618fb5415ed6cd7e2dc730c44c010931679397e7179cdcaee26ea59fe1fca1149fd0f4b61b1aefdb3ed0a2b7bf3b505dfd85dca0a3702bc054f274b3595a74f7
7
- data.tar.gz: 88fe2cca8e0c251b3a3bc75b5619f1196e8b4b87d0f082775f627ef228970bd6385dde5dc7a2de24d076c219039cdb0c969039d6ebbb8653cbebc470ad5d81bc
6
+ metadata.gz: e426ad35e4100cf8e9f08d3d5eff5d755b32553135cabd91ddcf5d8fba047bd3a1fbd3547a7712f8b43a3ea61dae452d3d423676bafbbb8da24e1090fa5bc1a5
7
+ data.tar.gz: 46c0c561af85f5c8ba06b3a457be95e07fd5e4be8f5ce0091dd824bdba1c7c5e717cb0c95b8201b8d557776837d0f94a5424dc52aa875c2026c6b1cfa63c6b96
@@ -29,8 +29,9 @@ ossl_obj2bio(VALUE obj)
29
29
  }
30
30
  rb_update_max_fd(fd);
31
31
  if (!(fp = fdopen(fd, "r"))){
32
+ int e = errno;
32
33
  close(fd);
33
- rb_sys_fail(0);
34
+ rb_syserr_fail(e, 0);
34
35
  }
35
36
  if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
36
37
  fclose(fp);
@@ -82,8 +82,8 @@ ossl_bn_new(const BIGNUM *bn)
82
82
  return obj;
83
83
  }
84
84
 
85
- BIGNUM *
86
- GetBNPtr(VALUE obj)
85
+ static BIGNUM *
86
+ try_convert_to_bnptr(VALUE obj)
87
87
  {
88
88
  BIGNUM *bn = NULL;
89
89
  VALUE newobj;
@@ -100,14 +100,20 @@ GetBNPtr(VALUE obj)
100
100
  }
101
101
  SetBN(newobj, bn); /* Handle potencial mem leaks */
102
102
  break;
103
- case T_NIL:
104
- break;
105
- default:
106
- ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
107
103
  }
108
104
  return bn;
109
105
  }
110
106
 
107
+ BIGNUM *
108
+ GetBNPtr(VALUE obj)
109
+ {
110
+ BIGNUM *bn = try_convert_to_bnptr(obj);
111
+ if (!bn)
112
+ ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
113
+
114
+ return bn;
115
+ }
116
+
111
117
  /*
112
118
  * Private
113
119
  */
@@ -841,20 +847,77 @@ BIGNUM_CMP(ucmp)
841
847
 
842
848
  /*
843
849
  * call-seq:
844
- * big.eql?(obj) => true or false
850
+ * bn == obj => true or false
845
851
  *
846
- * Returns <code>true</code> only if <i>obj</i> is a
847
- * <code>Bignum</code> with the same value as <i>big</i>. Contrast this
852
+ * Returns +true+ only if +obj+ has the same value as +bn+. Contrast this
853
+ * with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
848
854
  */
849
855
  static VALUE
850
- ossl_bn_eql(VALUE self, VALUE other)
856
+ ossl_bn_eq(VALUE self, VALUE other)
851
857
  {
852
- if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
858
+ BIGNUM *bn1, *bn2;
859
+
860
+ GetBN(self, bn1);
861
+ /* BNPtr may raise, so we can't use here */
862
+ bn2 = try_convert_to_bnptr(other);
863
+
864
+ if (bn2 && !BN_cmp(bn1, bn2)) {
853
865
  return Qtrue;
854
866
  }
855
867
  return Qfalse;
856
868
  }
857
869
 
870
+ /*
871
+ * call-seq:
872
+ * bn.eql?(obj) => true or false
873
+ *
874
+ * Returns <code>true</code> only if <i>obj</i> is a
875
+ * <code>OpenSSL::BN</code> with the same value as <i>big</i>. Contrast this
876
+ * with OpenSSL::BN#==, which performs type conversions.
877
+ */
878
+ static VALUE
879
+ ossl_bn_eql(VALUE self, VALUE other)
880
+ {
881
+ BIGNUM *bn1, *bn2;
882
+
883
+ if (!rb_obj_is_kind_of(other, cBN))
884
+ return Qfalse;
885
+ GetBN(self, bn1);
886
+ GetBN(other, bn2);
887
+
888
+ return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
889
+ }
890
+
891
+ /*
892
+ * call-seq:
893
+ * bn.hash => Integer
894
+ *
895
+ * Returns a hash code for this object.
896
+ *
897
+ * See also Object#hash.
898
+ */
899
+ static VALUE
900
+ ossl_bn_hash(VALUE self)
901
+ {
902
+ BIGNUM *bn;
903
+ VALUE hash;
904
+ unsigned char *buf;
905
+ int len;
906
+
907
+ GetBN(self, bn);
908
+ len = BN_num_bytes(bn);
909
+ buf = xmalloc(len);
910
+ if (BN_bn2bin(bn, buf) != len) {
911
+ xfree(buf);
912
+ ossl_raise(eBNError, NULL);
913
+ }
914
+
915
+ hash = INT2FIX(rb_memhash(buf, len));
916
+ xfree(buf);
917
+
918
+ return hash;
919
+ }
920
+
858
921
  /*
859
922
  * call-seq:
860
923
  * bn.prime? => true | false
@@ -982,8 +1045,9 @@ Init_ossl_bn(void)
982
1045
  rb_define_alias(cBN, "<=>", "cmp");
983
1046
  rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
984
1047
  rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
985
- rb_define_alias(cBN, "==", "eql?");
986
- rb_define_alias(cBN, "===", "eql?");
1048
+ rb_define_method(cBN, "hash", ossl_bn_hash, 0);
1049
+ rb_define_method(cBN, "==", ossl_bn_eq, 1);
1050
+ rb_define_alias(cBN, "===", "==");
987
1051
  rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
988
1052
  rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
989
1053
  /* is_word */
@@ -26,13 +26,13 @@ VALUE eConfigError;
26
26
  */
27
27
 
28
28
  /*
29
- * GetConfigPtr is a public C-level function for getting OpenSSL CONF struct
29
+ * DupConfigPtr is a public C-level function for getting OpenSSL CONF struct
30
30
  * from an OpenSSL::Config(eConfig) instance. We decided to implement
31
31
  * OpenSSL::Config in Ruby level but we need to pass native CONF struct for
32
32
  * some OpenSSL features such as X509V3_EXT_*.
33
33
  */
34
34
  CONF *
35
- GetConfigPtr(VALUE obj)
35
+ DupConfigPtr(VALUE obj)
36
36
  {
37
37
  CONF *conf;
38
38
  VALUE str;
@@ -50,9 +50,10 @@ GetConfigPtr(VALUE obj)
50
50
  if(!NCONF_load_bio(conf, bio, &eline)){
51
51
  BIO_free(bio);
52
52
  NCONF_free(conf);
53
- if (eline <= 0) ossl_raise(eConfigError, "wrong config format");
54
- else ossl_raise(eConfigError, "error in line %d", eline);
55
- ossl_raise(eConfigError, NULL);
53
+ if (eline <= 0)
54
+ ossl_raise(eConfigError, "wrong config format");
55
+ else
56
+ ossl_raise(eConfigError, "error in line %d", eline);
56
57
  }
57
58
  BIO_free(bio);
58
59
 
@@ -271,12 +271,17 @@ static VALUE
271
271
  ossl_ocspreq_add_certid(VALUE self, VALUE certid)
272
272
  {
273
273
  OCSP_REQUEST *req;
274
- OCSP_CERTID *id;
274
+ OCSP_CERTID *id, *id_new;
275
275
 
276
276
  GetOCSPReq(self, req);
277
277
  GetOCSPCertId(certid, id);
278
- if(!OCSP_request_add0_id(req, OCSP_CERTID_dup(id)))
279
- ossl_raise(eOCSPError, NULL);
278
+
279
+ if (!(id_new = OCSP_CERTID_dup(id)))
280
+ ossl_raise(eOCSPError, "OCSP_CERTID_dup");
281
+ if (!OCSP_request_add0_id(req, id_new)) {
282
+ OCSP_CERTID_free(id_new);
283
+ ossl_raise(eOCSPError, "OCSP_request_add0_id");
284
+ }
280
285
 
281
286
  return self;
282
287
  }
@@ -104,7 +104,6 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
104
104
  friendlyname = NIL_P(name) ? NULL : StringValuePtr(name);
105
105
  key = GetPKeyPtr(pkey);
106
106
  x509 = GetX509CertPtr(cert);
107
- x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
108
107
  /* TODO: make a VALUE to nid function */
109
108
  if (!NIL_P(key_nid)) {
110
109
  if ((nkey = OBJ_txt2nid(StringValuePtr(key_nid))) == NID_undef)
@@ -122,6 +121,7 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self)
122
121
  ktype = NUM2INT(keytype);
123
122
 
124
123
  obj = NewPKCS12(cPKCS12);
124
+ x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca);
125
125
  p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s,
126
126
  nkey, ncert, kiter, miter, ktype);
127
127
  sk_X509_pop_free(x509s, X509_free);
@@ -165,8 +165,12 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
165
165
  BIO_free(in);
166
166
 
167
167
  pkey = cert = ca = Qnil;
168
+ /* OpenSSL's bug; PKCS12_parse() puts errors even if it succeeds.
169
+ * Fixed in OpenSSL 1.0.0t, 1.0.1p, 1.0.2d */
170
+ ERR_set_mark();
168
171
  if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s))
169
172
  ossl_raise(ePKCS12Error, "PKCS12_parse");
173
+ ERR_pop_to_mark();
170
174
  pkey = rb_protect((VALUE(*)_((VALUE)))ossl_pkey_new, (VALUE)key,
171
175
  &st); /* NO DUP */
172
176
  if(st) goto err;
@@ -755,7 +755,9 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
755
755
  VALUE data;
756
756
  const char *msg;
757
757
 
758
+ GetPKCS7(self, p7);
758
759
  rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags);
760
+ x509st = GetX509StorePtr(store);
759
761
  flg = NIL_P(flags) ? 0 : NUM2INT(flags);
760
762
  if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self);
761
763
  in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);
@@ -767,8 +769,6 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
767
769
  rb_jump_tag(status);
768
770
  }
769
771
  }
770
- x509st = GetX509StorePtr(store);
771
- GetPKCS7(self, p7);
772
772
  if(!(out = BIO_new(BIO_s_mem()))){
773
773
  BIO_free(in);
774
774
  sk_X509_pop_free(x509s, X509_free);
@@ -776,13 +776,13 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
776
776
  }
777
777
  ok = PKCS7_verify(p7, x509s, x509st, in, out, flg);
778
778
  BIO_free(in);
779
- if (ok < 0) ossl_raise(ePKCS7Error, NULL);
779
+ sk_X509_pop_free(x509s, X509_free);
780
+ if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify");
780
781
  msg = ERR_reason_error_string(ERR_get_error());
781
782
  ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
782
783
  ERR_clear_error();
783
784
  data = ossl_membio2str(out);
784
785
  ossl_pkcs7_set_data(self, data);
785
- sk_X509_pop_free(x509s, X509_free);
786
786
 
787
787
  return (ok == 1) ? Qtrue : Qfalse;
788
788
  }
@@ -822,12 +822,12 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
822
822
  char buf[4096];
823
823
  int len;
824
824
 
825
- in = ossl_obj2bio(data);
826
825
  GetPKCS7(self, pkcs7);
827
826
  if(PKCS7_type_is_signed(pkcs7)){
828
827
  if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
829
828
  ossl_raise(ePKCS7Error, NULL);
830
829
  }
830
+ in = ossl_obj2bio(data);
831
831
  if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
832
832
  for(;;){
833
833
  if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
@@ -839,7 +839,7 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
839
839
  ossl_pkcs7_set_data(self, Qnil);
840
840
 
841
841
  err:
842
- BIO_free(out);
842
+ BIO_free_all(out);
843
843
  BIO_free(in);
844
844
  if(ERR_peek_error()){
845
845
  ossl_raise(ePKCS7Error, NULL);
@@ -506,6 +506,8 @@ ossl_dh_compute_key(VALUE self, VALUE pub)
506
506
 
507
507
  GetPKeyDH(self, pkey);
508
508
  dh = pkey->pkey.dh;
509
+ if (!dh->p)
510
+ ossl_raise(eDHError, "incomplete DH");
509
511
  pub_key = GetBNPtr(pub);
510
512
  len = DH_size(dh);
511
513
  str = rb_str_new(0, len);
@@ -498,10 +498,11 @@ ossl_dsa_sign(VALUE self, VALUE data)
498
498
  VALUE str;
499
499
 
500
500
  GetPKeyDSA(self, pkey);
501
- StringValue(data);
502
- if (!DSA_PRIVATE(self, pkey->pkey.dsa)) {
501
+ if (!pkey->pkey.dsa->q)
502
+ ossl_raise(eDSAError, "incomplete DSA");
503
+ if (!DSA_PRIVATE(self, pkey->pkey.dsa))
503
504
  ossl_raise(eDSAError, "Private DSA key needed!");
504
- }
505
+ StringValue(data);
505
506
  str = rb_str_new(0, ossl_dsa_buf_size(pkey));
506
507
  if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
507
508
  (unsigned char *)RSTRING_PTR(str),
@@ -475,6 +475,7 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
475
475
  int private = 0;
476
476
  char *password = NULL;
477
477
  VALUE str;
478
+ const EVP_CIPHER *cipher = NULL;
478
479
 
479
480
  Require_EC_KEY(self, ec);
480
481
 
@@ -487,25 +488,22 @@ static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int forma
487
488
  if (EC_KEY_get0_private_key(ec))
488
489
  private = 1;
489
490
 
491
+ if (!NIL_P(ciph)) {
492
+ cipher = GetCipherPtr(ciph);
493
+ if (!NIL_P(pass)) {
494
+ StringValue(pass);
495
+ if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
496
+ ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
497
+ password = RSTRING_PTR(pass);
498
+ }
499
+ }
500
+
490
501
  if (!(out = BIO_new(BIO_s_mem())))
491
502
  ossl_raise(eECError, "BIO_new(BIO_s_mem())");
492
503
 
493
504
  switch(format) {
494
505
  case EXPORT_PEM:
495
506
  if (private) {
496
- const EVP_CIPHER *cipher;
497
- if (!NIL_P(ciph)) {
498
- cipher = GetCipherPtr(ciph);
499
- if (!NIL_P(pass)) {
500
- StringValue(pass);
501
- if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
502
- ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
503
- password = RSTRING_PTR(pass);
504
- }
505
- }
506
- else {
507
- cipher = NULL;
508
- }
509
507
  i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
510
508
  } else {
511
509
  i = PEM_write_bio_EC_PUBKEY(out, ec);
@@ -391,6 +391,8 @@ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
391
391
  VALUE str, buffer, padding;
392
392
 
393
393
  GetPKeyRSA(self, pkey);
394
+ if (!pkey->pkey.rsa->n)
395
+ ossl_raise(eRSAError, "incomplete RSA");
394
396
  rb_scan_args(argc, argv, "11", &buffer, &padding);
395
397
  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
396
398
  StringValue(buffer);
@@ -420,6 +422,8 @@ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
420
422
  VALUE str, buffer, padding;
421
423
 
422
424
  GetPKeyRSA(self, pkey);
425
+ if (!pkey->pkey.rsa->n)
426
+ ossl_raise(eRSAError, "incomplete RSA");
423
427
  rb_scan_args(argc, argv, "11", &buffer, &padding);
424
428
  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
425
429
  StringValue(buffer);
@@ -449,9 +453,10 @@ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
449
453
  VALUE str, buffer, padding;
450
454
 
451
455
  GetPKeyRSA(self, pkey);
452
- if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
453
- ossl_raise(eRSAError, "private key needed.");
454
- }
456
+ if (!pkey->pkey.rsa->n)
457
+ ossl_raise(eRSAError, "incomplete RSA");
458
+ if (!RSA_PRIVATE(self, pkey->pkey.rsa))
459
+ ossl_raise(eRSAError, "private key needed");
455
460
  rb_scan_args(argc, argv, "11", &buffer, &padding);
456
461
  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
457
462
  StringValue(buffer);
@@ -481,9 +486,10 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
481
486
  VALUE str, buffer, padding;
482
487
 
483
488
  GetPKeyRSA(self, pkey);
484
- if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
485
- ossl_raise(eRSAError, "private key needed.");
486
- }
489
+ if (!pkey->pkey.rsa->n)
490
+ ossl_raise(eRSAError, "incomplete RSA");
491
+ if (!RSA_PRIVATE(self, pkey->pkey.rsa))
492
+ ossl_raise(eRSAError, "private key needed");
487
493
  rb_scan_args(argc, argv, "11", &buffer, &padding);
488
494
  pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
489
495
  StringValue(buffer);
@@ -544,7 +544,7 @@ ssl_renegotiation_cb(const SSL *ssl)
544
544
  (void) rb_funcall(cb, rb_intern("call"), 1, ssl_obj);
545
545
  }
546
546
 
547
- #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
547
+ #if defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) || defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB)
548
548
  static VALUE
549
549
  ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded)
550
550
  {
@@ -568,18 +568,6 @@ ssl_encode_npn_protocols(VALUE protocols)
568
568
  return encoded;
569
569
  }
570
570
 
571
- static int
572
- ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
573
- {
574
- VALUE sslctx_obj = (VALUE) arg;
575
- VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
576
-
577
- *out = (const unsigned char *) RSTRING_PTR(protocols);
578
- *outlen = RSTRING_LENINT(protocols);
579
-
580
- return SSL_TLSEXT_ERR_OK;
581
- }
582
-
583
571
  static int
584
572
  ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen)
585
573
  {
@@ -609,6 +597,19 @@ ssl_npn_select_cb_common(VALUE cb, const unsigned char **out, unsigned char *out
609
597
  return SSL_TLSEXT_ERR_OK;
610
598
  }
611
599
 
600
+ #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
601
+ static int
602
+ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, void *arg)
603
+ {
604
+ VALUE sslctx_obj = (VALUE) arg;
605
+ VALUE protocols = rb_iv_get(sslctx_obj, "@_protocols");
606
+
607
+ *out = (const unsigned char *) RSTRING_PTR(protocols);
608
+ *outlen = RSTRING_LENINT(protocols);
609
+
610
+ return SSL_TLSEXT_ERR_OK;
611
+ }
612
+
612
613
  static int
613
614
  ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
614
615
  {
@@ -619,6 +620,7 @@ ssl_npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen, const unsi
619
620
 
620
621
  return ssl_npn_select_cb_common(cb, (const unsigned char **)out, outlen, in, inlen);
621
622
  }
623
+ #endif
622
624
 
623
625
  #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
624
626
  static int
@@ -632,8 +634,7 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, c
632
634
  return ssl_npn_select_cb_common(cb, out, outlen, in, inlen);
633
635
  }
634
636
  #endif
635
-
636
- #endif
637
+ #endif /* HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB || HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
637
638
 
638
639
  /* This function may serve as the entry point to support further
639
640
  * callbacks. */
@@ -687,8 +688,8 @@ ossl_sslctx_set_options(VALUE self, VALUE options)
687
688
  * ctx.setup => nil # thereafter
688
689
  *
689
690
  * This method is called automatically when a new SSLSocket is created.
690
- * Normally you do not need to call this method (unless you are writing an
691
- * extension in C).
691
+ * However, it is not thread-safe and must be called before creating
692
+ * SSLSocket objects in a multi-threaded program.
692
693
  */
693
694
  static VALUE
694
695
  ossl_sslctx_setup(VALUE self)
@@ -793,7 +794,7 @@ ossl_sslctx_setup(VALUE self)
793
794
  val = ossl_sslctx_get_verify_dep(self);
794
795
  if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val));
795
796
 
796
- #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
797
+ #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
797
798
  val = rb_iv_get(self, "@npn_protocols");
798
799
  if (!NIL_P(val)) {
799
800
  rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
@@ -806,7 +807,7 @@ ossl_sslctx_setup(VALUE self)
806
807
  }
807
808
  #endif
808
809
 
809
- #ifdef HAVE_SSL_CTX_SET_ALPN_PROTOS
810
+ #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
810
811
  val = rb_iv_get(self, "@alpn_protocols");
811
812
  if (!NIL_P(val)) {
812
813
  VALUE rprotos = ssl_encode_npn_protocols(val);
@@ -1532,7 +1533,13 @@ ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts)
1532
1533
 
1533
1534
  if (ssl) {
1534
1535
  for (;;){
1535
- nwrite = SSL_write(ssl, RSTRING_PTR(str), RSTRING_LENINT(str));
1536
+ int num = RSTRING_LENINT(str);
1537
+
1538
+ /* SSL_write(3ssl) manpage states num == 0 is undefined */
1539
+ if (num == 0)
1540
+ goto end;
1541
+
1542
+ nwrite = SSL_write(ssl, RSTRING_PTR(str), num);
1536
1543
  switch(ssl_get_error(ssl, nwrite)){
1537
1544
  case SSL_ERROR_NONE:
1538
1545
  goto end;
@@ -1596,23 +1603,17 @@ ossl_ssl_write_nonblock(int argc, VALUE *argv, VALUE self)
1596
1603
  * call-seq:
1597
1604
  * ssl.stop => nil
1598
1605
  *
1599
- * Stops the SSL connection and prepares it for another connection.
1606
+ * Sends "close notify" to the peer and tries to shut down the SSL connection
1607
+ * gracefully.
1600
1608
  */
1601
1609
  static VALUE
1602
1610
  ossl_ssl_stop(VALUE self)
1603
1611
  {
1604
1612
  SSL *ssl;
1605
1613
 
1606
- /* ossl_ssl_data_get_struct() is not usable here because it may return
1607
- * from this function; */
1608
-
1609
- GetSSL(self, ssl);
1614
+ ossl_ssl_data_get_struct(self, ssl);
1610
1615
 
1611
- if (ssl) {
1612
- ossl_ssl_shutdown(ssl);
1613
- SSL_free(ssl);
1614
- }
1615
- DATA_PTR(self) = NULL;
1616
+ ossl_ssl_shutdown(ssl);
1616
1617
 
1617
1618
  return Qnil;
1618
1619
  }
@@ -1861,7 +1862,7 @@ ossl_ssl_get_client_ca_list(VALUE self)
1861
1862
  return ossl_x509name_sk2ary(ca);
1862
1863
  }
1863
1864
 
1864
- # ifdef HAVE_OPENSSL_NPN_NEGOTIATED
1865
+ # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
1865
1866
  /*
1866
1867
  * call-seq:
1867
1868
  * ssl.npn_protocol => String
@@ -2132,7 +2133,7 @@ Init_ossl_ssl(void)
2132
2133
  * end
2133
2134
  */
2134
2135
  rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse);
2135
- #ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2136
+ #ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
2136
2137
  /*
2137
2138
  * An Enumerable of Strings. Each String represents a protocol to be
2138
2139
  * advertised as the list of supported protocols for Next Protocol
@@ -2307,7 +2308,7 @@ Init_ossl_ssl(void)
2307
2308
  # ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
2308
2309
  rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0);
2309
2310
  # endif
2310
- # ifdef HAVE_OPENSSL_NPN_NEGOTIATED
2311
+ # ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
2311
2312
  rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0);
2312
2313
  # endif
2313
2314
  #endif
@@ -72,16 +72,13 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr)
72
72
  }
73
73
 
74
74
  X509_ATTRIBUTE *
75
- DupX509AttrPtr(VALUE obj)
75
+ GetX509AttrPtr(VALUE obj)
76
76
  {
77
- X509_ATTRIBUTE *attr, *new;
77
+ X509_ATTRIBUTE *attr;
78
78
 
79
79
  SafeGetX509Attr(obj, attr);
80
- if (!(new = X509_ATTRIBUTE_dup(attr))) {
81
- ossl_raise(eX509AttrError, NULL);
82
- }
83
80
 
84
- return new;
81
+ return attr;
85
82
  }
86
83
 
87
84
  /*
@@ -141,12 +138,15 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid)
141
138
  ASN1_OBJECT *obj;
142
139
  char *s;
143
140
 
144
- s = StringValuePtr(oid);
141
+ GetX509Attr(self, attr);
142
+ s = StringValueCStr(oid);
145
143
  obj = OBJ_txt2obj(s, 0);
146
- if(!obj) obj = OBJ_txt2obj(s, 1);
147
144
  if(!obj) ossl_raise(eX509AttrError, NULL);
148
- GetX509Attr(self, attr);
149
- X509_ATTRIBUTE_set1_object(attr, obj);
145
+ if (!X509_ATTRIBUTE_set1_object(attr, obj)) {
146
+ ASN1_OBJECT_free(obj);
147
+ ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object");
148
+ }
149
+ ASN1_OBJECT_free(obj);
150
150
 
151
151
  return oid;
152
152
  }
@@ -315,7 +315,8 @@ ossl_x509crl_set_revoked(VALUE self, VALUE ary)
315
315
  for (i=0; i<RARRAY_LEN(ary); i++) {
316
316
  rev = DupX509RevokedPtr(RARRAY_AREF(ary, i));
317
317
  if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
318
- ossl_raise(eX509CRLError, NULL);
318
+ X509_REVOKED_free(rev);
319
+ ossl_raise(eX509CRLError, "X509_CRL_add0_revoked");
319
320
  }
320
321
  }
321
322
  X509_CRL_sort(crl);
@@ -332,7 +333,8 @@ ossl_x509crl_add_revoked(VALUE self, VALUE revoked)
332
333
  GetX509CRL(self, crl);
333
334
  rev = DupX509RevokedPtr(revoked);
334
335
  if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */
335
- ossl_raise(eX509CRLError, NULL);
336
+ X509_REVOKED_free(rev);
337
+ ossl_raise(eX509CRLError, "X509_CRL_add0_revoked");
336
338
  }
337
339
  X509_CRL_sort(crl);
338
340
 
@@ -188,24 +188,6 @@ ossl_x509extfactory_set_crl(VALUE self, VALUE crl)
188
188
  return crl;
189
189
  }
190
190
 
191
- #ifdef HAVE_X509V3_SET_NCONF
192
- static VALUE
193
- ossl_x509extfactory_set_config(VALUE self, VALUE config)
194
- {
195
- X509V3_CTX *ctx;
196
- CONF *conf;
197
-
198
- GetX509ExtFactory(self, ctx);
199
- rb_iv_set(self, "@config", config);
200
- conf = GetConfigPtr(config); /* NO DUP NEEDED */
201
- X509V3_set_nconf(ctx, conf);
202
-
203
- return config;
204
- }
205
- #else
206
- #define ossl_x509extfactory_set_config rb_f_notimplement
207
- #endif
208
-
209
191
  static VALUE
210
192
  ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self)
211
193
  {
@@ -264,8 +246,11 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self)
264
246
  obj = NewX509Ext(cX509Ext);
265
247
  #ifdef HAVE_X509V3_EXT_NCONF_NID
266
248
  rconf = rb_iv_get(self, "@config");
267
- conf = NIL_P(rconf) ? NULL : GetConfigPtr(rconf);
249
+ conf = NIL_P(rconf) ? NULL : DupConfigPtr(rconf);
250
+ X509V3_set_nconf(ctx, conf);
268
251
  ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr));
252
+ X509V3_set_ctx_nodb(ctx);
253
+ NCONF_free(conf);
269
254
  #else
270
255
  if (!empty_lhash) empty_lhash = lh_new(NULL, NULL);
271
256
  ext = X509V3_EXT_conf_nid(empty_lhash, ctx, nid, RSTRING_PTR(valstr));
@@ -339,14 +324,16 @@ ossl_x509ext_set_oid(VALUE self, VALUE oid)
339
324
  {
340
325
  X509_EXTENSION *ext;
341
326
  ASN1_OBJECT *obj;
342
- char *s;
343
327
 
344
- s = StringValuePtr(oid);
345
- obj = OBJ_txt2obj(s, 0);
346
- if(!obj) obj = OBJ_txt2obj(s, 1);
347
- if(!obj) ossl_raise(eX509ExtError, NULL);
348
328
  GetX509Ext(self, ext);
349
- X509_EXTENSION_set_object(ext, obj);
329
+ obj = OBJ_txt2obj(StringValueCStr(oid), 0);
330
+ if (!obj)
331
+ ossl_raise(eX509ExtError, "OBJ_txt2obj");
332
+ if (!X509_EXTENSION_set_object(ext, obj)) {
333
+ ASN1_OBJECT_free(obj);
334
+ ossl_raise(eX509ExtError, "X509_EXTENSION_set_object");
335
+ }
336
+ ASN1_OBJECT_free(obj);
350
337
 
351
338
  return oid;
352
339
  }
@@ -356,25 +343,16 @@ ossl_x509ext_set_value(VALUE self, VALUE data)
356
343
  {
357
344
  X509_EXTENSION *ext;
358
345
  ASN1_OCTET_STRING *asn1s;
359
- char *s;
360
346
 
347
+ GetX509Ext(self, ext);
361
348
  data = ossl_to_der_if_possible(data);
362
349
  StringValue(data);
363
- if(!(s = OPENSSL_malloc(RSTRING_LEN(data))))
364
- ossl_raise(eX509ExtError, "malloc error");
365
- memcpy(s, RSTRING_PTR(data), RSTRING_LEN(data));
366
- if(!(asn1s = ASN1_OCTET_STRING_new())){
367
- OPENSSL_free(s);
368
- ossl_raise(eX509ExtError, NULL);
369
- }
370
- if(!M_ASN1_OCTET_STRING_set(asn1s, s, RSTRING_LENINT(data))){
371
- OPENSSL_free(s);
372
- ASN1_OCTET_STRING_free(asn1s);
373
- ossl_raise(eX509ExtError, NULL);
350
+ asn1s = X509_EXTENSION_get_data(ext);
351
+
352
+ if (!ASN1_OCTET_STRING_set(asn1s, (unsigned char *)RSTRING_PTR(data),
353
+ RSTRING_LENINT(data))) {
354
+ ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set");
374
355
  }
375
- OPENSSL_free(s);
376
- GetX509Ext(self, ext);
377
- X509_EXTENSION_set_data(ext, asn1s);
378
356
 
379
357
  return data;
380
358
  }
@@ -476,13 +454,12 @@ Init_ossl_x509ext(void)
476
454
  rb_attr(cX509ExtFactory, rb_intern("subject_certificate"), 1, 0, Qfalse);
477
455
  rb_attr(cX509ExtFactory, rb_intern("subject_request"), 1, 0, Qfalse);
478
456
  rb_attr(cX509ExtFactory, rb_intern("crl"), 1, 0, Qfalse);
479
- rb_attr(cX509ExtFactory, rb_intern("config"), 1, 0, Qfalse);
457
+ rb_attr(cX509ExtFactory, rb_intern("config"), 1, 1, Qfalse);
480
458
 
481
459
  rb_define_method(cX509ExtFactory, "issuer_certificate=", ossl_x509extfactory_set_issuer_cert, 1);
482
460
  rb_define_method(cX509ExtFactory, "subject_certificate=", ossl_x509extfactory_set_subject_cert, 1);
483
461
  rb_define_method(cX509ExtFactory, "subject_request=", ossl_x509extfactory_set_subject_req, 1);
484
462
  rb_define_method(cX509ExtFactory, "crl=", ossl_x509extfactory_set_crl, 1);
485
- rb_define_method(cX509ExtFactory, "config=", ossl_x509extfactory_set_config, 1);
486
463
  rb_define_method(cX509ExtFactory, "create_ext", ossl_x509extfactory_create_ext, -1);
487
464
 
488
465
  cX509Ext = rb_define_class_under(mX509, "Extension", rb_cObject);
@@ -430,7 +430,7 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary)
430
430
  req->req_info->attributes = NULL;
431
431
  for (i=0;i<RARRAY_LEN(ary); i++) {
432
432
  item = RARRAY_AREF(ary, i);
433
- attr = DupX509AttrPtr(item);
433
+ attr = GetX509AttrPtr(item);
434
434
  if (!X509_REQ_add1_attr(req, attr)) {
435
435
  ossl_raise(eX509ReqError, NULL);
436
436
  }
@@ -444,7 +444,7 @@ ossl_x509req_add_attribute(VALUE self, VALUE attr)
444
444
  X509_REQ *req;
445
445
 
446
446
  GetX509Req(self, req);
447
- if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) {
447
+ if (!X509_REQ_add1_attr(req, GetX509AttrPtr(attr))) {
448
448
  ossl_raise(eX509ReqError, NULL);
449
449
  }
450
450
 
@@ -200,7 +200,7 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary)
200
200
  rev->extensions = NULL;
201
201
  for (i=0; i<RARRAY_LEN(ary); i++) {
202
202
  item = RARRAY_AREF(ary, i);
203
- ext = DupX509ExtPtr(item);
203
+ ext = GetX509ExtPtr(item);
204
204
  if(!X509_REVOKED_add_ext(rev, ext, -1)) {
205
205
  ossl_raise(eX509RevError, NULL);
206
206
  }
@@ -215,7 +215,7 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext)
215
215
  X509_REVOKED *rev;
216
216
 
217
217
  GetX509Rev(self, rev);
218
- if(!X509_REVOKED_add_ext(rev, DupX509ExtPtr(ext), -1)) {
218
+ if (!X509_REVOKED_add_ext(rev, GetX509ExtPtr(ext), -1)) {
219
219
  ossl_raise(eX509RevError, NULL);
220
220
  }
221
221
 
@@ -251,7 +251,7 @@ module OpenSSL
251
251
  include SocketForwarder
252
252
 
253
253
  if ExtConfig::OPENSSL_NO_SOCK
254
- def initialize(io, ctx = nil); raise NotImplmentedError; end
254
+ def initialize(io, ctx = nil); raise NotImplementedError; end
255
255
  else
256
256
  if ExtConfig::HAVE_TLSEXT_HOST_NAME
257
257
  attr_accessor :hostname
@@ -290,7 +290,10 @@ module OpenSSL
290
290
  # call-seq:
291
291
  # ssl.sysclose => nil
292
292
  #
293
- # Shuts down the SSL connection and prepares it for another connection.
293
+ # Sends "close notify" to the peer and tries to shut down the SSL
294
+ # connection gracefully.
295
+ #
296
+ # If sync_close is set to +true+, the underlying IO is also closed.
294
297
  def sysclose
295
298
  return if closed?
296
299
  stop
@@ -1,5 +1,5 @@
1
1
  module RubySL
2
2
  module OpenSSL
3
- VERSION = "2.8.0"
3
+ VERSION = "2.9"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,24 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysl-openssl
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: '2.9'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Shirai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-29 00:00:00.000000000 Z
11
+ date: 2016-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
- type: :development
16
- prerelease: false
17
15
  requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
17
  - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
@@ -26,13 +26,13 @@ dependencies:
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
- type: :development
30
- prerelease: false
31
29
  requirement: !ruby/object:Gem::Requirement
32
30
  requirements:
33
31
  - - "~>"
34
32
  - !ruby/object:Gem::Version
35
33
  version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
@@ -40,13 +40,13 @@ dependencies:
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mspec
43
- type: :development
44
- prerelease: false
45
43
  requirement: !ruby/object:Gem::Requirement
46
44
  requirements:
47
45
  - - "~>"
48
46
  - !ruby/object:Gem::Version
49
47
  version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
@@ -54,13 +54,13 @@ dependencies:
54
54
  version: '1.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rubysl-prettyprint
57
- type: :development
58
- prerelease: false
59
57
  requirement: !ruby/object:Gem::Requirement
60
58
  requirements:
61
59
  - - "~>"
62
60
  - !ruby/object:Gem::Version
63
61
  version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
@@ -178,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
178
  version: '0'
179
179
  requirements: []
180
180
  rubyforge_project:
181
- rubygems_version: 2.4.8
181
+ rubygems_version: 2.5.1
182
182
  signing_key:
183
183
  specification_version: 4
184
184
  summary: Ruby standard library OpenSSL.