rubysl-openssl 1.0.2 → 2.0.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -6
  3. data/ext/rubysl/openssl/.gitignore +3 -0
  4. data/ext/rubysl/openssl/deprecation.rb +21 -0
  5. data/ext/rubysl/openssl/extconf.rb +45 -32
  6. data/ext/rubysl/openssl/openssl_missing.c +20 -7
  7. data/ext/rubysl/openssl/openssl_missing.h +22 -15
  8. data/ext/rubysl/openssl/ossl.c +610 -61
  9. data/ext/rubysl/openssl/ossl.h +31 -17
  10. data/ext/rubysl/openssl/ossl_asn1.c +974 -183
  11. data/ext/rubysl/openssl/ossl_asn1.h +3 -3
  12. data/ext/rubysl/openssl/ossl_bio.c +4 -3
  13. data/ext/rubysl/openssl/ossl_bio.h +1 -1
  14. data/ext/rubysl/openssl/ossl_bn.c +32 -28
  15. data/ext/rubysl/openssl/ossl_bn.h +1 -1
  16. data/ext/rubysl/openssl/ossl_cipher.c +494 -93
  17. data/ext/rubysl/openssl/ossl_cipher.h +1 -1
  18. data/ext/rubysl/openssl/ossl_config.c +4 -5
  19. data/ext/rubysl/openssl/ossl_config.h +1 -1
  20. data/ext/rubysl/openssl/ossl_digest.c +206 -24
  21. data/ext/rubysl/openssl/ossl_digest.h +1 -1
  22. data/ext/rubysl/openssl/ossl_engine.c +48 -26
  23. data/ext/rubysl/openssl/ossl_engine.h +1 -1
  24. data/ext/rubysl/openssl/ossl_hmac.c +40 -38
  25. data/ext/rubysl/openssl/ossl_hmac.h +1 -1
  26. data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
  27. data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
  28. data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
  29. data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
  30. data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
  31. data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
  32. data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
  33. data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
  34. data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
  35. data/ext/rubysl/openssl/ossl_pkey.c +211 -15
  36. data/ext/rubysl/openssl/ossl_pkey.h +19 -9
  37. data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
  38. data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
  39. data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
  40. data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
  41. data/ext/rubysl/openssl/ossl_rand.c +15 -15
  42. data/ext/rubysl/openssl/ossl_rand.h +1 -1
  43. data/ext/rubysl/openssl/ossl_ssl.c +939 -192
  44. data/ext/rubysl/openssl/ossl_ssl.h +6 -6
  45. data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
  46. data/ext/rubysl/openssl/ossl_version.h +2 -2
  47. data/ext/rubysl/openssl/ossl_x509.c +1 -1
  48. data/ext/rubysl/openssl/ossl_x509.h +1 -1
  49. data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
  50. data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
  51. data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
  52. data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
  53. data/ext/rubysl/openssl/ossl_x509name.c +139 -29
  54. data/ext/rubysl/openssl/ossl_x509req.c +42 -40
  55. data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
  56. data/ext/rubysl/openssl/ossl_x509store.c +99 -47
  57. data/ext/rubysl/openssl/ruby_missing.h +3 -16
  58. data/lib/openssl/bn.rb +19 -19
  59. data/lib/openssl/buffering.rb +222 -14
  60. data/lib/openssl/cipher.rb +20 -20
  61. data/lib/openssl/config.rb +1 -4
  62. data/lib/openssl/digest.rb +47 -19
  63. data/lib/openssl/ssl.rb +197 -1
  64. data/lib/openssl/x509.rb +162 -1
  65. data/lib/rubysl/openssl.rb +4 -8
  66. data/lib/rubysl/openssl/version.rb +1 -1
  67. data/rubysl-openssl.gemspec +1 -2
  68. metadata +16 -34
  69. data/ext/rubysl/openssl/extconf.h +0 -50
  70. data/lib/openssl/net/ftptls.rb +0 -53
  71. data/lib/openssl/net/telnets.rb +0 -251
  72. data/lib/openssl/pkcs7.rb +0 -25
  73. data/lib/openssl/ssl-internal.rb +0 -187
  74. data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_pkcs7.c 28367 2010-06-21 09:18:59Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -11,64 +11,64 @@
11
11
  #include "ossl.h"
12
12
 
13
13
  #define WrapPKCS7(klass, obj, pkcs7) do { \
14
- if (!pkcs7) { \
14
+ if (!(pkcs7)) { \
15
15
  ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
16
16
  } \
17
- obj = Data_Wrap_Struct(klass, 0, PKCS7_free, pkcs7); \
17
+ (obj) = Data_Wrap_Struct((klass), 0, PKCS7_free, (pkcs7)); \
18
18
  } while (0)
19
19
  #define GetPKCS7(obj, pkcs7) do { \
20
- Data_Get_Struct(obj, PKCS7, pkcs7); \
21
- if (!pkcs7) { \
20
+ Data_Get_Struct((obj), PKCS7, (pkcs7)); \
21
+ if (!(pkcs7)) { \
22
22
  ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \
23
23
  } \
24
24
  } while (0)
25
25
  #define SafeGetPKCS7(obj, pkcs7) do { \
26
- OSSL_Check_Kind(obj, cPKCS7); \
27
- GetPKCS7(obj, pkcs7); \
26
+ OSSL_Check_Kind((obj), cPKCS7); \
27
+ GetPKCS7((obj), (pkcs7)); \
28
28
  } while (0)
29
29
 
30
30
  #define WrapPKCS7si(klass, obj, p7si) do { \
31
- if (!p7si) { \
31
+ if (!(p7si)) { \
32
32
  ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \
33
33
  } \
34
- obj = Data_Wrap_Struct(klass, 0, PKCS7_SIGNER_INFO_free, p7si); \
34
+ (obj) = Data_Wrap_Struct((klass), 0, PKCS7_SIGNER_INFO_free, (p7si)); \
35
35
  } while (0)
36
36
  #define GetPKCS7si(obj, p7si) do { \
37
- Data_Get_Struct(obj, PKCS7_SIGNER_INFO, p7si); \
38
- if (!p7si) { \
37
+ Data_Get_Struct((obj), PKCS7_SIGNER_INFO, (p7si)); \
38
+ if (!(p7si)) { \
39
39
  ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \
40
40
  } \
41
41
  } while (0)
42
42
  #define SafeGetPKCS7si(obj, p7si) do { \
43
- OSSL_Check_Kind(obj, cPKCS7Signer); \
44
- GetPKCS7si(obj, p7si); \
43
+ OSSL_Check_Kind((obj), cPKCS7Signer); \
44
+ GetPKCS7si((obj), (p7si)); \
45
45
  } while (0)
46
46
 
47
47
  #define WrapPKCS7ri(klass, obj, p7ri) do { \
48
- if (!p7ri) { \
48
+ if (!(p7ri)) { \
49
49
  ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \
50
50
  } \
51
- obj = Data_Wrap_Struct(klass, 0, PKCS7_RECIP_INFO_free, p7ri); \
51
+ (obj) = Data_Wrap_Struct((klass), 0, PKCS7_RECIP_INFO_free, (p7ri)); \
52
52
  } while (0)
53
53
  #define GetPKCS7ri(obj, p7ri) do { \
54
- Data_Get_Struct(obj, PKCS7_RECIP_INFO, p7ri); \
55
- if (!p7ri) { \
54
+ Data_Get_Struct((obj), PKCS7_RECIP_INFO, (p7ri)); \
55
+ if (!(p7ri)) { \
56
56
  ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \
57
57
  } \
58
58
  } while (0)
59
59
  #define SafeGetPKCS7ri(obj, p7ri) do { \
60
- OSSL_Check_Kind(obj, cPKCS7Recipient); \
61
- GetPKCS7ri(obj, p7ri); \
60
+ OSSL_Check_Kind((obj), cPKCS7Recipient); \
61
+ GetPKCS7ri((obj), (p7ri)); \
62
62
  } while (0)
63
63
 
64
- #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
64
+ #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0]))
65
65
 
66
66
  #define ossl_pkcs7_set_data(o,v) rb_iv_set((o), "@data", (v))
67
67
  #define ossl_pkcs7_get_data(o) rb_iv_get((o), "@data")
68
68
  #define ossl_pkcs7_set_err_string(o,v) rb_iv_set((o), "@error_string", (v))
69
69
  #define ossl_pkcs7_get_err_string(o) rb_iv_get((o), "@error_string")
70
70
 
71
- /*
71
+ /*
72
72
  * Classes
73
73
  */
74
74
  VALUE cPKCS7;
@@ -97,7 +97,7 @@ static PKCS7_SIGNER_INFO *
97
97
  DupPKCS7SignerPtr(VALUE obj)
98
98
  {
99
99
  PKCS7_SIGNER_INFO *p7si, *pkcs7;
100
-
100
+
101
101
  SafeGetPKCS7si(obj, p7si);
102
102
  if (!(pkcs7 = PKCS7_SIGNER_INFO_dup(p7si))) {
103
103
  ossl_raise(ePKCS7Error, NULL);
@@ -123,7 +123,7 @@ static PKCS7_RECIP_INFO *
123
123
  DupPKCS7RecipientPtr(VALUE obj)
124
124
  {
125
125
  PKCS7_RECIP_INFO *p7ri, *pkcs7;
126
-
126
+
127
127
  SafeGetPKCS7ri(obj, p7ri);
128
128
  if (!(pkcs7 = PKCS7_RECIP_INFO_dup(p7ri))) {
129
129
  ossl_raise(ePKCS7Error, NULL);
@@ -295,7 +295,7 @@ ossl_pkcs7_alloc(VALUE klass)
295
295
  ossl_raise(ePKCS7Error, NULL);
296
296
  }
297
297
  WrapPKCS7(klass, obj, pkcs7);
298
-
298
+
299
299
  return obj;
300
300
  }
301
301
 
@@ -309,7 +309,7 @@ ossl_pkcs7_alloc(VALUE klass)
309
309
  static VALUE
310
310
  ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
311
311
  {
312
- PKCS7 *p7;
312
+ PKCS7 *p7, *pkcs = DATA_PTR(self);
313
313
  BIO *in;
314
314
  VALUE arg;
315
315
 
@@ -317,11 +317,18 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
317
317
  return self;
318
318
  arg = ossl_to_der_if_possible(arg);
319
319
  in = ossl_obj2bio(arg);
320
- p7 = PEM_read_bio_PKCS7(in, (PKCS7 **)&DATA_PTR(self), NULL, NULL);
320
+ p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
321
321
  if (!p7) {
322
- BIO_reset(in);
323
- p7 = d2i_PKCS7_bio(in, (PKCS7 **)&DATA_PTR(self));
322
+ OSSL_BIO_reset(in);
323
+ p7 = d2i_PKCS7_bio(in, &pkcs);
324
+ if (!p7) {
325
+ BIO_free(in);
326
+ PKCS7_free(pkcs);
327
+ DATA_PTR(self) = NULL;
328
+ ossl_raise(rb_eArgError, "Could not parse the PKCS7");
329
+ }
324
330
  }
331
+ DATA_PTR(self) = pkcs;
325
332
  BIO_free(in);
326
333
  ossl_pkcs7_set_data(self, Qnil);
327
334
  ossl_pkcs7_set_err_string(self, Qnil);
@@ -493,7 +500,7 @@ ossl_pkcs7_get_signer(VALUE self)
493
500
  PKCS7_SIGNER_INFO *si;
494
501
  int num, i;
495
502
  VALUE ary;
496
-
503
+
497
504
  GetPKCS7(self, pkcs7);
498
505
  if (!(sk = PKCS7_get_signer_info(pkcs7))) {
499
506
  OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!");
@@ -535,7 +542,7 @@ ossl_pkcs7_get_recipient(VALUE self)
535
542
  PKCS7_RECIP_INFO *si;
536
543
  int num, i;
537
544
  VALUE ary;
538
-
545
+
539
546
  GetPKCS7(self, pkcs7);
540
547
  if (PKCS7_type_is_enveloped(pkcs7))
541
548
  sk = pkcs7->d.enveloped->recipientinfo;
@@ -775,7 +782,7 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
775
782
  }
776
783
  if(!PKCS7_dataFinal(pkcs7, out)) goto err;
777
784
  ossl_pkcs7_set_data(self, Qnil);
778
-
785
+
779
786
  err:
780
787
  BIO_free(out);
781
788
  BIO_free(in);
@@ -798,7 +805,7 @@ ossl_pkcs7_to_der(VALUE self)
798
805
  if((len = i2d_PKCS7(pkcs7, NULL)) <= 0)
799
806
  ossl_raise(ePKCS7Error, NULL);
800
807
  str = rb_str_new(0, len);
801
- p = RSTRING_PTR(str);
808
+ p = (unsigned char *)RSTRING_PTR(str);
802
809
  if(i2d_PKCS7(pkcs7, &p) <= 0)
803
810
  ossl_raise(ePKCS7Error, NULL);
804
811
  ossl_str_adjust(str, p);
@@ -812,7 +819,7 @@ ossl_pkcs7_to_pem(VALUE self)
812
819
  PKCS7 *pkcs7;
813
820
  BIO *out;
814
821
  VALUE str;
815
-
822
+
816
823
  GetPKCS7(self, pkcs7);
817
824
  if (!(out = BIO_new(BIO_s_mem()))) {
818
825
  ossl_raise(ePKCS7Error, NULL);
@@ -887,9 +894,9 @@ ossl_pkcs7si_get_signed_time(VALUE self)
887
894
  {
888
895
  PKCS7_SIGNER_INFO *p7si;
889
896
  ASN1_TYPE *asn1obj;
890
-
897
+
891
898
  GetPKCS7si(self, p7si);
892
-
899
+
893
900
  if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) {
894
901
  ossl_raise(ePKCS7Error, NULL);
895
902
  }
@@ -1019,10 +1026,10 @@ Init_ossl_pkcs7()
1019
1026
 
1020
1027
  cPKCS7Recipient = rb_define_class_under(cPKCS7,"RecipientInfo",rb_cObject);
1021
1028
  rb_define_alloc_func(cPKCS7Recipient, ossl_pkcs7ri_alloc);
1022
- rb_define_method(cPKCS7Recipient, "initialize", ossl_pkcs7ri_initialize,1);
1029
+ rb_define_method(cPKCS7Recipient, "initialize", ossl_pkcs7ri_initialize,1);
1023
1030
  rb_define_method(cPKCS7Recipient, "issuer", ossl_pkcs7ri_get_issuer,0);
1024
1031
  rb_define_method(cPKCS7Recipient, "serial", ossl_pkcs7ri_get_serial,0);
1025
- rb_define_method(cPKCS7Recipient, "enc_key", ossl_pkcs7ri_get_enc_key,0);
1032
+ rb_define_method(cPKCS7Recipient, "enc_key", ossl_pkcs7ri_get_enc_key,0);
1026
1033
 
1027
1034
  #define DefPKCS7Const(x) rb_define_const(cPKCS7, #x, INT2NUM(PKCS7_##x))
1028
1035
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_pkcs7.h 12496 2007-06-08 15:02:04Z technorama $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * $Id: ossl_pkey.c 28004 2010-05-24 23:58:49Z shyouhei $
2
+ * $Id$
3
3
  * 'OpenSSL for Ruby' project
4
4
  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
5
  * All rights reserved.
@@ -33,6 +33,42 @@ ossl_generate_cb(int p, int n, void *arg)
33
33
  rb_yield(ary);
34
34
  }
35
35
 
36
+ #if HAVE_BN_GENCB
37
+ /* OpenSSL 2nd version of GN generation callback */
38
+ int
39
+ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
40
+ {
41
+ VALUE ary;
42
+ struct ossl_generate_cb_arg *arg;
43
+ int state;
44
+
45
+ arg = (struct ossl_generate_cb_arg *)cb->arg;
46
+ if (arg->yield) {
47
+ ary = rb_ary_new2(2);
48
+ rb_ary_store(ary, 0, INT2NUM(p));
49
+ rb_ary_store(ary, 1, INT2NUM(n));
50
+
51
+ /*
52
+ * can be break by raising exception or 'break'
53
+ */
54
+ rb_protect(rb_yield, ary, &state);
55
+ if (state) {
56
+ arg->stop = 1;
57
+ arg->state = state;
58
+ }
59
+ }
60
+ if (arg->stop) return 0;
61
+ return 1;
62
+ }
63
+
64
+ void
65
+ ossl_generate_cb_stop(void *ptr)
66
+ {
67
+ struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
68
+ arg->stop = 1;
69
+ }
70
+ #endif
71
+
36
72
  /*
37
73
  * Public
38
74
  */
@@ -62,7 +98,8 @@ ossl_pkey_new(EVP_PKEY *pkey)
62
98
  default:
63
99
  ossl_raise(ePKeyError, "unsupported key type");
64
100
  }
65
- return Qnil; /* not reached */
101
+
102
+ UNREACHABLE;
66
103
  }
67
104
 
68
105
  VALUE
@@ -75,6 +112,7 @@ ossl_pkey_new_from_file(VALUE filename)
75
112
  if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
76
113
  ossl_raise(ePKeyError, "%s", strerror(errno));
77
114
  }
115
+ rb_update_max_fd(fileno(fp));
78
116
 
79
117
  pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
80
118
  fclose(fp);
@@ -85,6 +123,53 @@ ossl_pkey_new_from_file(VALUE filename)
85
123
  return ossl_pkey_new(pkey);
86
124
  }
87
125
 
126
+ /*
127
+ * call-seq:
128
+ * OpenSSL::PKey.read(string [, pwd ] ) -> PKey
129
+ * OpenSSL::PKey.read(file [, pwd ]) -> PKey
130
+ *
131
+ * === Parameters
132
+ * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
133
+ * or public key.
134
+ * * +file+ is an instance of +File+ containing a DER- or PEM-encoded
135
+ * arbitrary private or public key.
136
+ * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
137
+ * PEM resource.
138
+ */
139
+ static VALUE
140
+ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
141
+ {
142
+ EVP_PKEY *pkey;
143
+ BIO *bio;
144
+ VALUE data, pass;
145
+ char *passwd = NULL;
146
+
147
+ rb_scan_args(argc, argv, "11", &data, &pass);
148
+
149
+ bio = ossl_obj2bio(data);
150
+ if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
151
+ OSSL_BIO_reset(bio);
152
+ if (!NIL_P(pass)) {
153
+ passwd = StringValuePtr(pass);
154
+ }
155
+ if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
156
+ OSSL_BIO_reset(bio);
157
+ if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
158
+ OSSL_BIO_reset(bio);
159
+ if (!NIL_P(pass)) {
160
+ passwd = StringValuePtr(pass);
161
+ }
162
+ pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
163
+ }
164
+ }
165
+ }
166
+
167
+ BIO_free(bio);
168
+ if (!pkey)
169
+ ossl_raise(rb_eArgError, "Could not parse PKey");
170
+ return ossl_pkey_new(pkey);
171
+ }
172
+
88
173
  EVP_PKEY *
89
174
  GetPKeyPtr(VALUE obj)
90
175
  {
@@ -99,7 +184,7 @@ EVP_PKEY *
99
184
  GetPrivPKeyPtr(VALUE obj)
100
185
  {
101
186
  EVP_PKEY *pkey;
102
-
187
+
103
188
  if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
104
189
  ossl_raise(rb_eArgError, "Private key is needed.");
105
190
  }
@@ -112,7 +197,7 @@ EVP_PKEY *
112
197
  DupPKeyPtr(VALUE obj)
113
198
  {
114
199
  EVP_PKEY *pkey;
115
-
200
+
116
201
  SafeGetPKey(obj, pkey);
117
202
  CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
118
203
 
@@ -123,7 +208,7 @@ EVP_PKEY *
123
208
  DupPrivPKeyPtr(VALUE obj)
124
209
  {
125
210
  EVP_PKEY *pkey;
126
-
211
+
127
212
  if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
128
213
  ossl_raise(rb_eArgError, "Private key is needed.");
129
214
  }
@@ -150,6 +235,13 @@ ossl_pkey_alloc(VALUE klass)
150
235
  return obj;
151
236
  }
152
237
 
238
+ /*
239
+ * call-seq:
240
+ * PKeyClass.new -> self
241
+ *
242
+ * Because PKey is an abstract class, actually calling this method explicitly
243
+ * will raise a +NotImplementedError+.
244
+ */
153
245
  static VALUE
154
246
  ossl_pkey_initialize(VALUE self)
155
247
  {
@@ -159,12 +251,29 @@ ossl_pkey_initialize(VALUE self)
159
251
  return self;
160
252
  }
161
253
 
254
+ /*
255
+ * call-seq:
256
+ * pkey.sign(digest, data) -> String
257
+ *
258
+ * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must
259
+ * be provided. The return value is again a +String+ containing the signature.
260
+ * A PKeyError is raised should errors occur.
261
+ * Any previous state of the +Digest+ instance is irrelevant to the signature
262
+ * outcome, the digest instance is reset to its initial state during the
263
+ * operation.
264
+ *
265
+ * == Example
266
+ * data = 'Sign me!'
267
+ * digest = OpenSSL::Digest::SHA256.new
268
+ * pkey = OpenSSL::PKey::RSA.new(2048)
269
+ * signature = pkey.sign(digest, data)
270
+ */
162
271
  static VALUE
163
272
  ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
164
273
  {
165
274
  EVP_PKEY *pkey;
166
275
  EVP_MD_CTX ctx;
167
- int buf_len;
276
+ unsigned int buf_len;
168
277
  VALUE str;
169
278
 
170
279
  if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
@@ -175,7 +284,7 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
175
284
  StringValue(data);
176
285
  EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
177
286
  str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
178
- if (!EVP_SignFinal(&ctx, RSTRING_PTR(str), &buf_len, pkey))
287
+ if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
179
288
  ossl_raise(ePKeyError, NULL);
180
289
  assert((long)buf_len <= RSTRING_LEN(str));
181
290
  rb_str_set_len(str, buf_len);
@@ -183,6 +292,27 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
183
292
  return str;
184
293
  }
185
294
 
295
+ /*
296
+ * call-seq:
297
+ * pkey.verify(digest, signature, data) -> String
298
+ *
299
+ * To verify the +String+ +signature+, +digest+, an instance of
300
+ * OpenSSL::Digest, must be provided to re-compute the message digest of the
301
+ * original +data+, also a +String+. The return value is +true+ if the
302
+ * signature is valid, +false+ otherwise. A PKeyError is raised should errors
303
+ * occur.
304
+ * Any previous state of the +Digest+ instance is irrelevant to the validation
305
+ * outcome, the digest instance is reset to its initial state during the
306
+ * operation.
307
+ *
308
+ * == Example
309
+ * data = 'Sign me!'
310
+ * digest = OpenSSL::Digest::SHA256.new
311
+ * pkey = OpenSSL::PKey::RSA.new(2048)
312
+ * signature = pkey.sign(digest, data)
313
+ * pub_key = pkey.public_key
314
+ * puts pub_key.verify(digest, signature, data) # => true
315
+ */
186
316
  static VALUE
187
317
  ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
188
318
  {
@@ -194,7 +324,7 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
194
324
  StringValue(sig);
195
325
  StringValue(data);
196
326
  EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
197
- switch (EVP_VerifyFinal(&ctx, RSTRING_PTR(sig), RSTRING_LEN(sig), pkey)) {
327
+ switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) {
198
328
  case 0:
199
329
  return Qfalse;
200
330
  case 1:
@@ -211,24 +341,90 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
211
341
  void
212
342
  Init_ossl_pkey()
213
343
  {
214
- #if 0 /* let rdoc know about mOSSL */
215
- mOSSL = rb_define_module("OpenSSL");
344
+ #if 0
345
+ mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
216
346
  #endif
217
-
347
+
348
+ /* Document-module: OpenSSL::PKey
349
+ *
350
+ * == Asymmetric Public Key Algorithms
351
+ *
352
+ * Asymmetric public key algorithms solve the problem of establishing and
353
+ * sharing secret keys to en-/decrypt messages. The key in such an
354
+ * algorithm consists of two parts: a public key that may be distributed
355
+ * to others and a private key that needs to remain secret.
356
+ *
357
+ * Messages encrypted with a public key can only be encrypted by
358
+ * recipients that are in possession of the associated private key.
359
+ * Since public key algorithms are considerably slower than symmetric
360
+ * key algorithms (cf. OpenSSL::Cipher) they are often used to establish
361
+ * a symmetric key shared between two parties that are in possession of
362
+ * each other's public key.
363
+ *
364
+ * Asymmetric algorithms offer a lot of nice features that are used in a
365
+ * lot of different areas. A very common application is the creation and
366
+ * validation of digital signatures. To sign a document, the signatory
367
+ * generally uses a message digest algorithm (cf. OpenSSL::Digest) to
368
+ * compute a digest of the document that is then encrypted (i.e. signed)
369
+ * using the private key. Anyone in possession of the public key may then
370
+ * verify the signature by computing the message digest of the original
371
+ * document on their own, decrypting the signature using the signatory's
372
+ * public key and comparing the result to the message digest they
373
+ * previously computed. The signature is valid if and only if the
374
+ * decrypted signature is equal to this message digest.
375
+ *
376
+ * The PKey module offers support for three popular public/private key
377
+ * algorithms:
378
+ * * RSA (OpenSSL::PKey::RSA)
379
+ * * DSA (OpenSSL::PKey::DSA)
380
+ * * Elliptic Curve Cryptography (OpenSSL::PKey::EC)
381
+ * Each of these implementations is in fact a sub-class of the abstract
382
+ * PKey class which offers the interface for supporting digital signatures
383
+ * in the form of PKey#sign and PKey#verify.
384
+ *
385
+ * == Diffie-Hellman Key Exchange
386
+ *
387
+ * Finally PKey also features OpenSSL::PKey::DH, an implementation of
388
+ * the Diffie-Hellman key exchange protocol based on discrete logarithms
389
+ * in finite fields, the same basis that DSA is built on.
390
+ * The Diffie-Hellman protocol can be used to exchange (symmetric) keys
391
+ * over insecure channels without needing any prior joint knowledge
392
+ * between the participating parties. As the security of DH demands
393
+ * relatively long "public keys" (i.e. the part that is overtly
394
+ * transmitted between participants) DH tends to be quite slow. If
395
+ * security or speed is your primary concern, OpenSSL::PKey::EC offers
396
+ * another implementation of the Diffie-Hellman protocol.
397
+ *
398
+ */
218
399
  mPKey = rb_define_module_under(mOSSL, "PKey");
219
-
400
+
401
+ /* Document-class: OpenSSL::PKey::PKeyError
402
+ *
403
+ *Raised when errors occur during PKey#sign or PKey#verify.
404
+ */
220
405
  ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
221
406
 
407
+ /* Document-class: OpenSSL::PKey::PKey
408
+ *
409
+ * An abstract class that bundles signature creation (PKey#sign) and
410
+ * validation (PKey#verify) that is common to all implementations except
411
+ * OpenSSL::PKey::DH
412
+ * * OpenSSL::PKey::RSA
413
+ * * OpenSSL::PKey::DSA
414
+ * * OpenSSL::PKey::EC
415
+ */
222
416
  cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
223
-
417
+
418
+ rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
419
+
224
420
  rb_define_alloc_func(cPKey, ossl_pkey_alloc);
225
421
  rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
226
422
 
227
423
  rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
228
424
  rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
229
-
425
+
230
426
  id_private_q = rb_intern("private?");
231
-
427
+
232
428
  /*
233
429
  * INIT rsa, dsa, dh, ec
234
430
  */