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,66 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' team members
3
+ * Copyright (C) 2003
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_ASN1_H_)
11
+ #define _OSSL_ASN1_H_
12
+
13
+ /*
14
+ * ASN1_DATE conversions
15
+ */
16
+ VALUE asn1time_to_time(const ASN1_TIME *);
17
+ #if defined(HAVE_ASN1_TIME_ADJ)
18
+ /* Splits VALUE to seconds and offset days. VALUE is typically a Time or an
19
+ * Integer. This is used when updating ASN1_*TIME with ASN1_TIME_adj() or
20
+ * X509_time_adj_ex(). We can't use ASN1_TIME_set() and X509_time_adj() because
21
+ * they have the Year 2038 issue on sizeof(time_t) == 4 environment */
22
+ void ossl_time_split(VALUE, time_t *, int *);
23
+ #else
24
+ time_t time_to_time_t(VALUE);
25
+ #endif
26
+
27
+ /*
28
+ * ASN1_STRING conversions
29
+ */
30
+ VALUE asn1str_to_str(const ASN1_STRING *);
31
+
32
+ /*
33
+ * ASN1_INTEGER conversions
34
+ */
35
+ VALUE asn1integer_to_num(const ASN1_INTEGER *);
36
+ ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *);
37
+
38
+ /*
39
+ * ASN1 module
40
+ */
41
+ extern VALUE mASN1;
42
+ extern VALUE eASN1Error;
43
+
44
+ extern VALUE cASN1Data;
45
+ extern VALUE cASN1Primitive;
46
+ extern VALUE cASN1Constructive;
47
+
48
+ extern VALUE cASN1Boolean; /* BOOLEAN */
49
+ extern VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */
50
+ extern VALUE cASN1BitString; /* BIT STRING */
51
+ extern VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */
52
+ extern VALUE cASN1NumericString, cASN1PrintableString;
53
+ extern VALUE cASN1T61String, cASN1VideotexString;
54
+ extern VALUE cASN1IA5String, cASN1GraphicString;
55
+ extern VALUE cASN1ISO64String, cASN1GeneralString;
56
+ extern VALUE cASN1UniversalString, cASN1BMPString;
57
+ extern VALUE cASN1Null; /* NULL */
58
+ extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */
59
+ extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */
60
+ extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */
61
+
62
+ ASN1_TYPE *ossl_asn1_get_asn1type(VALUE);
63
+
64
+ void Init_ossl_asn1(void);
65
+
66
+ #endif
@@ -0,0 +1,87 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' team members
3
+ * Copyright (C) 2003
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
+ #ifdef HAVE_UNISTD_H
12
+ #include <unistd.h>
13
+ #endif
14
+
15
+ BIO *
16
+ ossl_obj2bio(VALUE obj)
17
+ {
18
+ BIO *bio;
19
+
20
+ if (RB_TYPE_P(obj, T_FILE)) {
21
+ rb_io_t *fptr;
22
+ FILE *fp;
23
+ int fd;
24
+
25
+ GetOpenFile(obj, fptr);
26
+ rb_io_check_readable(fptr);
27
+ if ((fd = rb_cloexec_dup(FPTR_TO_FD(fptr))) < 0){
28
+ rb_sys_fail(0);
29
+ }
30
+ rb_update_max_fd(fd);
31
+ if (!(fp = fdopen(fd, "r"))){
32
+ int e = errno;
33
+ close(fd);
34
+ rb_syserr_fail(e, 0);
35
+ }
36
+ if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
37
+ fclose(fp);
38
+ ossl_raise(eOSSLError, NULL);
39
+ }
40
+ }
41
+ else {
42
+ StringValue(obj);
43
+ bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
44
+ if (!bio) ossl_raise(eOSSLError, NULL);
45
+ }
46
+
47
+ return bio;
48
+ }
49
+
50
+ BIO *
51
+ ossl_protect_obj2bio(VALUE obj, int *status)
52
+ {
53
+ BIO *ret = NULL;
54
+ ret = (BIO*)rb_protect((VALUE (*)(VALUE))ossl_obj2bio, obj, status);
55
+ return ret;
56
+ }
57
+
58
+ VALUE
59
+ ossl_membio2str0(BIO *bio)
60
+ {
61
+ VALUE ret;
62
+ BUF_MEM *buf;
63
+
64
+ BIO_get_mem_ptr(bio, &buf);
65
+ ret = rb_str_new(buf->data, buf->length);
66
+
67
+ return ret;
68
+ }
69
+
70
+ VALUE
71
+ ossl_protect_membio2str(BIO *bio, int *status)
72
+ {
73
+ return rb_protect((VALUE (*)(VALUE))ossl_membio2str0, (VALUE)bio, status);
74
+ }
75
+
76
+ VALUE
77
+ ossl_membio2str(BIO *bio)
78
+ {
79
+ VALUE ret;
80
+ int status = 0;
81
+
82
+ ret = ossl_protect_membio2str(bio, &status);
83
+ BIO_free(bio);
84
+ if(status) rb_jump_tag(status);
85
+
86
+ return ret;
87
+ }
@@ -0,0 +1,19 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' team members
3
+ * Copyright (C) 2003
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_BIO_H_)
11
+ #define _OSSL_BIO_H_
12
+
13
+ BIO *ossl_obj2bio(VALUE);
14
+ BIO *ossl_protect_obj2bio(VALUE,int*);
15
+ VALUE ossl_membio2str0(BIO*);
16
+ VALUE ossl_membio2str(BIO*);
17
+ VALUE ossl_protect_membio2str(BIO*,int*);
18
+
19
+ #endif
@@ -0,0 +1,1153 @@
1
+ /*
2
+ * 'OpenSSL for Ruby' project
3
+ * Copyright (C) 2001-2002 Technorama team <oss-ruby@technorama.net>
4
+ * All rights reserved.
5
+ */
6
+ /*
7
+ * This program is licensed under the same licence as Ruby.
8
+ * (See the file 'LICENCE'.)
9
+ */
10
+ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */
11
+ #include "ossl.h"
12
+
13
+ #define NewBN(klass) \
14
+ TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
15
+ #define SetBN(obj, bn) do { \
16
+ if (!(bn)) { \
17
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
18
+ } \
19
+ RTYPEDDATA_DATA(obj) = (bn); \
20
+ } while (0)
21
+
22
+ #define GetBN(obj, bn) do { \
23
+ TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \
24
+ if (!(bn)) { \
25
+ ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
26
+ } \
27
+ } while (0)
28
+
29
+ #define SafeGetBN(obj, bn) do { \
30
+ OSSL_Check_Kind((obj), cBN); \
31
+ GetBN((obj), (bn)); \
32
+ } while (0)
33
+
34
+ static void
35
+ ossl_bn_free(void *ptr)
36
+ {
37
+ BN_clear_free(ptr);
38
+ }
39
+
40
+ static const rb_data_type_t ossl_bn_type = {
41
+ "OpenSSL/BN",
42
+ {
43
+ 0, ossl_bn_free,
44
+ },
45
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
46
+ };
47
+
48
+ /*
49
+ * Classes
50
+ */
51
+ VALUE cBN;
52
+
53
+ /* Document-class: OpenSSL::BNError
54
+ *
55
+ * Generic Error for all of OpenSSL::BN (big num)
56
+ */
57
+ VALUE eBNError;
58
+
59
+ /*
60
+ * Public
61
+ */
62
+ VALUE
63
+ ossl_bn_new(const BIGNUM *bn)
64
+ {
65
+ BIGNUM *newbn;
66
+ VALUE obj;
67
+
68
+ obj = NewBN(cBN);
69
+ newbn = bn ? BN_dup(bn) : BN_new();
70
+ if (!newbn) {
71
+ ossl_raise(eBNError, NULL);
72
+ }
73
+ SetBN(obj, newbn);
74
+
75
+ return obj;
76
+ }
77
+
78
+ static BIGNUM *
79
+ integer_to_bnptr(VALUE obj, BIGNUM *orig)
80
+ {
81
+ BIGNUM *bn;
82
+
83
+ if (FIXNUM_P(obj)) {
84
+ long i;
85
+ unsigned char bin[sizeof(long)];
86
+ long n = FIX2LONG(obj);
87
+ unsigned long un = labs(n);
88
+
89
+ for (i = sizeof(long) - 1; 0 <= i; i--) {
90
+ bin[i] = un & 0xff;
91
+ un >>= 8;
92
+ }
93
+
94
+ bn = BN_bin2bn(bin, sizeof(bin), orig);
95
+ if (!bn)
96
+ ossl_raise(eBNError, "BN_bin2bn");
97
+ if (n < 0)
98
+ BN_set_negative(bn, 1);
99
+ }
100
+ else { /* assuming Bignum */
101
+ size_t len = rb_absint_size(obj, NULL);
102
+ unsigned char *bin;
103
+ VALUE buf;
104
+ int sign;
105
+
106
+ if (INT_MAX < len) {
107
+ rb_raise(eBNError, "bignum too long");
108
+ }
109
+ bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len);
110
+ sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN);
111
+
112
+ bn = BN_bin2bn(bin, (int)len, orig);
113
+ ALLOCV_END(buf);
114
+ if (!bn)
115
+ ossl_raise(eBNError, "BN_bin2bn");
116
+ if (sign < 0)
117
+ BN_set_negative(bn, 1);
118
+ }
119
+
120
+ return bn;
121
+ }
122
+
123
+ static BIGNUM *
124
+ try_convert_to_bnptr(VALUE obj)
125
+ {
126
+ BIGNUM *bn = NULL;
127
+ VALUE newobj;
128
+
129
+ if (rb_obj_is_kind_of(obj, cBN)) {
130
+ GetBN(obj, bn);
131
+ }
132
+ else if (RB_INTEGER_TYPE_P(obj)) {
133
+ newobj = NewBN(cBN); /* Handle potencial mem leaks */
134
+ bn = integer_to_bnptr(obj, NULL);
135
+ SetBN(newobj, bn);
136
+ }
137
+
138
+ return bn;
139
+ }
140
+
141
+ BIGNUM *
142
+ GetBNPtr(VALUE obj)
143
+ {
144
+ BIGNUM *bn = try_convert_to_bnptr(obj);
145
+ if (!bn)
146
+ ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
147
+
148
+ return bn;
149
+ }
150
+
151
+ /*
152
+ * Private
153
+ */
154
+ /*
155
+ * BN_CTX - is used in more difficult math. ops
156
+ * (Why just 1? Because Ruby itself isn't thread safe,
157
+ * we don't need to care about threads)
158
+ */
159
+ BN_CTX *ossl_bn_ctx;
160
+
161
+ static VALUE
162
+ ossl_bn_alloc(VALUE klass)
163
+ {
164
+ BIGNUM *bn;
165
+ VALUE obj = NewBN(klass);
166
+
167
+ if (!(bn = BN_new())) {
168
+ ossl_raise(eBNError, NULL);
169
+ }
170
+ SetBN(obj, bn);
171
+
172
+ return obj;
173
+ }
174
+
175
+ /* Document-method: OpenSSL::BN.new
176
+ *
177
+ * call-seq:
178
+ * OpenSSL::BN.new => aBN
179
+ * OpenSSL::BN.new(bn) => aBN
180
+ * OpenSSL::BN.new(integer) => aBN
181
+ * OpenSSL::BN.new(string) => aBN
182
+ * OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN
183
+ *
184
+ * Construct a new OpenSSL BigNum object.
185
+ */
186
+ static VALUE
187
+ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
188
+ {
189
+ BIGNUM *bn;
190
+ VALUE str, bs;
191
+ int base = 10;
192
+
193
+ if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
194
+ base = NUM2INT(bs);
195
+ }
196
+
197
+ if (RB_INTEGER_TYPE_P(str)) {
198
+ GetBN(self, bn);
199
+ integer_to_bnptr(str, bn);
200
+
201
+ return self;
202
+ }
203
+
204
+ if (RTEST(rb_obj_is_kind_of(str, cBN))) {
205
+ BIGNUM *other;
206
+
207
+ GetBN(self, bn);
208
+ GetBN(str, other); /* Safe - we checked kind_of? above */
209
+ if (!BN_copy(bn, other)) {
210
+ ossl_raise(eBNError, NULL);
211
+ }
212
+ return self;
213
+ }
214
+
215
+ GetBN(self, bn);
216
+ switch (base) {
217
+ case 0:
218
+ if (!BN_mpi2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
219
+ ossl_raise(eBNError, NULL);
220
+ }
221
+ break;
222
+ case 2:
223
+ if (!BN_bin2bn((unsigned char *)StringValuePtr(str), RSTRING_LENINT(str), bn)) {
224
+ ossl_raise(eBNError, NULL);
225
+ }
226
+ break;
227
+ case 10:
228
+ if (!BN_dec2bn(&bn, StringValueCStr(str))) {
229
+ ossl_raise(eBNError, NULL);
230
+ }
231
+ break;
232
+ case 16:
233
+ if (!BN_hex2bn(&bn, StringValueCStr(str))) {
234
+ ossl_raise(eBNError, NULL);
235
+ }
236
+ break;
237
+ default:
238
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
239
+ }
240
+ return self;
241
+ }
242
+
243
+ /*
244
+ * call-seq:
245
+ * bn.to_s => string
246
+ * bn.to_s(base) => string
247
+ *
248
+ * === Parameters
249
+ * * +base+ - integer
250
+ * Valid values:
251
+ * * 0 - MPI
252
+ * * 2 - binary
253
+ * * 10 - the default
254
+ * * 16 - hex
255
+ */
256
+ static VALUE
257
+ ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
258
+ {
259
+ BIGNUM *bn;
260
+ VALUE str, bs;
261
+ int base = 10, len;
262
+ char *buf;
263
+
264
+ if (rb_scan_args(argc, argv, "01", &bs) == 1) {
265
+ base = NUM2INT(bs);
266
+ }
267
+ GetBN(self, bn);
268
+ switch (base) {
269
+ case 0:
270
+ len = BN_bn2mpi(bn, NULL);
271
+ str = rb_str_new(0, len);
272
+ if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
273
+ ossl_raise(eBNError, NULL);
274
+ break;
275
+ case 2:
276
+ len = BN_num_bytes(bn);
277
+ str = rb_str_new(0, len);
278
+ if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
279
+ ossl_raise(eBNError, NULL);
280
+ break;
281
+ case 10:
282
+ if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
283
+ str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
284
+ break;
285
+ case 16:
286
+ if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
287
+ str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
288
+ break;
289
+ default:
290
+ ossl_raise(rb_eArgError, "invalid radix %d", base);
291
+ }
292
+
293
+ return str;
294
+ }
295
+
296
+ /*
297
+ * call-seq:
298
+ * bn.to_i => integer
299
+ */
300
+ static VALUE
301
+ ossl_bn_to_i(VALUE self)
302
+ {
303
+ BIGNUM *bn;
304
+ char *txt;
305
+ VALUE num;
306
+
307
+ GetBN(self, bn);
308
+
309
+ if (!(txt = BN_bn2hex(bn))) {
310
+ ossl_raise(eBNError, NULL);
311
+ }
312
+ num = rb_cstr_to_inum(txt, 16, Qtrue);
313
+ OPENSSL_free(txt);
314
+
315
+ return num;
316
+ }
317
+
318
+ static VALUE
319
+ ossl_bn_to_bn(VALUE self)
320
+ {
321
+ return self;
322
+ }
323
+
324
+ static VALUE
325
+ ossl_bn_coerce(VALUE self, VALUE other)
326
+ {
327
+ switch(TYPE(other)) {
328
+ case T_STRING:
329
+ self = ossl_bn_to_s(0, NULL, self);
330
+ break;
331
+ case T_FIXNUM:
332
+ case T_BIGNUM:
333
+ self = ossl_bn_to_i(self);
334
+ break;
335
+ default:
336
+ if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
337
+ ossl_raise(rb_eTypeError, "Don't know how to coerce");
338
+ }
339
+ }
340
+ return rb_assoc_new(other, self);
341
+ }
342
+
343
+ #define BIGNUM_BOOL1(func) \
344
+ static VALUE \
345
+ ossl_bn_##func(VALUE self) \
346
+ { \
347
+ BIGNUM *bn; \
348
+ GetBN(self, bn); \
349
+ if (BN_##func(bn)) { \
350
+ return Qtrue; \
351
+ } \
352
+ return Qfalse; \
353
+ }
354
+
355
+ /*
356
+ * Document-method: OpenSSL::BN#zero?
357
+ * call-seq:
358
+ * bn.zero? => true | false
359
+ */
360
+ BIGNUM_BOOL1(is_zero)
361
+
362
+ /*
363
+ * Document-method: OpenSSL::BN#one?
364
+ * call-seq:
365
+ * bn.one? => true | false
366
+ */
367
+ BIGNUM_BOOL1(is_one)
368
+
369
+ /*
370
+ * Document-method: OpenSSL::BN#odd?
371
+ * call-seq:
372
+ * bn.odd? => true | false
373
+ */
374
+ BIGNUM_BOOL1(is_odd)
375
+
376
+ #define BIGNUM_1c(func) \
377
+ static VALUE \
378
+ ossl_bn_##func(VALUE self) \
379
+ { \
380
+ BIGNUM *bn, *result; \
381
+ VALUE obj; \
382
+ GetBN(self, bn); \
383
+ obj = NewBN(CLASS_OF(self)); \
384
+ if (!(result = BN_new())) { \
385
+ ossl_raise(eBNError, NULL); \
386
+ } \
387
+ if (!BN_##func(result, bn, ossl_bn_ctx)) { \
388
+ BN_free(result); \
389
+ ossl_raise(eBNError, NULL); \
390
+ } \
391
+ SetBN(obj, result); \
392
+ return obj; \
393
+ }
394
+
395
+ /*
396
+ * Document-method: OpenSSL::BN#sqr
397
+ * call-seq:
398
+ * bn.sqr => aBN
399
+ */
400
+ BIGNUM_1c(sqr)
401
+
402
+ #define BIGNUM_2(func) \
403
+ static VALUE \
404
+ ossl_bn_##func(VALUE self, VALUE other) \
405
+ { \
406
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
407
+ VALUE obj; \
408
+ GetBN(self, bn1); \
409
+ obj = NewBN(CLASS_OF(self)); \
410
+ if (!(result = BN_new())) { \
411
+ ossl_raise(eBNError, NULL); \
412
+ } \
413
+ if (!BN_##func(result, bn1, bn2)) { \
414
+ BN_free(result); \
415
+ ossl_raise(eBNError, NULL); \
416
+ } \
417
+ SetBN(obj, result); \
418
+ return obj; \
419
+ }
420
+
421
+ /*
422
+ * Document-method: OpenSSL::BN#+
423
+ * call-seq:
424
+ * bn + bn2 => aBN
425
+ */
426
+ BIGNUM_2(add)
427
+
428
+ /*
429
+ * Document-method: OpenSSL::BN#-
430
+ * call-seq:
431
+ * bn - bn2 => aBN
432
+ */
433
+ BIGNUM_2(sub)
434
+
435
+ #define BIGNUM_2c(func) \
436
+ static VALUE \
437
+ ossl_bn_##func(VALUE self, VALUE other) \
438
+ { \
439
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
440
+ VALUE obj; \
441
+ GetBN(self, bn1); \
442
+ obj = NewBN(CLASS_OF(self)); \
443
+ if (!(result = BN_new())) { \
444
+ ossl_raise(eBNError, NULL); \
445
+ } \
446
+ if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \
447
+ BN_free(result); \
448
+ ossl_raise(eBNError, NULL); \
449
+ } \
450
+ SetBN(obj, result); \
451
+ return obj; \
452
+ }
453
+
454
+ /*
455
+ * Document-method: OpenSSL::BN#*
456
+ * call-seq:
457
+ * bn * bn2 => aBN
458
+ */
459
+ BIGNUM_2c(mul)
460
+
461
+ /*
462
+ * Document-method: OpenSSL::BN#%
463
+ * call-seq:
464
+ * bn % bn2 => aBN
465
+ */
466
+ BIGNUM_2c(mod)
467
+
468
+ /*
469
+ * Document-method: OpenSSL::BN#**
470
+ * call-seq:
471
+ * bn ** bn2 => aBN
472
+ */
473
+ BIGNUM_2c(exp)
474
+
475
+ /*
476
+ * Document-method: OpenSSL::BN#gcd
477
+ * call-seq:
478
+ * bn.gcd(bn2) => aBN
479
+ */
480
+ BIGNUM_2c(gcd)
481
+
482
+ /*
483
+ * Document-method: OpenSSL::BN#mod_sqr
484
+ * call-seq:
485
+ * bn.mod_sqr(bn2) => aBN
486
+ */
487
+ BIGNUM_2c(mod_sqr)
488
+
489
+ /*
490
+ * Document-method: OpenSSL::BN#mod_inverse
491
+ * call-seq:
492
+ * bn.mod_inverse(bn2) => aBN
493
+ */
494
+ BIGNUM_2c(mod_inverse)
495
+
496
+ /*
497
+ * Document-method: OpenSSL::BN#/
498
+ * call-seq:
499
+ * bn1 / bn2 => [result, remainder]
500
+ *
501
+ * Division of OpenSSL::BN instances
502
+ */
503
+ static VALUE
504
+ ossl_bn_div(VALUE self, VALUE other)
505
+ {
506
+ BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
507
+ VALUE obj1, obj2;
508
+
509
+ GetBN(self, bn1);
510
+
511
+ obj1 = NewBN(CLASS_OF(self));
512
+ obj2 = NewBN(CLASS_OF(self));
513
+ if (!(r1 = BN_new())) {
514
+ ossl_raise(eBNError, NULL);
515
+ }
516
+ if (!(r2 = BN_new())) {
517
+ BN_free(r1);
518
+ ossl_raise(eBNError, NULL);
519
+ }
520
+ if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
521
+ BN_free(r1);
522
+ BN_free(r2);
523
+ ossl_raise(eBNError, NULL);
524
+ }
525
+ SetBN(obj1, r1);
526
+ SetBN(obj2, r2);
527
+
528
+ return rb_ary_new3(2, obj1, obj2);
529
+ }
530
+
531
+ #define BIGNUM_3c(func) \
532
+ static VALUE \
533
+ ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
534
+ { \
535
+ BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
536
+ BIGNUM *bn3 = GetBNPtr(other2), *result; \
537
+ VALUE obj; \
538
+ GetBN(self, bn1); \
539
+ obj = NewBN(CLASS_OF(self)); \
540
+ if (!(result = BN_new())) { \
541
+ ossl_raise(eBNError, NULL); \
542
+ } \
543
+ if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \
544
+ BN_free(result); \
545
+ ossl_raise(eBNError, NULL); \
546
+ } \
547
+ SetBN(obj, result); \
548
+ return obj; \
549
+ }
550
+
551
+ /*
552
+ * Document-method: OpenSSL::BN#mod_add
553
+ * call-seq:
554
+ * bn.mod_add(bn1, bn2) -> aBN
555
+ */
556
+ BIGNUM_3c(mod_add)
557
+
558
+ /*
559
+ * Document-method: OpenSSL::BN#mod_sub
560
+ * call-seq:
561
+ * bn.mod_sub(bn1, bn2) -> aBN
562
+ */
563
+ BIGNUM_3c(mod_sub)
564
+
565
+ /*
566
+ * Document-method: OpenSSL::BN#mod_mul
567
+ * call-seq:
568
+ * bn.mod_mul(bn1, bn2) -> aBN
569
+ */
570
+ BIGNUM_3c(mod_mul)
571
+
572
+ /*
573
+ * Document-method: OpenSSL::BN#mod_exp
574
+ * call-seq:
575
+ * bn.mod_exp(bn1, bn2) -> aBN
576
+ */
577
+ BIGNUM_3c(mod_exp)
578
+
579
+ #define BIGNUM_BIT(func) \
580
+ static VALUE \
581
+ ossl_bn_##func(VALUE self, VALUE bit) \
582
+ { \
583
+ BIGNUM *bn; \
584
+ GetBN(self, bn); \
585
+ if (!BN_##func(bn, NUM2INT(bit))) { \
586
+ ossl_raise(eBNError, NULL); \
587
+ } \
588
+ return self; \
589
+ }
590
+
591
+ /*
592
+ * Document-method: OpenSSL::BN#set_bit!
593
+ * call-seq:
594
+ * bn.set_bit!(bit) -> self
595
+ */
596
+ BIGNUM_BIT(set_bit)
597
+
598
+ /*
599
+ * Document-method: OpenSSL::BN#clear_bit!
600
+ * call-seq:
601
+ * bn.clear_bit!(bit) -> self
602
+ */
603
+ BIGNUM_BIT(clear_bit)
604
+
605
+ /*
606
+ * Document-method: OpenSSL::BN#mask_bit!
607
+ * call-seq:
608
+ * bn.mask_bit!(bit) -> self
609
+ */
610
+ BIGNUM_BIT(mask_bits)
611
+
612
+ /* Document-method: OpenSSL::BN#bit_set?
613
+ * call-seq:
614
+ * bn.bit_set?(bit) => true | false
615
+ *
616
+ * Returns boolean of whether +bit+ is set.
617
+ * Bitwise operations for openssl BIGNUMs.
618
+ */
619
+ static VALUE
620
+ ossl_bn_is_bit_set(VALUE self, VALUE bit)
621
+ {
622
+ int b;
623
+ BIGNUM *bn;
624
+
625
+ b = NUM2INT(bit);
626
+ GetBN(self, bn);
627
+ if (BN_is_bit_set(bn, b)) {
628
+ return Qtrue;
629
+ }
630
+ return Qfalse;
631
+ }
632
+
633
+ #define BIGNUM_SHIFT(func) \
634
+ static VALUE \
635
+ ossl_bn_##func(VALUE self, VALUE bits) \
636
+ { \
637
+ BIGNUM *bn, *result; \
638
+ int b; \
639
+ VALUE obj; \
640
+ b = NUM2INT(bits); \
641
+ GetBN(self, bn); \
642
+ obj = NewBN(CLASS_OF(self)); \
643
+ if (!(result = BN_new())) { \
644
+ ossl_raise(eBNError, NULL); \
645
+ } \
646
+ if (!BN_##func(result, bn, b)) { \
647
+ BN_free(result); \
648
+ ossl_raise(eBNError, NULL); \
649
+ } \
650
+ SetBN(obj, result); \
651
+ return obj; \
652
+ }
653
+
654
+ /*
655
+ * Document-method: OpenSSL::BN#<<
656
+ * call-seq:
657
+ * bn << bits -> aBN
658
+ */
659
+ BIGNUM_SHIFT(lshift)
660
+
661
+ /*
662
+ * Document-method: OpenSSL::BN#>>
663
+ * call-seq:
664
+ * bn >> bits -> aBN
665
+ */
666
+ BIGNUM_SHIFT(rshift)
667
+
668
+ #define BIGNUM_SELF_SHIFT(func) \
669
+ static VALUE \
670
+ ossl_bn_self_##func(VALUE self, VALUE bits) \
671
+ { \
672
+ BIGNUM *bn; \
673
+ int b; \
674
+ b = NUM2INT(bits); \
675
+ GetBN(self, bn); \
676
+ if (!BN_##func(bn, bn, b)) \
677
+ ossl_raise(eBNError, NULL); \
678
+ return self; \
679
+ }
680
+
681
+ /*
682
+ * Document-method: OpenSSL::BN#lshift!
683
+ * call-seq:
684
+ * bn.lshift!(bits) -> self
685
+ */
686
+ BIGNUM_SELF_SHIFT(lshift)
687
+
688
+ /*
689
+ * Document-method: OpenSSL::BN#rshift!
690
+ * call-seq:
691
+ * bn.rshift!(bits) -> self
692
+ */
693
+ BIGNUM_SELF_SHIFT(rshift)
694
+
695
+ #define BIGNUM_RAND(func) \
696
+ static VALUE \
697
+ ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
698
+ { \
699
+ BIGNUM *result; \
700
+ int bottom = 0, top = 0, b; \
701
+ VALUE bits, fill, odd, obj; \
702
+ \
703
+ switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
704
+ case 3: \
705
+ bottom = (odd == Qtrue) ? 1 : 0; \
706
+ /* FALLTHROUGH */ \
707
+ case 2: \
708
+ top = NUM2INT(fill); \
709
+ } \
710
+ b = NUM2INT(bits); \
711
+ obj = NewBN(klass); \
712
+ if (!(result = BN_new())) { \
713
+ ossl_raise(eBNError, NULL); \
714
+ } \
715
+ if (!BN_##func(result, b, top, bottom)) { \
716
+ BN_free(result); \
717
+ ossl_raise(eBNError, NULL); \
718
+ } \
719
+ SetBN(obj, result); \
720
+ return obj; \
721
+ }
722
+
723
+ /*
724
+ * Document-method: OpenSSL::BN.rand
725
+ * BN.rand(bits [, fill [, odd]]) -> aBN
726
+ */
727
+ BIGNUM_RAND(rand)
728
+
729
+ /*
730
+ * Document-method: OpenSSL::BN.pseudo_rand
731
+ * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
732
+ */
733
+ BIGNUM_RAND(pseudo_rand)
734
+
735
+ #define BIGNUM_RAND_RANGE(func) \
736
+ static VALUE \
737
+ ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
738
+ { \
739
+ BIGNUM *bn = GetBNPtr(range), *result; \
740
+ VALUE obj = NewBN(klass); \
741
+ if (!(result = BN_new())) { \
742
+ ossl_raise(eBNError, NULL); \
743
+ } \
744
+ if (!BN_##func##_range(result, bn)) { \
745
+ BN_free(result); \
746
+ ossl_raise(eBNError, NULL); \
747
+ } \
748
+ SetBN(obj, result); \
749
+ return obj; \
750
+ }
751
+
752
+ /*
753
+ * Document-method: OpenSSL::BN.rand_range
754
+ * call-seq:
755
+ * BN.rand_range(range) -> aBN
756
+ *
757
+ */
758
+ BIGNUM_RAND_RANGE(rand)
759
+
760
+ /*
761
+ * Document-method: OpenSSL::BN.pseudo_rand_range
762
+ * call-seq:
763
+ * BN.pseudo_rand_range(range) -> aBN
764
+ *
765
+ */
766
+ BIGNUM_RAND_RANGE(pseudo_rand)
767
+
768
+ /*
769
+ * call-seq:
770
+ * BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
771
+ *
772
+ * Generates a random prime number of bit length +bits+. If +safe+ is true,
773
+ * generates a safe prime. If +add+ is specified, generates a prime that
774
+ * fulfills condition <tt>p % add = rem</tt>.
775
+ *
776
+ * === Parameters
777
+ * * +bits+ - integer
778
+ * * +safe+ - boolean
779
+ * * +add+ - BN
780
+ * * +rem+ - BN
781
+ */
782
+ static VALUE
783
+ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
784
+ {
785
+ BIGNUM *add = NULL, *rem = NULL, *result;
786
+ int safe = 1, num;
787
+ VALUE vnum, vsafe, vadd, vrem, obj;
788
+
789
+ rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
790
+
791
+ num = NUM2INT(vnum);
792
+
793
+ if (vsafe == Qfalse) {
794
+ safe = 0;
795
+ }
796
+ if (!NIL_P(vadd)) {
797
+ add = GetBNPtr(vadd);
798
+ rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
799
+ }
800
+ obj = NewBN(klass);
801
+ if (!(result = BN_new())) {
802
+ ossl_raise(eBNError, NULL);
803
+ }
804
+ if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) {
805
+ BN_free(result);
806
+ ossl_raise(eBNError, NULL);
807
+ }
808
+ SetBN(obj, result);
809
+
810
+ return obj;
811
+ }
812
+
813
+ #define BIGNUM_NUM(func) \
814
+ static VALUE \
815
+ ossl_bn_##func(VALUE self) \
816
+ { \
817
+ BIGNUM *bn; \
818
+ GetBN(self, bn); \
819
+ return INT2NUM(BN_##func(bn)); \
820
+ }
821
+
822
+ /*
823
+ * Document-method: OpenSSL::BN#num_bytes
824
+ * call-seq:
825
+ * bn.num_bytes => integer
826
+ */
827
+ BIGNUM_NUM(num_bytes)
828
+
829
+ /*
830
+ * Document-method: OpenSSL::BN#num_bits
831
+ * call-seq:
832
+ * bn.num_bits => integer
833
+ */
834
+ BIGNUM_NUM(num_bits)
835
+
836
+ static VALUE
837
+ ossl_bn_copy(VALUE self, VALUE other)
838
+ {
839
+ BIGNUM *bn1, *bn2;
840
+
841
+ rb_check_frozen(self);
842
+
843
+ if (self == other) return self;
844
+
845
+ GetBN(self, bn1);
846
+ bn2 = GetBNPtr(other);
847
+
848
+ if (!BN_copy(bn1, bn2)) {
849
+ ossl_raise(eBNError, NULL);
850
+ }
851
+ return self;
852
+ }
853
+
854
+ #define BIGNUM_CMP(func) \
855
+ static VALUE \
856
+ ossl_bn_##func(VALUE self, VALUE other) \
857
+ { \
858
+ BIGNUM *bn1, *bn2 = GetBNPtr(other); \
859
+ GetBN(self, bn1); \
860
+ return INT2NUM(BN_##func(bn1, bn2)); \
861
+ }
862
+
863
+ /*
864
+ * Document-method: OpenSSL::BN#cmp
865
+ * call-seq:
866
+ * bn.cmp(bn2) => integer
867
+ */
868
+ /*
869
+ * Document-method: OpenSSL::BN#<=>
870
+ * call-seq:
871
+ * bn <=> bn2 => integer
872
+ */
873
+ BIGNUM_CMP(cmp)
874
+
875
+ /*
876
+ * Document-method: OpenSSL::BN#ucmp
877
+ * call-seq:
878
+ * bn.ucmp(bn2) => integer
879
+ */
880
+ BIGNUM_CMP(ucmp)
881
+
882
+ /*
883
+ * call-seq:
884
+ * bn == obj => true or false
885
+ *
886
+ * Returns +true+ only if +obj+ has the same value as +bn+. Contrast this
887
+ * with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
888
+ */
889
+ static VALUE
890
+ ossl_bn_eq(VALUE self, VALUE other)
891
+ {
892
+ BIGNUM *bn1, *bn2;
893
+
894
+ GetBN(self, bn1);
895
+ /* BNPtr may raise, so we can't use here */
896
+ bn2 = try_convert_to_bnptr(other);
897
+
898
+ if (bn2 && !BN_cmp(bn1, bn2)) {
899
+ return Qtrue;
900
+ }
901
+ return Qfalse;
902
+ }
903
+
904
+ /*
905
+ * call-seq:
906
+ * bn.eql?(obj) => true or false
907
+ *
908
+ * Returns <code>true</code> only if <i>obj</i> is a
909
+ * <code>OpenSSL::BN</code> with the same value as <i>big</i>. Contrast this
910
+ * with OpenSSL::BN#==, which performs type conversions.
911
+ */
912
+ static VALUE
913
+ ossl_bn_eql(VALUE self, VALUE other)
914
+ {
915
+ BIGNUM *bn1, *bn2;
916
+
917
+ if (!rb_obj_is_kind_of(other, cBN))
918
+ return Qfalse;
919
+ GetBN(self, bn1);
920
+ GetBN(other, bn2);
921
+
922
+ return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
923
+ }
924
+
925
+ /*
926
+ * call-seq:
927
+ * bn.hash => Integer
928
+ *
929
+ * Returns a hash code for this object.
930
+ *
931
+ * See also Object#hash.
932
+ */
933
+ static VALUE
934
+ ossl_bn_hash(VALUE self)
935
+ {
936
+ BIGNUM *bn;
937
+ VALUE hash;
938
+ unsigned char *buf;
939
+ int len;
940
+
941
+ GetBN(self, bn);
942
+ len = BN_num_bytes(bn);
943
+ buf = xmalloc(len);
944
+ if (BN_bn2bin(bn, buf) != len) {
945
+ xfree(buf);
946
+ ossl_raise(eBNError, NULL);
947
+ }
948
+
949
+ hash = INT2FIX(rb_memhash(buf, len));
950
+ xfree(buf);
951
+
952
+ return hash;
953
+ }
954
+
955
+ /*
956
+ * call-seq:
957
+ * bn.prime? => true | false
958
+ * bn.prime?(checks) => true | false
959
+ *
960
+ * Performs a Miller-Rabin probabilistic primality test with +checks+
961
+ * iterations. If +nchecks+ is not specified, a number of iterations is used
962
+ * that yields a false positive rate of at most 2^-80 for random input.
963
+ *
964
+ * === Parameters
965
+ * * +checks+ - integer
966
+ */
967
+ static VALUE
968
+ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
969
+ {
970
+ BIGNUM *bn;
971
+ VALUE vchecks;
972
+ int checks = BN_prime_checks;
973
+
974
+ if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
975
+ checks = NUM2INT(vchecks);
976
+ }
977
+ GetBN(self, bn);
978
+ switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
979
+ case 1:
980
+ return Qtrue;
981
+ case 0:
982
+ return Qfalse;
983
+ default:
984
+ ossl_raise(eBNError, NULL);
985
+ }
986
+ /* not reachable */
987
+ return Qnil;
988
+ }
989
+
990
+ /*
991
+ * call-seq:
992
+ * bn.prime_fasttest? => true | false
993
+ * bn.prime_fasttest?(checks) => true | false
994
+ * bn.prime_fasttest?(checks, trial_div) => true | false
995
+ *
996
+ * Performs a Miller-Rabin primality test. This is same as #prime? except this
997
+ * first attempts trial divisions with some small primes.
998
+ *
999
+ * === Parameters
1000
+ * * +checks+ - integer
1001
+ * * +trial_div+ - boolean
1002
+ */
1003
+ static VALUE
1004
+ ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
1005
+ {
1006
+ BIGNUM *bn;
1007
+ VALUE vchecks, vtrivdiv;
1008
+ int checks = BN_prime_checks, do_trial_division = 1;
1009
+
1010
+ rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
1011
+
1012
+ if (!NIL_P(vchecks)) {
1013
+ checks = NUM2INT(vchecks);
1014
+ }
1015
+ GetBN(self, bn);
1016
+ /* handle true/false */
1017
+ if (vtrivdiv == Qfalse) {
1018
+ do_trial_division = 0;
1019
+ }
1020
+ switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
1021
+ case 1:
1022
+ return Qtrue;
1023
+ case 0:
1024
+ return Qfalse;
1025
+ default:
1026
+ ossl_raise(eBNError, NULL);
1027
+ }
1028
+ /* not reachable */
1029
+ return Qnil;
1030
+ }
1031
+
1032
+ /*
1033
+ * INIT
1034
+ * (NOTE: ordering of methods is the same as in 'man bn')
1035
+ */
1036
+ void
1037
+ Init_ossl_bn(void)
1038
+ {
1039
+ #if 0
1040
+ mOSSL = rb_define_module("OpenSSL");
1041
+ eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
1042
+ #endif
1043
+
1044
+ if (!(ossl_bn_ctx = BN_CTX_new())) {
1045
+ ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
1046
+ }
1047
+
1048
+ eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
1049
+
1050
+ cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
1051
+
1052
+ rb_define_alloc_func(cBN, ossl_bn_alloc);
1053
+ rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
1054
+
1055
+ rb_define_copy_func(cBN, ossl_bn_copy);
1056
+ rb_define_method(cBN, "copy", ossl_bn_copy, 1);
1057
+
1058
+ /* swap (=coerce?) */
1059
+
1060
+ rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
1061
+ rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
1062
+ /* num_bits_word */
1063
+
1064
+ rb_define_method(cBN, "+", ossl_bn_add, 1);
1065
+ rb_define_method(cBN, "-", ossl_bn_sub, 1);
1066
+ rb_define_method(cBN, "*", ossl_bn_mul, 1);
1067
+ rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
1068
+ rb_define_method(cBN, "/", ossl_bn_div, 1);
1069
+ rb_define_method(cBN, "%", ossl_bn_mod, 1);
1070
+ /* nnmod */
1071
+
1072
+ rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
1073
+ rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
1074
+ rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
1075
+ rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
1076
+ rb_define_method(cBN, "**", ossl_bn_exp, 1);
1077
+ rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
1078
+ rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
1079
+
1080
+ /* add_word
1081
+ * sub_word
1082
+ * mul_word
1083
+ * div_word
1084
+ * mod_word */
1085
+
1086
+ rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
1087
+ rb_define_alias(cBN, "<=>", "cmp");
1088
+ rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
1089
+ rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
1090
+ rb_define_method(cBN, "hash", ossl_bn_hash, 0);
1091
+ rb_define_method(cBN, "==", ossl_bn_eq, 1);
1092
+ rb_define_alias(cBN, "===", "==");
1093
+ rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
1094
+ rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
1095
+ /* is_word */
1096
+ rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
1097
+
1098
+ /* zero
1099
+ * one
1100
+ * value_one - DON'T IMPL.
1101
+ * set_word
1102
+ * get_word */
1103
+
1104
+ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
1105
+ rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
1106
+ rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
1107
+ rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
1108
+
1109
+ rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
1110
+ rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
1111
+ rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
1112
+
1113
+ rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
1114
+ rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
1115
+ rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
1116
+ rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
1117
+ rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
1118
+ rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
1119
+ rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
1120
+ rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
1121
+ /* lshift1 - DON'T IMPL. */
1122
+ /* rshift1 - DON'T IMPL. */
1123
+
1124
+ /*
1125
+ * bn2bin
1126
+ * bin2bn
1127
+ * bn2hex
1128
+ * bn2dec
1129
+ * hex2bn
1130
+ * dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
1131
+ * print - NOT IMPL.
1132
+ * print_fp - NOT IMPL.
1133
+ * bn2mpi
1134
+ * mpi2bn
1135
+ */
1136
+ rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
1137
+ rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
1138
+ rb_define_alias(cBN, "to_int", "to_i");
1139
+ rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
1140
+ rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
1141
+
1142
+ /*
1143
+ * TODO:
1144
+ * But how to: from_bin, from_mpi? PACK?
1145
+ * to_bin
1146
+ * to_mpi
1147
+ */
1148
+
1149
+ rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
1150
+
1151
+ /* RECiProcal
1152
+ * MONTgomery */
1153
+ }