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,59 @@
1
+ /*
2
+ * $Id: ossl_asn1.h 11708 2007-02-12 23:01:19Z shyouhei $
3
+ * 'OpenSSL for Ruby' team members
4
+ * Copyright (C) 2003
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(_OSSL_ASN1_H_)
12
+ #define _OSSL_ASN1_H_
13
+
14
+ /*
15
+ * ASN1_DATE conversions
16
+ */
17
+ VALUE asn1time_to_time(ASN1_TIME *);
18
+ time_t time_to_time_t(VALUE);
19
+
20
+ /*
21
+ * ASN1_STRING conversions
22
+ */
23
+ VALUE asn1str_to_str(ASN1_STRING *);
24
+
25
+ /*
26
+ * ASN1_INTEGER conversions
27
+ */
28
+ VALUE asn1integer_to_num(ASN1_INTEGER *);
29
+ ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *);
30
+
31
+ /*
32
+ * ASN1 module
33
+ */
34
+ extern VALUE mASN1;
35
+ extern VALUE eASN1Error;
36
+
37
+ extern VALUE cASN1Data;
38
+ extern VALUE cASN1Primitive;
39
+ extern VALUE cASN1Constructive;
40
+
41
+ extern VALUE cASN1Boolean; /* BOOLEAN */
42
+ extern VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
43
+ extern VALUE cASN1BitString; /* BIT STRING */
44
+ extern VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
45
+ extern VALUE cASN1NumericString, cASN1PrintableString;
46
+ extern VALUE cASN1T61String, cASN1VideotexString;
47
+ extern VALUE cASN1IA5String, cASN1GraphicString;
48
+ extern VALUE cASN1ISO64String, cASN1GeneralString;
49
+ extern VALUE cASN1UniversalString, cASN1BMPString;
50
+ extern VALUE cASN1Null; /* NULL */
51
+ extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
52
+ extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
53
+ extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
54
+
55
+ ASN1_TYPE *ossl_asn1_get_asn1type(VALUE);
56
+
57
+ void Init_ossl_asn1(void);
58
+
59
+ #endif
@@ -0,0 +1,86 @@
1
+ /*
2
+ * $Id: ossl_bio.c 12496 2007-06-08 15:02:04Z technorama $
3
+ * 'OpenSSL for Ruby' team members
4
+ * Copyright (C) 2003
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ #include "ossl.h"
12
+ #ifdef HAVE_UNISTD_H
13
+ #include <unistd.h>
14
+ #endif
15
+
16
+ BIO *
17
+ ossl_obj2bio(VALUE obj)
18
+ {
19
+ BIO *bio;
20
+
21
+ if (TYPE(obj) == T_FILE) {
22
+ rb_io_t *fptr;
23
+ FILE *fp;
24
+ int fd;
25
+
26
+ GetOpenFile(obj, fptr);
27
+ rb_io_check_readable(fptr);
28
+ if ((fd = dup(FPTR_TO_FD(fptr))) < 0){
29
+ rb_sys_fail(0);
30
+ }
31
+ if (!(fp = fdopen(fd, "r"))){
32
+ close(fd);
33
+ rb_sys_fail(0);
34
+ }
35
+ if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
36
+ fclose(fp);
37
+ ossl_raise(eOSSLError, NULL);
38
+ }
39
+ }
40
+ else {
41
+ StringValue(obj);
42
+ bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LEN(obj));
43
+ if (!bio) ossl_raise(eOSSLError, NULL);
44
+ }
45
+
46
+ return bio;
47
+ }
48
+
49
+ BIO *
50
+ ossl_protect_obj2bio(VALUE obj, int *status)
51
+ {
52
+ BIO *ret = NULL;
53
+ ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status);
54
+ return ret;
55
+ }
56
+
57
+ VALUE
58
+ ossl_membio2str0(BIO *bio)
59
+ {
60
+ VALUE ret;
61
+ BUF_MEM *buf;
62
+
63
+ BIO_get_mem_ptr(bio, &buf);
64
+ ret = rb_str_new(buf->data, buf->length);
65
+
66
+ return ret;
67
+ }
68
+
69
+ VALUE
70
+ ossl_protect_membio2str(BIO *bio, int *status)
71
+ {
72
+ return rb_protect((VALUE(*)_((VALUE)))ossl_membio2str0, (VALUE)bio, status);
73
+ }
74
+
75
+ VALUE
76
+ ossl_membio2str(BIO *bio)
77
+ {
78
+ VALUE ret;
79
+ int status = 0;
80
+
81
+ ret = ossl_protect_membio2str(bio, &status);
82
+ BIO_free(bio);
83
+ if(status) rb_jump_tag(status);
84
+
85
+ return ret;
86
+ }
@@ -0,0 +1,21 @@
1
+ /*
2
+ * $Id: ossl_bio.h 11708 2007-02-12 23:01:19Z shyouhei $
3
+ * 'OpenSSL for Ruby' team members
4
+ * Copyright (C) 2003
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(_OSSL_BIO_H_)
12
+ #define _OSSL_BIO_H_
13
+
14
+ BIO *ossl_obj2bio(VALUE);
15
+ BIO *ossl_protect_obj2bio(VALUE,int*);
16
+ VALUE ossl_membio2str0(BIO*);
17
+ VALUE ossl_membio2str(BIO*);
18
+ VALUE ossl_protect_membio2str(BIO*,int*);
19
+
20
+ #endif
21
+
@@ -0,0 +1,852 @@
1
+ /*
2
+ * $Id: ossl_bn.c 31657 2011-05-20 22:25:35Z shyouhei $
3
+ * 'OpenSSL for Ruby' project
4
+ * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net>
5
+ * All rights reserved.
6
+ */
7
+ /*
8
+ * This program is licenced under the same licence as Ruby.
9
+ * (See the file 'LICENCE'.)
10
+ */
11
+ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
12
+ #include "ossl.h"
13
+
14
+ #define WrapBN(klass, obj, bn) do { \
15
+ if (!bn) { \
16
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
17
+ } \
18
+ obj = Data_Wrap_Struct(klass, 0, BN_clear_free, bn); \
19
+ } while (0)
20
+
21
+ #define GetBN(obj, bn) do { \
22
+ Data_Get_Struct(obj, BIGNUM, bn); \
23
+ if (!bn) { \
24
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
25
+ } \
26
+ } while (0)
27
+
28
+ #define SafeGetBN(obj, bn) do { \
29
+ OSSL_Check_Kind(obj, cBN); \
30
+ GetBN(obj, bn); \
31
+ } while (0)
32
+
33
+ /*
34
+ * Classes
35
+ */
36
+ VALUE cBN;
37
+ VALUE eBNError;
38
+
39
+ /*
40
+ * Public
41
+ */
42
+ VALUE
43
+ ossl_bn_new(const BIGNUM *bn)
44
+ {
45
+ BIGNUM *newbn;
46
+ VALUE obj;
47
+
48
+ newbn = bn ? BN_dup(bn) : BN_new();
49
+ if (!newbn) {
50
+ ossl_raise(eBNError, NULL);
51
+ }
52
+ WrapBN(cBN, obj, newbn);
53
+
54
+ return obj;
55
+ }
56
+
57
+ BIGNUM *
58
+ GetBNPtr(VALUE obj)
59
+ {
60
+ BIGNUM *bn = NULL;
61
+
62
+ if (RTEST(rb_obj_is_kind_of(obj, cBN))) {
63
+ GetBN(obj, bn);
64
+ } else switch (TYPE(obj)) {
65
+ case T_FIXNUM:
66
+ case T_BIGNUM:
67
+ obj = rb_String(obj);
68
+ if (!BN_dec2bn(&bn, StringValuePtr(obj))) {
69
+ ossl_raise(eBNError, NULL);
70
+ }
71
+ WrapBN(cBN, obj, bn); /* Handle potencial mem leaks */
72
+ break;
73
+ default:
74
+ ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
75
+ }
76
+ return bn;
77
+ }
78
+
79
+ /*
80
+ * Private
81
+ */
82
+ /*
83
+ * BN_CTX - is used in more difficult math. ops
84
+ * (Why just 1? Because Ruby itself isn't thread safe,
85
+ * we don't need to care about threads)
86
+ */
87
+ BN_CTX *ossl_bn_ctx;
88
+
89
+ static VALUE
90
+ ossl_bn_alloc(VALUE klass)
91
+ {
92
+ BIGNUM *bn;
93
+ VALUE obj;
94
+
95
+ if (!(bn = BN_new())) {
96
+ ossl_raise(eBNError, NULL);
97
+ }
98
+ WrapBN(klass, obj, bn);
99
+
100
+ return obj;
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * BN.new => aBN
106
+ * BN.new(bn) => aBN
107
+ * BN.new(string) => aBN
108
+ * BN.new(string, 0 | 2 | 10 | 16) => aBN
109
+ */
110
+ static VALUE
111
+ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
112
+ {
113
+ BIGNUM *bn;
114
+ VALUE str, bs;
115
+ int base = 10;
116
+
117
+ if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
118
+ base = NUM2INT(bs);
119
+ }
120
+ StringValue(str);
121
+ GetBN(self, bn);
122
+ if (RTEST(rb_obj_is_kind_of(str, cBN))) {
123
+ BIGNUM *other;
124
+
125
+ GetBN(str, other); /* Safe - we checked kind_of? above */
126
+ if (!BN_copy(bn, other)) {
127
+ ossl_raise(eBNError, NULL);
128
+ }
129
+ return self;
130
+ }
131
+
132
+ switch (base) {
133
+ case 0:
134
+ if (!BN_mpi2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
135
+ ossl_raise(eBNError, NULL);
136
+ }
137
+ break;
138
+ case 2:
139
+ if (!BN_bin2bn(RSTRING_PTR(str), RSTRING_LEN(str), bn)) {
140
+ ossl_raise(eBNError, NULL);
141
+ }
142
+ break;
143
+ case 10:
144
+ if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
145
+ ossl_raise(eBNError, NULL);
146
+ }
147
+ break;
148
+ case 16:
149
+ if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
150
+ ossl_raise(eBNError, NULL);
151
+ }
152
+ break;
153
+ default:
154
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
155
+ }
156
+ return self;
157
+ }
158
+
159
+ /*
160
+ * call-seq:
161
+ * bn.to_s => string
162
+ * bn.to_s(base) => string
163
+ *
164
+ * === Parameters
165
+ * * +base+ - integer
166
+ * * * Valid values:
167
+ * * * * 0 - MPI
168
+ * * * * 2 - binary
169
+ * * * * 10 - the default
170
+ * * * * 16 - hex
171
+ */
172
+ static VALUE
173
+ ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
174
+ {
175
+ BIGNUM *bn;
176
+ VALUE str, bs;
177
+ int base = 10, len;
178
+ char *buf;
179
+
180
+ if (rb_scan_args(argc, argv, "01", &bs) == 1) {
181
+ base = NUM2INT(bs);
182
+ }
183
+ GetBN(self, bn);
184
+ switch (base) {
185
+ case 0:
186
+ len = BN_bn2mpi(bn, NULL);
187
+ str = rb_str_new(0, len);
188
+ if (BN_bn2mpi(bn, RSTRING_PTR(str)) != len)
189
+ ossl_raise(eBNError, NULL);
190
+ break;
191
+ case 2:
192
+ len = BN_num_bytes(bn);
193
+ str = rb_str_new(0, len);
194
+ if (BN_bn2bin(bn, RSTRING_PTR(str)) != len)
195
+ ossl_raise(eBNError, NULL);
196
+ break;
197
+ case 10:
198
+ if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
199
+ str = ossl_buf2str(buf, strlen(buf));
200
+ break;
201
+ case 16:
202
+ if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
203
+ str = ossl_buf2str(buf, strlen(buf));
204
+ break;
205
+ default:
206
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
207
+ }
208
+
209
+ return str;
210
+ }
211
+
212
+ /*
213
+ * call-seq:
214
+ * bn.to_i => integer
215
+ */
216
+ static VALUE
217
+ ossl_bn_to_i(VALUE self)
218
+ {
219
+ BIGNUM *bn;
220
+ char *txt;
221
+ VALUE num;
222
+
223
+ GetBN(self, bn);
224
+
225
+ if (!(txt = BN_bn2dec(bn))) {
226
+ ossl_raise(eBNError, NULL);
227
+ }
228
+ num = rb_cstr_to_inum(txt, 10, Qtrue);
229
+ OPENSSL_free(txt);
230
+
231
+ return num;
232
+ }
233
+
234
+ static VALUE
235
+ ossl_bn_to_bn(VALUE self)
236
+ {
237
+ return self;
238
+ }
239
+
240
+ static VALUE
241
+ ossl_bn_coerce(VALUE self, VALUE other)
242
+ {
243
+ switch(TYPE(other)) {
244
+ case T_STRING:
245
+ self = ossl_bn_to_s(0, NULL, self);
246
+ break;
247
+ case T_FIXNUM:
248
+ case T_BIGNUM:
249
+ self = ossl_bn_to_i(self);
250
+ break;
251
+ default:
252
+ if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
253
+ ossl_raise(rb_eTypeError, "Don't know how to coerce");
254
+ }
255
+ }
256
+ return rb_assoc_new(other, self);
257
+ }
258
+
259
+ #define BIGNUM_BOOL1(func) \
260
+ /* \
261
+ * call-seq: \
262
+ * bn.##func -> true | false \
263
+ * \
264
+ */ \
265
+ static VALUE \
266
+ ossl_bn_##func(VALUE self) \
267
+ { \
268
+ BIGNUM *bn; \
269
+ GetBN(self, bn); \
270
+ if (BN_##func(bn)) { \
271
+ return Qtrue; \
272
+ } \
273
+ return Qfalse; \
274
+ }
275
+ BIGNUM_BOOL1(is_zero)
276
+ BIGNUM_BOOL1(is_one)
277
+ BIGNUM_BOOL1(is_odd)
278
+
279
+ #define BIGNUM_1c(func) \
280
+ /* \
281
+ * call-seq: \
282
+ * bn.##func -> aBN \
283
+ * \
284
+ */ \
285
+ static VALUE \
286
+ ossl_bn_##func(VALUE self) \
287
+ { \
288
+ BIGNUM *bn, *result; \
289
+ VALUE obj; \
290
+ GetBN(self, bn); \
291
+ if (!(result = BN_new())) { \
292
+ ossl_raise(eBNError, NULL); \
293
+ } \
294
+ if (!BN_##func(result, bn, ossl_bn_ctx)) { \
295
+ BN_free(result); \
296
+ ossl_raise(eBNError, NULL); \
297
+ } \
298
+ WrapBN(CLASS_OF(self), obj, result); \
299
+ return obj; \
300
+ }
301
+ BIGNUM_1c(sqr)
302
+
303
+ #define BIGNUM_2(func) \
304
+ /* \
305
+ * call-seq: \
306
+ * bn.##func(bn2) -> aBN \
307
+ * \
308
+ */ \
309
+ static VALUE \
310
+ ossl_bn_##func(VALUE self, VALUE other) \
311
+ { \
312
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
313
+ VALUE obj; \
314
+ GetBN(self, bn1); \
315
+ if (!(result = BN_new())) { \
316
+ ossl_raise(eBNError, NULL); \
317
+ } \
318
+ if (!BN_##func(result, bn1, bn2)) { \
319
+ BN_free(result); \
320
+ ossl_raise(eBNError, NULL); \
321
+ } \
322
+ WrapBN(CLASS_OF(self), obj, result); \
323
+ return obj; \
324
+ }
325
+ BIGNUM_2(add)
326
+ BIGNUM_2(sub)
327
+
328
+ #define BIGNUM_2c(func) \
329
+ /* \
330
+ * call-seq: \
331
+ * bn.##func(bn2) -> aBN \
332
+ * \
333
+ */ \
334
+ static VALUE \
335
+ ossl_bn_##func(VALUE self, VALUE other) \
336
+ { \
337
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
338
+ VALUE obj; \
339
+ GetBN(self, bn1); \
340
+ if (!(result = BN_new())) { \
341
+ ossl_raise(eBNError, NULL); \
342
+ } \
343
+ if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
344
+ BN_free(result); \
345
+ ossl_raise(eBNError, NULL); \
346
+ } \
347
+ WrapBN(CLASS_OF(self), obj, result); \
348
+ return obj; \
349
+ }
350
+ BIGNUM_2c(mul)
351
+ BIGNUM_2c(mod)
352
+ BIGNUM_2c(exp)
353
+ BIGNUM_2c(gcd)
354
+ BIGNUM_2c(mod_sqr)
355
+ BIGNUM_2c(mod_inverse)
356
+
357
+ /*
358
+ * call-seq:
359
+ * bn1 / bn2 => [result, remainder]
360
+ */
361
+ static VALUE
362
+ ossl_bn_div(VALUE self, VALUE other)
363
+ {
364
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
365
+ VALUE obj1, obj2;
366
+
367
+ GetBN(self, bn1);
368
+
369
+ if (!(r1 = BN_new())) {
370
+ ossl_raise(eBNError, NULL);
371
+ }
372
+ if (!(r2 = BN_new())) {
373
+ BN_free(r1);
374
+ ossl_raise(eBNError, NULL);
375
+ }
376
+ if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
377
+ BN_free(r1);
378
+ BN_free(r2);
379
+ ossl_raise(eBNError, NULL);
380
+ }
381
+ WrapBN(CLASS_OF(self), obj1, r1);
382
+ WrapBN(CLASS_OF(self), obj2, r2);
383
+
384
+ return rb_ary_new3(2, obj1, obj2);
385
+ }
386
+
387
+ #define BIGNUM_3c(func) \
388
+ /* \
389
+ * call-seq: \
390
+ * bn.##func(bn1, bn2) -> aBN \
391
+ * \
392
+ */ \
393
+ static VALUE \
394
+ ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
395
+ { \
396
+ BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
397
+ BIGNUM *bn3 = GetBNPtr(other2), *result; \
398
+ VALUE obj; \
399
+ GetBN(self, bn1); \
400
+ if (!(result = BN_new())) { \
401
+ ossl_raise(eBNError, NULL); \
402
+ } \
403
+ if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
404
+ BN_free(result); \
405
+ ossl_raise(eBNError, NULL); \
406
+ } \
407
+ WrapBN(CLASS_OF(self), obj, result); \
408
+ return obj; \
409
+ }
410
+ BIGNUM_3c(mod_add)
411
+ BIGNUM_3c(mod_sub)
412
+ BIGNUM_3c(mod_mul)
413
+ BIGNUM_3c(mod_exp)
414
+
415
+ #define BIGNUM_BIT(func) \
416
+ /* \
417
+ * call-seq: \
418
+ * bn.##func(bit) -> self \
419
+ * \
420
+ */ \
421
+ static VALUE \
422
+ ossl_bn_##func(VALUE self, VALUE bit) \
423
+ { \
424
+ BIGNUM *bn; \
425
+ GetBN(self, bn); \
426
+ if (!BN_##func(bn, NUM2INT(bit))) { \
427
+ ossl_raise(eBNError, NULL); \
428
+ } \
429
+ return self; \
430
+ }
431
+ BIGNUM_BIT(set_bit)
432
+ BIGNUM_BIT(clear_bit)
433
+ BIGNUM_BIT(mask_bits)
434
+
435
+ /*
436
+ * call-seq:
437
+ * bn.bit_set?(bit) => true | false
438
+ */
439
+ static VALUE
440
+ ossl_bn_is_bit_set(VALUE self, VALUE bit)
441
+ {
442
+ int b;
443
+ BIGNUM *bn;
444
+
445
+ b = NUM2INT(bit);
446
+ GetBN(self, bn);
447
+ if (BN_is_bit_set(bn, b)) {
448
+ return Qtrue;
449
+ }
450
+ return Qfalse;
451
+ }
452
+
453
+ #define BIGNUM_SHIFT(func) \
454
+ /* \
455
+ * call-seq: \
456
+ * bn.##func(bits) -> aBN \
457
+ * \
458
+ */ \
459
+ static VALUE \
460
+ ossl_bn_##func(VALUE self, VALUE bits) \
461
+ { \
462
+ BIGNUM *bn, *result; \
463
+ int b; \
464
+ VALUE obj; \
465
+ b = NUM2INT(bits); \
466
+ GetBN(self, bn); \
467
+ if (!(result = BN_new())) { \
468
+ ossl_raise(eBNError, NULL); \
469
+ } \
470
+ if (!BN_##func(result, bn, b)) { \
471
+ BN_free(result); \
472
+ ossl_raise(eBNError, NULL); \
473
+ } \
474
+ WrapBN(CLASS_OF(self), obj, result); \
475
+ return obj; \
476
+ }
477
+ BIGNUM_SHIFT(lshift)
478
+ BIGNUM_SHIFT(rshift)
479
+
480
+ #define BIGNUM_SELF_SHIFT(func) \
481
+ /* \
482
+ * call-seq: \
483
+ * bn.##func!(bits) -> self \
484
+ * \
485
+ */ \
486
+ static VALUE \
487
+ ossl_bn_self_##func(VALUE self, VALUE bits) \
488
+ { \
489
+ BIGNUM *bn; \
490
+ int b; \
491
+ b = NUM2INT(bits); \
492
+ GetBN(self, bn); \
493
+ if (!BN_##func(bn, bn, b)) \
494
+ ossl_raise(eBNError, NULL); \
495
+ return self; \
496
+ }
497
+ BIGNUM_SELF_SHIFT(lshift)
498
+ BIGNUM_SELF_SHIFT(rshift)
499
+
500
+ #define BIGNUM_RAND(func) \
501
+ /* \
502
+ * call-seq: \
503
+ * BN.##func(bits [, fill [, odd]]) -> aBN \
504
+ * \
505
+ */ \
506
+ static VALUE \
507
+ ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
508
+ { \
509
+ BIGNUM *result; \
510
+ int bottom = 0, top = 0, b; \
511
+ VALUE bits, fill, odd, obj; \
512
+ \
513
+ switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
514
+ case 3: \
515
+ bottom = (odd == Qtrue) ? 1 : 0; \
516
+ /* FALLTHROUGH */ \
517
+ case 2: \
518
+ top = NUM2INT(fill); \
519
+ } \
520
+ b = NUM2INT(bits); \
521
+ if (!(result = BN_new())) { \
522
+ ossl_raise(eBNError, NULL); \
523
+ } \
524
+ if (!BN_##func(result, b, top, bottom)) { \
525
+ BN_free(result); \
526
+ ossl_raise(eBNError, NULL); \
527
+ } \
528
+ WrapBN(klass, obj, result); \
529
+ return obj; \
530
+ }
531
+ BIGNUM_RAND(rand)
532
+ BIGNUM_RAND(pseudo_rand)
533
+
534
+ #define BIGNUM_RAND_RANGE(func) \
535
+ /* \
536
+ * call-seq: \
537
+ * BN.##func(range) -> aBN \
538
+ * \
539
+ */ \
540
+ static VALUE \
541
+ ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
542
+ { \
543
+ BIGNUM *bn = GetBNPtr(range), *result; \
544
+ VALUE obj; \
545
+ if (!(result = BN_new())) { \
546
+ ossl_raise(eBNError, NULL); \
547
+ } \
548
+ if (!BN_##func##_range(result, bn)) { \
549
+ BN_free(result); \
550
+ ossl_raise(eBNError, NULL); \
551
+ } \
552
+ WrapBN(klass, obj, result); \
553
+ return obj; \
554
+ }
555
+ BIGNUM_RAND_RANGE(rand)
556
+ BIGNUM_RAND_RANGE(pseudo_rand)
557
+
558
+ /*
559
+ * call-seq:
560
+ * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
561
+ *
562
+ * === Parameters
563
+ * * +bits+ - integer
564
+ * * +safe+ - boolean
565
+ * * +add+ - BN
566
+ * * +rem+ - BN
567
+ */
568
+ static VALUE
569
+ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
570
+ {
571
+ BIGNUM *add = NULL, *rem = NULL, *result;
572
+ int safe = 1, num;
573
+ VALUE vnum, vsafe, vadd, vrem, obj;
574
+
575
+ rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
576
+
577
+ num = NUM2INT(vnum);
578
+
579
+ if (vsafe == Qfalse) {
580
+ safe = 0;
581
+ }
582
+ if (!NIL_P(vadd)) {
583
+ add = GetBNPtr(vadd);
584
+ rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
585
+ }
586
+ if (!(result = BN_new())) {
587
+ ossl_raise(eBNError, NULL);
588
+ }
589
+ if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) {
590
+ BN_free(result);
591
+ ossl_raise(eBNError, NULL);
592
+ }
593
+ WrapBN(klass, obj, result);
594
+
595
+ return obj;
596
+ }
597
+
598
+ #define BIGNUM_NUM(func) \
599
+ /* \
600
+ * call-seq: \
601
+ * bn.##func -> integer \
602
+ * \
603
+ */ \
604
+ static VALUE \
605
+ ossl_bn_##func(VALUE self) \
606
+ { \
607
+ BIGNUM *bn; \
608
+ GetBN(self, bn); \
609
+ return INT2FIX(BN_##func(bn)); \
610
+ }
611
+ BIGNUM_NUM(num_bytes)
612
+ BIGNUM_NUM(num_bits)
613
+
614
+ static VALUE
615
+ ossl_bn_copy(VALUE self, VALUE other)
616
+ {
617
+ BIGNUM *bn1, *bn2;
618
+
619
+ rb_check_frozen(self);
620
+
621
+ if (self == other) return self;
622
+
623
+ GetBN(self, bn1);
624
+ bn2 = GetBNPtr(other);
625
+
626
+ if (!BN_copy(bn1, bn2)) {
627
+ ossl_raise(eBNError, NULL);
628
+ }
629
+ return self;
630
+ }
631
+
632
+ #define BIGNUM_CMP(func) \
633
+ /* \
634
+ * call-seq: \
635
+ * bn.##func(bn2) -> integer \
636
+ * \
637
+ */ \
638
+ static VALUE \
639
+ ossl_bn_##func(VALUE self, VALUE other) \
640
+ { \
641
+ BIGNUM *bn1, *bn2 = GetBNPtr(other); \
642
+ GetBN(self, bn1); \
643
+ return INT2FIX(BN_##func(bn1, bn2)); \
644
+ }
645
+ BIGNUM_CMP(cmp)
646
+ BIGNUM_CMP(ucmp)
647
+
648
+ static VALUE
649
+ ossl_bn_eql(VALUE self, VALUE other)
650
+ {
651
+ if (ossl_bn_cmp(self, other) == INT2FIX(0)) {
652
+ return Qtrue;
653
+ }
654
+ return Qfalse;
655
+ }
656
+
657
+ /*
658
+ * call-seq:
659
+ * bn.prime? => true | false
660
+ * bn.prime?(checks) => true | false
661
+ *
662
+ * === Parameters
663
+ * * +checks+ - integer
664
+ */
665
+ static VALUE
666
+ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
667
+ {
668
+ BIGNUM *bn;
669
+ VALUE vchecks;
670
+ int checks = BN_prime_checks;
671
+
672
+ if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
673
+ checks = NUM2INT(vchecks);
674
+ }
675
+ GetBN(self, bn);
676
+ switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) {
677
+ case 1:
678
+ return Qtrue;
679
+ case 0:
680
+ return Qfalse;
681
+ default:
682
+ ossl_raise(eBNError, NULL);
683
+ }
684
+ /* not reachable */
685
+ return Qnil;
686
+ }
687
+
688
+ /*
689
+ * call-seq:
690
+ * bn.prime_fasttest? => true | false
691
+ * bn.prime_fasttest?(checks) => true | false
692
+ * bn.prime_fasttest?(checks, trial_div) => true | false
693
+ *
694
+ * === Parameters
695
+ * * +checks+ - integer
696
+ * * +trial_div+ - boolean
697
+ */
698
+ static VALUE
699
+ ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
700
+ {
701
+ BIGNUM *bn;
702
+ VALUE vchecks, vtrivdiv;
703
+ int checks = BN_prime_checks, do_trial_division = 1;
704
+
705
+ rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
706
+
707
+ if (!NIL_P(vchecks)) {
708
+ checks = NUM2INT(vchecks);
709
+ }
710
+ GetBN(self, bn);
711
+ /* handle true/false */
712
+ if (vtrivdiv == Qfalse) {
713
+ do_trial_division = 0;
714
+ }
715
+ switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) {
716
+ case 1:
717
+ return Qtrue;
718
+ case 0:
719
+ return Qfalse;
720
+ default:
721
+ ossl_raise(eBNError, NULL);
722
+ }
723
+ /* not reachable */
724
+ return Qnil;
725
+ }
726
+
727
+ /*
728
+ * INIT
729
+ * (NOTE: ordering of methods is the same as in 'man bn')
730
+ */
731
+ void
732
+ Init_ossl_bn()
733
+ {
734
+ #if 0 /* let rdoc know about mOSSL */
735
+ mOSSL = rb_define_module("OpenSSL");
736
+ #endif
737
+
738
+ if (!(ossl_bn_ctx = BN_CTX_new())) {
739
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
740
+ }
741
+
742
+ eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
743
+
744
+ cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
745
+
746
+ rb_define_alloc_func(cBN, ossl_bn_alloc);
747
+ rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
748
+
749
+ rb_define_copy_func(cBN, ossl_bn_copy);
750
+ rb_define_method(cBN, "copy", ossl_bn_copy, 1);
751
+
752
+ /* swap (=coerce?) */
753
+
754
+ rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
755
+ rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
756
+ /* num_bits_word */
757
+
758
+ rb_define_method(cBN, "+", ossl_bn_add, 1);
759
+ rb_define_method(cBN, "-", ossl_bn_sub, 1);
760
+ rb_define_method(cBN, "*", ossl_bn_mul, 1);
761
+ rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
762
+ rb_define_method(cBN, "/", ossl_bn_div, 1);
763
+ rb_define_method(cBN, "%", ossl_bn_mod, 1);
764
+ /* nnmod */
765
+
766
+ rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
767
+ rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
768
+ rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
769
+ rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
770
+ rb_define_method(cBN, "**", ossl_bn_exp, 1);
771
+ rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
772
+ rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
773
+
774
+ /* add_word
775
+ * sub_word
776
+ * mul_word
777
+ * div_word
778
+ * mod_word */
779
+
780
+ rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
781
+ rb_define_alias(cBN, "<=>", "cmp");
782
+ rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
783
+ rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
784
+ rb_define_alias(cBN, "==", "eql?");
785
+ rb_define_alias(cBN, "===", "eql?");
786
+ rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
787
+ rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
788
+ /* is_word */
789
+ rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
790
+
791
+ /* zero
792
+ * one
793
+ * value_one - DON'T IMPL.
794
+ * set_word
795
+ * get_word */
796
+
797
+ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
798
+ rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
799
+ rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
800
+ rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
801
+
802
+ rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
803
+ rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
804
+
805
+ rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
806
+ rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
807
+ rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
808
+ rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
809
+ rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
810
+ rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
811
+ rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
812
+ rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
813
+ /* lshift1 - DON'T IMPL. */
814
+ /* rshift1 - DON'T IMPL. */
815
+
816
+ /*
817
+ * bn2bin
818
+ * bin2bn
819
+ * bn2hex
820
+ * bn2dec
821
+ * hex2bn
822
+ * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
823
+ * print - NOT IMPL.
824
+ * print_fp - NOT IMPL.
825
+ * bn2mpi
826
+ * mpi2bn
827
+ */
828
+ rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
829
+ rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
830
+ rb_define_alias(cBN, "to_int", "to_i");
831
+ rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
832
+ rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
833
+
834
+ /*
835
+ * TODO:
836
+ * But how to: from_bin, from_mpi? PACK?
837
+ * to_bin
838
+ * to_mpi
839
+ */
840
+
841
+ rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
842
+
843
+ /* RECiProcal
844
+ * MONTgomery */
845
+
846
+ /*
847
+ * TODO:
848
+ * Where to belong these?
849
+ */
850
+ rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
851
+ }
852
+