rubysl-openssl 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +0 -1
  3. data/.travis.yml +7 -0
  4. data/README.md +2 -2
  5. data/Rakefile +0 -1
  6. data/ext/rubysl/openssl/extconf.h +50 -0
  7. data/ext/rubysl/openssl/extconf.rb +144 -0
  8. data/ext/rubysl/openssl/openssl_missing.c +343 -0
  9. data/ext/rubysl/openssl/openssl_missing.h +191 -0
  10. data/ext/rubysl/openssl/ossl.c +552 -0
  11. data/ext/rubysl/openssl/ossl.h +233 -0
  12. data/ext/rubysl/openssl/ossl_asn1.c +1160 -0
  13. data/ext/rubysl/openssl/ossl_asn1.h +59 -0
  14. data/ext/rubysl/openssl/ossl_bio.c +86 -0
  15. data/ext/rubysl/openssl/ossl_bio.h +21 -0
  16. data/ext/rubysl/openssl/ossl_bn.c +852 -0
  17. data/ext/rubysl/openssl/ossl_bn.h +25 -0
  18. data/ext/rubysl/openssl/ossl_cipher.c +569 -0
  19. data/ext/rubysl/openssl/ossl_cipher.h +22 -0
  20. data/ext/rubysl/openssl/ossl_config.c +75 -0
  21. data/ext/rubysl/openssl/ossl_config.h +22 -0
  22. data/ext/rubysl/openssl/ossl_digest.c +259 -0
  23. data/ext/rubysl/openssl/ossl_digest.h +22 -0
  24. data/ext/rubysl/openssl/ossl_engine.c +411 -0
  25. data/ext/rubysl/openssl/ossl_engine.h +20 -0
  26. data/ext/rubysl/openssl/ossl_hmac.c +268 -0
  27. data/ext/rubysl/openssl/ossl_hmac.h +19 -0
  28. data/ext/rubysl/openssl/ossl_ns_spki.c +257 -0
  29. data/ext/rubysl/openssl/ossl_ns_spki.h +21 -0
  30. data/ext/rubysl/openssl/ossl_ocsp.c +769 -0
  31. data/ext/rubysl/openssl/ossl_ocsp.h +24 -0
  32. data/ext/rubysl/openssl/ossl_pkcs12.c +210 -0
  33. data/ext/rubysl/openssl/ossl_pkcs12.h +15 -0
  34. data/ext/rubysl/openssl/ossl_pkcs5.c +99 -0
  35. data/ext/rubysl/openssl/ossl_pkcs5.h +6 -0
  36. data/ext/rubysl/openssl/ossl_pkcs7.c +1039 -0
  37. data/ext/rubysl/openssl/ossl_pkcs7.h +22 -0
  38. data/ext/rubysl/openssl/ossl_pkey.c +240 -0
  39. data/ext/rubysl/openssl/ossl_pkey.h +141 -0
  40. data/ext/rubysl/openssl/ossl_pkey_dh.c +532 -0
  41. data/ext/rubysl/openssl/ossl_pkey_dsa.c +484 -0
  42. data/ext/rubysl/openssl/ossl_pkey_ec.c +1593 -0
  43. data/ext/rubysl/openssl/ossl_pkey_rsa.c +593 -0
  44. data/ext/rubysl/openssl/ossl_rand.c +202 -0
  45. data/ext/rubysl/openssl/ossl_rand.h +20 -0
  46. data/ext/rubysl/openssl/ossl_ssl.c +1484 -0
  47. data/ext/rubysl/openssl/ossl_ssl.h +36 -0
  48. data/ext/rubysl/openssl/ossl_ssl_session.c +307 -0
  49. data/ext/rubysl/openssl/ossl_version.h +16 -0
  50. data/ext/rubysl/openssl/ossl_x509.c +104 -0
  51. data/ext/rubysl/openssl/ossl_x509.h +114 -0
  52. data/ext/rubysl/openssl/ossl_x509attr.c +274 -0
  53. data/ext/rubysl/openssl/ossl_x509cert.c +764 -0
  54. data/ext/rubysl/openssl/ossl_x509crl.c +535 -0
  55. data/ext/rubysl/openssl/ossl_x509ext.c +458 -0
  56. data/ext/rubysl/openssl/ossl_x509name.c +399 -0
  57. data/ext/rubysl/openssl/ossl_x509req.c +466 -0
  58. data/ext/rubysl/openssl/ossl_x509revoked.c +229 -0
  59. data/ext/rubysl/openssl/ossl_x509store.c +625 -0
  60. data/ext/rubysl/openssl/ruby_missing.h +41 -0
  61. data/lib/openssl.rb +1 -0
  62. data/lib/openssl/bn.rb +35 -0
  63. data/lib/openssl/buffering.rb +241 -0
  64. data/lib/openssl/cipher.rb +65 -0
  65. data/lib/openssl/config.rb +316 -0
  66. data/lib/openssl/digest.rb +61 -0
  67. data/lib/openssl/net/ftptls.rb +53 -0
  68. data/lib/openssl/net/telnets.rb +251 -0
  69. data/lib/openssl/pkcs7.rb +25 -0
  70. data/lib/openssl/ssl-internal.rb +187 -0
  71. data/lib/openssl/ssl.rb +1 -0
  72. data/lib/openssl/x509-internal.rb +153 -0
  73. data/lib/openssl/x509.rb +1 -0
  74. data/lib/rubysl/openssl.rb +28 -0
  75. data/lib/rubysl/openssl/version.rb +5 -0
  76. data/rubysl-openssl.gemspec +19 -18
  77. data/spec/cipher_spec.rb +16 -0
  78. data/spec/config/freeze_spec.rb +17 -0
  79. data/spec/hmac/digest_spec.rb +15 -0
  80. data/spec/hmac/hexdigest_spec.rb +15 -0
  81. data/spec/random/pseudo_bytes_spec.rb +5 -0
  82. data/spec/random/random_bytes_spec.rb +5 -0
  83. data/spec/random/shared/random_bytes.rb +28 -0
  84. data/spec/shared/constants.rb +11 -0
  85. data/spec/x509/name/parse_spec.rb +47 -0
  86. metadata +153 -89
  87. data/lib/rubysl-openssl.rb +0 -7
  88. data/lib/rubysl-openssl/version.rb +0 -5
@@ -0,0 +1,593 @@
1
+ /*
2
+ * $Id: ossl_pkey_rsa.c 28004 2010-05-24 23:58:49Z shyouhei $
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #if !defined(OPENSSL_NO_RSA)
12
+
13
+ #include "ossl.h"
14
+
15
+ #define GetPKeyRSA(obj, pkey) do { \
16
+ GetPKey(obj, pkey); \
17
+ if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) { /* PARANOIA? */ \
18
+ ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \
19
+ } \
20
+ } while (0)
21
+
22
+ #define RSA_HAS_PRIVATE(rsa) ((rsa)->p && (rsa)->q)
23
+ #define RSA_PRIVATE(obj,rsa) (RSA_HAS_PRIVATE(rsa)||OSSL_PKEY_IS_PRIVATE(obj))
24
+
25
+ /*
26
+ * Classes
27
+ */
28
+ VALUE cRSA;
29
+ VALUE eRSAError;
30
+
31
+ /*
32
+ * Public
33
+ */
34
+ static VALUE
35
+ rsa_instance(VALUE klass, RSA *rsa)
36
+ {
37
+ EVP_PKEY *pkey;
38
+ VALUE obj;
39
+
40
+ if (!rsa) {
41
+ return Qfalse;
42
+ }
43
+ if (!(pkey = EVP_PKEY_new())) {
44
+ return Qfalse;
45
+ }
46
+ if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
47
+ EVP_PKEY_free(pkey);
48
+ return Qfalse;
49
+ }
50
+ WrapPKey(klass, obj, pkey);
51
+
52
+ return obj;
53
+ }
54
+
55
+ VALUE
56
+ ossl_rsa_new(EVP_PKEY *pkey)
57
+ {
58
+ VALUE obj;
59
+
60
+ if (!pkey) {
61
+ obj = rsa_instance(cRSA, RSA_new());
62
+ }
63
+ else {
64
+ if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
65
+ ossl_raise(rb_eTypeError, "Not a RSA key!");
66
+ }
67
+ WrapPKey(cRSA, obj, pkey);
68
+ }
69
+ if (obj == Qfalse) {
70
+ ossl_raise(eRSAError, NULL);
71
+ }
72
+
73
+ return obj;
74
+ }
75
+
76
+ /*
77
+ * Private
78
+ */
79
+ static RSA *
80
+ rsa_generate(int size, int exp)
81
+ {
82
+ return RSA_generate_key(size, exp,
83
+ rb_block_given_p() ? ossl_generate_cb : NULL,
84
+ NULL);
85
+ }
86
+
87
+ /*
88
+ * call-seq:
89
+ * RSA.generate(size [, exponent]) -> rsa
90
+ *
91
+ * === Parameters
92
+ * * +size+ is an integer representing the desired key size. Keys smaller than 1024 should be considered insecure.
93
+ * * +exponent+ is an odd number normally 3, 17, or 65537.
94
+ *
95
+ */
96
+ static VALUE
97
+ ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass)
98
+ {
99
+ /* why does this method exist? why can't initialize take an optional exponent? */
100
+ RSA *rsa;
101
+ VALUE size, exp;
102
+ VALUE obj;
103
+
104
+ rb_scan_args(argc, argv, "11", &size, &exp);
105
+
106
+ rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2INT(exp)); /* err handled by rsa_instance */
107
+ obj = rsa_instance(klass, rsa);
108
+
109
+ if (obj == Qfalse) {
110
+ RSA_free(rsa);
111
+ ossl_raise(eRSAError, NULL);
112
+ }
113
+
114
+ return obj;
115
+ }
116
+
117
+ /*
118
+ * call-seq:
119
+ * RSA.new([size | encoded_key] [, pass]) -> rsa
120
+ *
121
+ * === Parameters
122
+ * * +size+ is an integer representing the desired key size.
123
+ * * +encoded_key+ is a string containing PEM or DER encoded key.
124
+ * * +pass+ is an optional string with the password to decrypt the encoded key.
125
+ *
126
+ * === Examples
127
+ * * RSA.new(2048) -> rsa
128
+ * * RSA.new(File.read("rsa.pem")) -> rsa
129
+ * * RSA.new(File.read("rsa.pem"), "mypassword") -> rsa
130
+ */
131
+ static VALUE
132
+ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
133
+ {
134
+ EVP_PKEY *pkey;
135
+ RSA *rsa;
136
+ BIO *in;
137
+ char *passwd = NULL;
138
+ VALUE arg, pass;
139
+
140
+ GetPKey(self, pkey);
141
+ if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
142
+ rsa = RSA_new();
143
+ }
144
+ else if (FIXNUM_P(arg)) {
145
+ rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
146
+ if (!rsa) ossl_raise(eRSAError, NULL);
147
+ }
148
+ else {
149
+ if (!NIL_P(pass)) passwd = StringValuePtr(pass);
150
+ arg = ossl_to_der_if_possible(arg);
151
+ in = ossl_obj2bio(arg);
152
+ rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
153
+ if (!rsa) {
154
+ BIO_reset(in);
155
+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
156
+ }
157
+ if (!rsa) {
158
+ BIO_reset(in);
159
+ rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
160
+ }
161
+ if (!rsa) {
162
+ BIO_reset(in);
163
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
164
+ }
165
+ if (!rsa) {
166
+ BIO_reset(in);
167
+ rsa = d2i_RSAPublicKey_bio(in, NULL);
168
+ }
169
+ if (!rsa) {
170
+ BIO_reset(in);
171
+ rsa = d2i_RSA_PUBKEY_bio(in, NULL);
172
+ }
173
+ BIO_free(in);
174
+ if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
175
+ }
176
+ if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
177
+ RSA_free(rsa);
178
+ ossl_raise(eRSAError, NULL);
179
+ }
180
+
181
+ return self;
182
+ }
183
+
184
+ /*
185
+ * call-seq:
186
+ * rsa.public? -> true
187
+ *
188
+ * The return value is always true since every private key is also a public key.
189
+ *
190
+ */
191
+ static VALUE
192
+ ossl_rsa_is_public(VALUE self)
193
+ {
194
+ EVP_PKEY *pkey;
195
+
196
+ GetPKeyRSA(self, pkey);
197
+ /*
198
+ * This method should check for n and e. BUG.
199
+ */
200
+ return Qtrue;
201
+ }
202
+
203
+ /*
204
+ * call-seq:
205
+ * rsa.private? -> true | false
206
+ *
207
+ */
208
+ static VALUE
209
+ ossl_rsa_is_private(VALUE self)
210
+ {
211
+ EVP_PKEY *pkey;
212
+
213
+ GetPKeyRSA(self, pkey);
214
+
215
+ return (RSA_PRIVATE(self, pkey->pkey.rsa)) ? Qtrue : Qfalse;
216
+ }
217
+
218
+ /*
219
+ * call-seq:
220
+ * rsa.to_pem([cipher, pass]) -> aString
221
+ *
222
+ * === Parameters
223
+ * * +cipher+ is a Cipher object.
224
+ * * +pass+ is a string.
225
+ *
226
+ * === Examples
227
+ * * rsa.to_pem -> aString
228
+ * * rsa.to_pem(cipher, pass) -> aString
229
+ */
230
+ static VALUE
231
+ ossl_rsa_export(int argc, VALUE *argv, VALUE self)
232
+ {
233
+ EVP_PKEY *pkey;
234
+ BIO *out;
235
+ const EVP_CIPHER *ciph = NULL;
236
+ char *passwd = NULL;
237
+ VALUE cipher, pass, str;
238
+
239
+ GetPKeyRSA(self, pkey);
240
+
241
+ rb_scan_args(argc, argv, "02", &cipher, &pass);
242
+
243
+ if (!NIL_P(cipher)) {
244
+ ciph = GetCipherPtr(cipher);
245
+ if (!NIL_P(pass)) {
246
+ passwd = StringValuePtr(pass);
247
+ }
248
+ }
249
+ if (!(out = BIO_new(BIO_s_mem()))) {
250
+ ossl_raise(eRSAError, NULL);
251
+ }
252
+ if (RSA_HAS_PRIVATE(pkey->pkey.rsa)) {
253
+ if (!PEM_write_bio_RSAPrivateKey(out, pkey->pkey.rsa, ciph,
254
+ NULL, 0, ossl_pem_passwd_cb, passwd)) {
255
+ BIO_free(out);
256
+ ossl_raise(eRSAError, NULL);
257
+ }
258
+ } else {
259
+ if (!PEM_write_bio_RSAPublicKey(out, pkey->pkey.rsa)) {
260
+ BIO_free(out);
261
+ ossl_raise(eRSAError, NULL);
262
+ }
263
+ }
264
+ str = ossl_membio2str(out);
265
+
266
+ return str;
267
+ }
268
+
269
+ /*
270
+ * call-seq:
271
+ * rsa.to_der -> aString
272
+ *
273
+ */
274
+ static VALUE
275
+ ossl_rsa_to_der(VALUE self)
276
+ {
277
+ EVP_PKEY *pkey;
278
+ int (*i2d_func)_((const RSA*, unsigned char**));
279
+ unsigned char *p;
280
+ long len;
281
+ VALUE str;
282
+
283
+ GetPKeyRSA(self, pkey);
284
+ if(RSA_HAS_PRIVATE(pkey->pkey.rsa))
285
+ i2d_func = i2d_RSAPrivateKey;
286
+ else
287
+ i2d_func = i2d_RSAPublicKey;
288
+ if((len = i2d_func(pkey->pkey.rsa, NULL)) <= 0)
289
+ ossl_raise(eRSAError, NULL);
290
+ str = rb_str_new(0, len);
291
+ p = RSTRING_PTR(str);
292
+ if(i2d_func(pkey->pkey.rsa, &p) < 0)
293
+ ossl_raise(eRSAError, NULL);
294
+ ossl_str_adjust(str, p);
295
+
296
+ return str;
297
+ }
298
+
299
+ #define ossl_rsa_buf_size(pkey) (RSA_size((pkey)->pkey.rsa)+16)
300
+
301
+ /*
302
+ * call-seq:
303
+ * rsa.public_encrypt(string [, padding]) -> aString
304
+ *
305
+ */
306
+ static VALUE
307
+ ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
308
+ {
309
+ EVP_PKEY *pkey;
310
+ int buf_len, pad;
311
+ VALUE str, buffer, padding;
312
+
313
+ GetPKeyRSA(self, pkey);
314
+ rb_scan_args(argc, argv, "11", &buffer, &padding);
315
+ pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
316
+ StringValue(buffer);
317
+ str = rb_str_new(0, ossl_rsa_buf_size(pkey));
318
+ buf_len = RSA_public_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
319
+ RSTRING_PTR(str), pkey->pkey.rsa,
320
+ pad);
321
+ if (buf_len < 0) ossl_raise(eRSAError, NULL);
322
+ rb_str_set_len(str, buf_len);
323
+
324
+ return str;
325
+ }
326
+
327
+ /*
328
+ * call-seq:
329
+ * rsa.public_decrypt(string [, padding]) -> aString
330
+ *
331
+ */
332
+ static VALUE
333
+ ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
334
+ {
335
+ EVP_PKEY *pkey;
336
+ int buf_len, pad;
337
+ VALUE str, buffer, padding;
338
+
339
+ GetPKeyRSA(self, pkey);
340
+ rb_scan_args(argc, argv, "11", &buffer, &padding);
341
+ pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
342
+ StringValue(buffer);
343
+ str = rb_str_new(0, ossl_rsa_buf_size(pkey));
344
+ buf_len = RSA_public_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
345
+ RSTRING_PTR(str), pkey->pkey.rsa,
346
+ pad);
347
+ if (buf_len < 0) ossl_raise(eRSAError, NULL);
348
+ rb_str_set_len(str, buf_len);
349
+
350
+ return str;
351
+ }
352
+
353
+ /*
354
+ * call-seq:
355
+ * rsa.private_encrypt(string [, padding]) -> aString
356
+ *
357
+ */
358
+ static VALUE
359
+ ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
360
+ {
361
+ EVP_PKEY *pkey;
362
+ int buf_len, pad;
363
+ VALUE str, buffer, padding;
364
+
365
+ GetPKeyRSA(self, pkey);
366
+ if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
367
+ ossl_raise(eRSAError, "private key needed.");
368
+ }
369
+ rb_scan_args(argc, argv, "11", &buffer, &padding);
370
+ pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
371
+ StringValue(buffer);
372
+ str = rb_str_new(0, ossl_rsa_buf_size(pkey));
373
+ buf_len = RSA_private_encrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
374
+ RSTRING_PTR(str), pkey->pkey.rsa,
375
+ pad);
376
+ if (buf_len < 0) ossl_raise(eRSAError, NULL);
377
+ rb_str_set_len(str, buf_len);
378
+
379
+ return str;
380
+ }
381
+
382
+
383
+ /*
384
+ * call-seq:
385
+ * rsa.private_decrypt(string [, padding]) -> aString
386
+ *
387
+ */
388
+ static VALUE
389
+ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
390
+ {
391
+ EVP_PKEY *pkey;
392
+ int buf_len, pad;
393
+ VALUE str, buffer, padding;
394
+
395
+ GetPKeyRSA(self, pkey);
396
+ if (!RSA_PRIVATE(self, pkey->pkey.rsa)) {
397
+ ossl_raise(eRSAError, "private key needed.");
398
+ }
399
+ rb_scan_args(argc, argv, "11", &buffer, &padding);
400
+ pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
401
+ StringValue(buffer);
402
+ str = rb_str_new(0, ossl_rsa_buf_size(pkey));
403
+ buf_len = RSA_private_decrypt(RSTRING_LEN(buffer), RSTRING_PTR(buffer),
404
+ RSTRING_PTR(str), pkey->pkey.rsa,
405
+ pad);
406
+ if (buf_len < 0) ossl_raise(eRSAError, NULL);
407
+ rb_str_set_len(str, buf_len);
408
+
409
+ return str;
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * rsa.params -> hash
415
+ *
416
+ * Stores all parameters of key to the hash
417
+ * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
418
+ * Don't use :-)) (I's up to you)
419
+ */
420
+ static VALUE
421
+ ossl_rsa_get_params(VALUE self)
422
+ {
423
+ EVP_PKEY *pkey;
424
+ VALUE hash;
425
+
426
+ GetPKeyRSA(self, pkey);
427
+
428
+ hash = rb_hash_new();
429
+
430
+ rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(pkey->pkey.rsa->n));
431
+ rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(pkey->pkey.rsa->e));
432
+ rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(pkey->pkey.rsa->d));
433
+ rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.rsa->p));
434
+ rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.rsa->q));
435
+ rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(pkey->pkey.rsa->dmp1));
436
+ rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(pkey->pkey.rsa->dmq1));
437
+ rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(pkey->pkey.rsa->iqmp));
438
+
439
+ return hash;
440
+ }
441
+
442
+ /*
443
+ * call-seq:
444
+ * rsa.to_text -> aString
445
+ *
446
+ * Prints all parameters of key to buffer
447
+ * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
448
+ * Don't use :-)) (It's up to you)
449
+ */
450
+ static VALUE
451
+ ossl_rsa_to_text(VALUE self)
452
+ {
453
+ EVP_PKEY *pkey;
454
+ BIO *out;
455
+ VALUE str;
456
+
457
+ GetPKeyRSA(self, pkey);
458
+ if (!(out = BIO_new(BIO_s_mem()))) {
459
+ ossl_raise(eRSAError, NULL);
460
+ }
461
+ if (!RSA_print(out, pkey->pkey.rsa, 0)) { /* offset = 0 */
462
+ BIO_free(out);
463
+ ossl_raise(eRSAError, NULL);
464
+ }
465
+ str = ossl_membio2str(out);
466
+
467
+ return str;
468
+ }
469
+
470
+ /*
471
+ * call-seq:
472
+ * rsa.public_key -> aRSA
473
+ *
474
+ * Makes new instance RSA PUBLIC_KEY from PRIVATE_KEY
475
+ */
476
+ static VALUE
477
+ ossl_rsa_to_public_key(VALUE self)
478
+ {
479
+ EVP_PKEY *pkey;
480
+ RSA *rsa;
481
+ VALUE obj;
482
+
483
+ GetPKeyRSA(self, pkey);
484
+ /* err check performed by rsa_instance */
485
+ rsa = RSAPublicKey_dup(pkey->pkey.rsa);
486
+ obj = rsa_instance(CLASS_OF(self), rsa);
487
+ if (obj == Qfalse) {
488
+ RSA_free(rsa);
489
+ ossl_raise(eRSAError, NULL);
490
+ }
491
+ return obj;
492
+ }
493
+
494
+ /*
495
+ * TODO: Test me
496
+
497
+ static VALUE
498
+ ossl_rsa_blinding_on(VALUE self)
499
+ {
500
+ EVP_PKEY *pkey;
501
+
502
+ GetPKeyRSA(self, pkey);
503
+
504
+ if (RSA_blinding_on(pkey->pkey.rsa, ossl_bn_ctx) != 1) {
505
+ ossl_raise(eRSAError, NULL);
506
+ }
507
+ return self;
508
+ }
509
+
510
+ static VALUE
511
+ ossl_rsa_blinding_off(VALUE self)
512
+ {
513
+ EVP_PKEY *pkey;
514
+
515
+ GetPKeyRSA(self, pkey);
516
+ RSA_blinding_off(pkey->pkey.rsa);
517
+
518
+ return self;
519
+ }
520
+ */
521
+
522
+ OSSL_PKEY_BN(rsa, n)
523
+ OSSL_PKEY_BN(rsa, e)
524
+ OSSL_PKEY_BN(rsa, d)
525
+ OSSL_PKEY_BN(rsa, p)
526
+ OSSL_PKEY_BN(rsa, q)
527
+ OSSL_PKEY_BN(rsa, dmp1)
528
+ OSSL_PKEY_BN(rsa, dmq1)
529
+ OSSL_PKEY_BN(rsa, iqmp)
530
+
531
+ /*
532
+ * INIT
533
+ */
534
+ #define DefRSAConst(x) rb_define_const(cRSA, #x,INT2FIX(RSA_##x))
535
+
536
+ void
537
+ Init_ossl_rsa()
538
+ {
539
+ #if 0 /* let rdoc know about mOSSL and mPKey */
540
+ mOSSL = rb_define_module("OpenSSL");
541
+ mPKey = rb_define_module_under(mOSSL, "PKey");
542
+ #endif
543
+
544
+ eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError);
545
+
546
+ cRSA = rb_define_class_under(mPKey, "RSA", cPKey);
547
+
548
+ rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1);
549
+ rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1);
550
+
551
+ rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0);
552
+ rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0);
553
+ rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0);
554
+ rb_define_method(cRSA, "export", ossl_rsa_export, -1);
555
+ rb_define_alias(cRSA, "to_pem", "export");
556
+ rb_define_alias(cRSA, "to_s", "export");
557
+ rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
558
+ rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0);
559
+ rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
560
+ rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
561
+ rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
562
+ rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
563
+
564
+ DEF_OSSL_PKEY_BN(cRSA, rsa, n);
565
+ DEF_OSSL_PKEY_BN(cRSA, rsa, e);
566
+ DEF_OSSL_PKEY_BN(cRSA, rsa, d);
567
+ DEF_OSSL_PKEY_BN(cRSA, rsa, p);
568
+ DEF_OSSL_PKEY_BN(cRSA, rsa, q);
569
+ DEF_OSSL_PKEY_BN(cRSA, rsa, dmp1);
570
+ DEF_OSSL_PKEY_BN(cRSA, rsa, dmq1);
571
+ DEF_OSSL_PKEY_BN(cRSA, rsa, iqmp);
572
+
573
+ rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
574
+
575
+ DefRSAConst(PKCS1_PADDING);
576
+ DefRSAConst(SSLV23_PADDING);
577
+ DefRSAConst(NO_PADDING);
578
+ DefRSAConst(PKCS1_OAEP_PADDING);
579
+
580
+ /*
581
+ * TODO: Test it
582
+ rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);
583
+ rb_define_method(cRSA, "blinding_off!", ossl_rsa_blinding_off, 0);
584
+ */
585
+ }
586
+
587
+ #else /* defined NO_RSA */
588
+ void
589
+ Init_ossl_rsa()
590
+ {
591
+ }
592
+ #endif /* NO_RSA */
593
+