rubysl-openssl 2.8.0 → 2.9

Sign up to get free protection for your applications and to get access to all the features.
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.