openssl 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openssl might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/BSDL +22 -0
  3. data/CONTRIBUTING.md +130 -0
  4. data/History.md +118 -0
  5. data/LICENSE.txt +56 -0
  6. data/README.md +70 -0
  7. data/ext/openssl/deprecation.rb +26 -0
  8. data/ext/openssl/extconf.rb +158 -0
  9. data/ext/openssl/openssl_missing.c +173 -0
  10. data/ext/openssl/openssl_missing.h +244 -0
  11. data/ext/openssl/ossl.c +1201 -0
  12. data/ext/openssl/ossl.h +222 -0
  13. data/ext/openssl/ossl_asn1.c +1992 -0
  14. data/ext/openssl/ossl_asn1.h +66 -0
  15. data/ext/openssl/ossl_bio.c +87 -0
  16. data/ext/openssl/ossl_bio.h +19 -0
  17. data/ext/openssl/ossl_bn.c +1153 -0
  18. data/ext/openssl/ossl_bn.h +23 -0
  19. data/ext/openssl/ossl_cipher.c +1085 -0
  20. data/ext/openssl/ossl_cipher.h +20 -0
  21. data/ext/openssl/ossl_config.c +89 -0
  22. data/ext/openssl/ossl_config.h +19 -0
  23. data/ext/openssl/ossl_digest.c +453 -0
  24. data/ext/openssl/ossl_digest.h +20 -0
  25. data/ext/openssl/ossl_engine.c +580 -0
  26. data/ext/openssl/ossl_engine.h +19 -0
  27. data/ext/openssl/ossl_hmac.c +398 -0
  28. data/ext/openssl/ossl_hmac.h +18 -0
  29. data/ext/openssl/ossl_ns_spki.c +406 -0
  30. data/ext/openssl/ossl_ns_spki.h +19 -0
  31. data/ext/openssl/ossl_ocsp.c +2013 -0
  32. data/ext/openssl/ossl_ocsp.h +23 -0
  33. data/ext/openssl/ossl_pkcs12.c +259 -0
  34. data/ext/openssl/ossl_pkcs12.h +13 -0
  35. data/ext/openssl/ossl_pkcs5.c +180 -0
  36. data/ext/openssl/ossl_pkcs5.h +6 -0
  37. data/ext/openssl/ossl_pkcs7.c +1125 -0
  38. data/ext/openssl/ossl_pkcs7.h +20 -0
  39. data/ext/openssl/ossl_pkey.c +435 -0
  40. data/ext/openssl/ossl_pkey.h +245 -0
  41. data/ext/openssl/ossl_pkey_dh.c +650 -0
  42. data/ext/openssl/ossl_pkey_dsa.c +672 -0
  43. data/ext/openssl/ossl_pkey_ec.c +1899 -0
  44. data/ext/openssl/ossl_pkey_rsa.c +768 -0
  45. data/ext/openssl/ossl_rand.c +238 -0
  46. data/ext/openssl/ossl_rand.h +18 -0
  47. data/ext/openssl/ossl_ssl.c +2679 -0
  48. data/ext/openssl/ossl_ssl.h +41 -0
  49. data/ext/openssl/ossl_ssl_session.c +352 -0
  50. data/ext/openssl/ossl_version.h +15 -0
  51. data/ext/openssl/ossl_x509.c +186 -0
  52. data/ext/openssl/ossl_x509.h +119 -0
  53. data/ext/openssl/ossl_x509attr.c +328 -0
  54. data/ext/openssl/ossl_x509cert.c +860 -0
  55. data/ext/openssl/ossl_x509crl.c +565 -0
  56. data/ext/openssl/ossl_x509ext.c +480 -0
  57. data/ext/openssl/ossl_x509name.c +547 -0
  58. data/ext/openssl/ossl_x509req.c +492 -0
  59. data/ext/openssl/ossl_x509revoked.c +279 -0
  60. data/ext/openssl/ossl_x509store.c +846 -0
  61. data/ext/openssl/ruby_missing.h +32 -0
  62. data/lib/openssl.rb +21 -0
  63. data/lib/openssl/bn.rb +39 -0
  64. data/lib/openssl/buffering.rb +451 -0
  65. data/lib/openssl/cipher.rb +67 -0
  66. data/lib/openssl/config.rb +473 -0
  67. data/lib/openssl/digest.rb +78 -0
  68. data/lib/openssl/pkey.rb +44 -0
  69. data/lib/openssl/ssl.rb +416 -0
  70. data/lib/openssl/x509.rb +176 -0
  71. metadata +178 -0
@@ -0,0 +1,20 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ #if !defined(_OSSL_PKCS7_H_)
11
+ #define _OSSL_PKCS7_H_
12
+
13
+ extern VALUE cPKCS7;
14
+ extern VALUE cPKCS7Signer;
15
+ extern VALUE cPKCS7Recipient;
16
+ extern VALUE ePKCS7Error;
17
+
18
+ void Init_ossl_pkcs7(void);
19
+
20
+ #endif /* _OSSL_PKCS7_H_ */
@@ -0,0 +1,435 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ #include "ossl.h"
11
+
12
+ /*
13
+ * Classes
14
+ */
15
+ VALUE mPKey;
16
+ VALUE cPKey;
17
+ VALUE ePKeyError;
18
+ static ID id_private_q;
19
+
20
+ /*
21
+ * callback for generating keys
22
+ */
23
+ int
24
+ ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
25
+ {
26
+ VALUE ary;
27
+ struct ossl_generate_cb_arg *arg;
28
+ int state;
29
+
30
+ arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb);
31
+ if (arg->yield) {
32
+ ary = rb_ary_new2(2);
33
+ rb_ary_store(ary, 0, INT2NUM(p));
34
+ rb_ary_store(ary, 1, INT2NUM(n));
35
+
36
+ /*
37
+ * can be break by raising exception or 'break'
38
+ */
39
+ rb_protect(rb_yield, ary, &state);
40
+ if (state) {
41
+ arg->stop = 1;
42
+ arg->state = state;
43
+ }
44
+ }
45
+ if (arg->stop) return 0;
46
+ return 1;
47
+ }
48
+
49
+ void
50
+ ossl_generate_cb_stop(void *ptr)
51
+ {
52
+ struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
53
+ arg->stop = 1;
54
+ }
55
+
56
+ static void
57
+ ossl_evp_pkey_free(void *ptr)
58
+ {
59
+ EVP_PKEY_free(ptr);
60
+ }
61
+
62
+ /*
63
+ * Public
64
+ */
65
+ const rb_data_type_t ossl_evp_pkey_type = {
66
+ "OpenSSL/EVP_PKEY",
67
+ {
68
+ 0, ossl_evp_pkey_free,
69
+ },
70
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
71
+ };
72
+
73
+ VALUE
74
+ ossl_pkey_new(EVP_PKEY *pkey)
75
+ {
76
+ if (!pkey) {
77
+ ossl_raise(ePKeyError, "Cannot make new key from NULL.");
78
+ }
79
+ switch (EVP_PKEY_base_id(pkey)) {
80
+ #if !defined(OPENSSL_NO_RSA)
81
+ case EVP_PKEY_RSA:
82
+ return ossl_rsa_new(pkey);
83
+ #endif
84
+ #if !defined(OPENSSL_NO_DSA)
85
+ case EVP_PKEY_DSA:
86
+ return ossl_dsa_new(pkey);
87
+ #endif
88
+ #if !defined(OPENSSL_NO_DH)
89
+ case EVP_PKEY_DH:
90
+ return ossl_dh_new(pkey);
91
+ #endif
92
+ #if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
93
+ case EVP_PKEY_EC:
94
+ return ossl_ec_new(pkey);
95
+ #endif
96
+ default:
97
+ ossl_raise(ePKeyError, "unsupported key type");
98
+ }
99
+
100
+ UNREACHABLE;
101
+ }
102
+
103
+ VALUE
104
+ ossl_pkey_new_from_file(VALUE filename)
105
+ {
106
+ FILE *fp;
107
+ EVP_PKEY *pkey;
108
+
109
+ rb_check_safe_obj(filename);
110
+ if (!(fp = fopen(StringValueCStr(filename), "r"))) {
111
+ ossl_raise(ePKeyError, "%s", strerror(errno));
112
+ }
113
+ rb_fd_fix_cloexec(fileno(fp));
114
+
115
+ pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
116
+ fclose(fp);
117
+ if (!pkey) {
118
+ ossl_raise(ePKeyError, NULL);
119
+ }
120
+
121
+ return ossl_pkey_new(pkey);
122
+ }
123
+
124
+ /*
125
+ * call-seq:
126
+ * OpenSSL::PKey.read(string [, pwd ]) -> PKey
127
+ * OpenSSL::PKey.read(io [, pwd ]) -> PKey
128
+ *
129
+ * Reads a DER or PEM encoded string from +string+ or +io+ and returns an
130
+ * instance of the appropriate PKey class.
131
+ *
132
+ * === Parameters
133
+ * * +string+ is a DER- or PEM-encoded string containing an arbitrary private
134
+ * or public key.
135
+ * * +io+ is an instance of +IO+ containing a DER- or PEM-encoded
136
+ * arbitrary private or public key.
137
+ * * +pwd+ is an optional password in case +string+ or +file+ is an encrypted
138
+ * PEM resource.
139
+ */
140
+ static VALUE
141
+ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
142
+ {
143
+ EVP_PKEY *pkey;
144
+ BIO *bio;
145
+ VALUE data, pass;
146
+
147
+ rb_scan_args(argc, argv, "11", &data, &pass);
148
+ pass = ossl_pem_passwd_value(pass);
149
+
150
+ bio = ossl_obj2bio(data);
151
+ if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
152
+ OSSL_BIO_reset(bio);
153
+ if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) {
154
+ OSSL_BIO_reset(bio);
155
+ if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
156
+ OSSL_BIO_reset(bio);
157
+ pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass);
158
+ }
159
+ }
160
+ }
161
+
162
+ BIO_free(bio);
163
+ if (!pkey)
164
+ ossl_raise(ePKeyError, "Could not parse PKey");
165
+
166
+ return ossl_pkey_new(pkey);
167
+ }
168
+
169
+ EVP_PKEY *
170
+ GetPKeyPtr(VALUE obj)
171
+ {
172
+ EVP_PKEY *pkey;
173
+
174
+ SafeGetPKey(obj, pkey);
175
+
176
+ return pkey;
177
+ }
178
+
179
+ EVP_PKEY *
180
+ GetPrivPKeyPtr(VALUE obj)
181
+ {
182
+ EVP_PKEY *pkey;
183
+
184
+ if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) {
185
+ ossl_raise(rb_eArgError, "Private key is needed.");
186
+ }
187
+ SafeGetPKey(obj, pkey);
188
+
189
+ return pkey;
190
+ }
191
+
192
+ EVP_PKEY *
193
+ DupPKeyPtr(VALUE obj)
194
+ {
195
+ EVP_PKEY *pkey;
196
+
197
+ SafeGetPKey(obj, pkey);
198
+ EVP_PKEY_up_ref(pkey);
199
+
200
+ return pkey;
201
+ }
202
+
203
+ /*
204
+ * Private
205
+ */
206
+ static VALUE
207
+ ossl_pkey_alloc(VALUE klass)
208
+ {
209
+ EVP_PKEY *pkey;
210
+ VALUE obj;
211
+
212
+ obj = NewPKey(klass);
213
+ if (!(pkey = EVP_PKEY_new())) {
214
+ ossl_raise(ePKeyError, NULL);
215
+ }
216
+ SetPKey(obj, pkey);
217
+
218
+ return obj;
219
+ }
220
+
221
+ /*
222
+ * call-seq:
223
+ * PKeyClass.new -> self
224
+ *
225
+ * Because PKey is an abstract class, actually calling this method explicitly
226
+ * will raise a +NotImplementedError+.
227
+ */
228
+ static VALUE
229
+ ossl_pkey_initialize(VALUE self)
230
+ {
231
+ if (rb_obj_is_instance_of(self, cPKey)) {
232
+ ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class.");
233
+ }
234
+ return self;
235
+ }
236
+
237
+ /*
238
+ * call-seq:
239
+ * pkey.sign(digest, data) -> String
240
+ *
241
+ * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must
242
+ * be provided. The return value is again a +String+ containing the signature.
243
+ * A PKeyError is raised should errors occur.
244
+ * Any previous state of the +Digest+ instance is irrelevant to the signature
245
+ * outcome, the digest instance is reset to its initial state during the
246
+ * operation.
247
+ *
248
+ * == Example
249
+ * data = 'Sign me!'
250
+ * digest = OpenSSL::Digest::SHA256.new
251
+ * pkey = OpenSSL::PKey::RSA.new(2048)
252
+ * signature = pkey.sign(digest, data)
253
+ */
254
+ static VALUE
255
+ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
256
+ {
257
+ EVP_PKEY *pkey;
258
+ const EVP_MD *md;
259
+ EVP_MD_CTX *ctx;
260
+ unsigned int buf_len;
261
+ VALUE str;
262
+ int result;
263
+
264
+ pkey = GetPrivPKeyPtr(self);
265
+ md = GetDigestPtr(digest);
266
+ StringValue(data);
267
+ str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
268
+
269
+ ctx = EVP_MD_CTX_new();
270
+ if (!ctx)
271
+ ossl_raise(ePKeyError, "EVP_MD_CTX_new");
272
+ EVP_SignInit(ctx, md);
273
+ EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
274
+ result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
275
+ EVP_MD_CTX_free(ctx);
276
+ if (!result)
277
+ ossl_raise(ePKeyError, NULL);
278
+ assert((long)buf_len <= RSTRING_LEN(str));
279
+ rb_str_set_len(str, buf_len);
280
+
281
+ return str;
282
+ }
283
+
284
+ /*
285
+ * call-seq:
286
+ * pkey.verify(digest, signature, data) -> String
287
+ *
288
+ * To verify the +String+ +signature+, +digest+, an instance of
289
+ * OpenSSL::Digest, must be provided to re-compute the message digest of the
290
+ * original +data+, also a +String+. The return value is +true+ if the
291
+ * signature is valid, +false+ otherwise. A PKeyError is raised should errors
292
+ * occur.
293
+ * Any previous state of the +Digest+ instance is irrelevant to the validation
294
+ * outcome, the digest instance is reset to its initial state during the
295
+ * operation.
296
+ *
297
+ * == Example
298
+ * data = 'Sign me!'
299
+ * digest = OpenSSL::Digest::SHA256.new
300
+ * pkey = OpenSSL::PKey::RSA.new(2048)
301
+ * signature = pkey.sign(digest, data)
302
+ * pub_key = pkey.public_key
303
+ * puts pub_key.verify(digest, signature, data) # => true
304
+ */
305
+ static VALUE
306
+ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
307
+ {
308
+ EVP_PKEY *pkey;
309
+ const EVP_MD *md;
310
+ EVP_MD_CTX *ctx;
311
+ int result;
312
+
313
+ GetPKey(self, pkey);
314
+ md = GetDigestPtr(digest);
315
+ StringValue(sig);
316
+ StringValue(data);
317
+
318
+ ctx = EVP_MD_CTX_new();
319
+ if (!ctx)
320
+ ossl_raise(ePKeyError, "EVP_MD_CTX_new");
321
+ EVP_VerifyInit(ctx, md);
322
+ EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
323
+ result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
324
+ EVP_MD_CTX_free(ctx);
325
+ switch (result) {
326
+ case 0:
327
+ ossl_clear_error();
328
+ return Qfalse;
329
+ case 1:
330
+ return Qtrue;
331
+ default:
332
+ ossl_raise(ePKeyError, NULL);
333
+ }
334
+ return Qnil; /* dummy */
335
+ }
336
+
337
+ /*
338
+ * INIT
339
+ */
340
+ void
341
+ Init_ossl_pkey(void)
342
+ {
343
+ #if 0
344
+ mOSSL = rb_define_module("OpenSSL");
345
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
346
+ #endif
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 decrypted 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
+ */
399
+ mPKey = rb_define_module_under(mOSSL, "PKey");
400
+
401
+ /* Document-class: OpenSSL::PKey::PKeyError
402
+ *
403
+ *Raised when errors occur during PKey#sign or PKey#verify.
404
+ */
405
+ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
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
+ */
416
+ cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
417
+
418
+ rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
419
+
420
+ rb_define_alloc_func(cPKey, ossl_pkey_alloc);
421
+ rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
422
+
423
+ rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
424
+ rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
425
+
426
+ id_private_q = rb_intern("private?");
427
+
428
+ /*
429
+ * INIT rsa, dsa, dh, ec
430
+ */
431
+ Init_ossl_rsa();
432
+ Init_ossl_dsa();
433
+ Init_ossl_dh();
434
+ Init_ossl_ec();
435
+ }