openssl-custom 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/BSDL +22 -0
- data/CONTRIBUTING.md +132 -0
- data/History.md +485 -0
- data/LICENSE.txt +56 -0
- data/README.md +66 -0
- data/ext/openssl/extconf.rb +190 -0
- data/ext/openssl/openssl_missing.c +106 -0
- data/ext/openssl/openssl_missing.h +257 -0
- data/ext/openssl/ossl.c +1282 -0
- data/ext/openssl/ossl.h +181 -0
- data/ext/openssl/ossl_asn1.c +1878 -0
- data/ext/openssl/ossl_asn1.h +62 -0
- data/ext/openssl/ossl_bio.c +42 -0
- data/ext/openssl/ossl_bio.h +16 -0
- data/ext/openssl/ossl_bn.c +1270 -0
- data/ext/openssl/ossl_bn.h +26 -0
- data/ext/openssl/ossl_cipher.c +1075 -0
- data/ext/openssl/ossl_cipher.h +20 -0
- data/ext/openssl/ossl_config.c +89 -0
- data/ext/openssl/ossl_config.h +19 -0
- data/ext/openssl/ossl_digest.c +425 -0
- data/ext/openssl/ossl_digest.h +20 -0
- data/ext/openssl/ossl_engine.c +567 -0
- data/ext/openssl/ossl_engine.h +19 -0
- data/ext/openssl/ossl_hmac.c +389 -0
- data/ext/openssl/ossl_hmac.h +18 -0
- data/ext/openssl/ossl_kdf.c +303 -0
- data/ext/openssl/ossl_kdf.h +6 -0
- data/ext/openssl/ossl_ns_spki.c +405 -0
- data/ext/openssl/ossl_ns_spki.h +19 -0
- data/ext/openssl/ossl_ocsp.c +2013 -0
- data/ext/openssl/ossl_ocsp.h +23 -0
- data/ext/openssl/ossl_pkcs12.c +257 -0
- data/ext/openssl/ossl_pkcs12.h +13 -0
- data/ext/openssl/ossl_pkcs7.c +1098 -0
- data/ext/openssl/ossl_pkcs7.h +36 -0
- data/ext/openssl/ossl_pkey.c +673 -0
- data/ext/openssl/ossl_pkey.h +241 -0
- data/ext/openssl/ossl_pkey_dh.c +650 -0
- data/ext/openssl/ossl_pkey_dsa.c +664 -0
- data/ext/openssl/ossl_pkey_ec.c +1827 -0
- data/ext/openssl/ossl_pkey_rsa.c +966 -0
- data/ext/openssl/ossl_rand.c +200 -0
- data/ext/openssl/ossl_rand.h +18 -0
- data/ext/openssl/ossl_ssl.c +3080 -0
- data/ext/openssl/ossl_ssl.h +36 -0
- data/ext/openssl/ossl_ssl_session.c +332 -0
- data/ext/openssl/ossl_ts.c +1524 -0
- data/ext/openssl/ossl_ts.h +16 -0
- data/ext/openssl/ossl_x509.c +262 -0
- data/ext/openssl/ossl_x509.h +115 -0
- data/ext/openssl/ossl_x509attr.c +324 -0
- data/ext/openssl/ossl_x509cert.c +846 -0
- data/ext/openssl/ossl_x509crl.c +542 -0
- data/ext/openssl/ossl_x509ext.c +491 -0
- data/ext/openssl/ossl_x509name.c +590 -0
- data/ext/openssl/ossl_x509req.c +441 -0
- data/ext/openssl/ossl_x509revoked.c +300 -0
- data/ext/openssl/ossl_x509store.c +902 -0
- data/ext/openssl/ruby_missing.h +24 -0
- data/lib/openssl/bn.rb +40 -0
- data/lib/openssl/buffering.rb +478 -0
- data/lib/openssl/cipher.rb +67 -0
- data/lib/openssl/config.rb +501 -0
- data/lib/openssl/digest.rb +73 -0
- data/lib/openssl/hmac.rb +13 -0
- data/lib/openssl/marshal.rb +30 -0
- data/lib/openssl/pkcs5.rb +22 -0
- data/lib/openssl/pkey.rb +42 -0
- data/lib/openssl/ssl.rb +542 -0
- data/lib/openssl/version.rb +5 -0
- data/lib/openssl/x509.rb +369 -0
- data/lib/openssl.rb +38 -0
- metadata +196 -0
@@ -0,0 +1,1270 @@
|
|
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
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
14
|
+
#include <ruby/ractor.h>
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#define NewBN(klass) \
|
18
|
+
TypedData_Wrap_Struct((klass), &ossl_bn_type, 0)
|
19
|
+
#define SetBN(obj, bn) do { \
|
20
|
+
if (!(bn)) { \
|
21
|
+
ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
|
22
|
+
} \
|
23
|
+
RTYPEDDATA_DATA(obj) = (bn); \
|
24
|
+
} while (0)
|
25
|
+
|
26
|
+
#define GetBN(obj, bn) do { \
|
27
|
+
TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \
|
28
|
+
if (!(bn)) { \
|
29
|
+
ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \
|
30
|
+
} \
|
31
|
+
} while (0)
|
32
|
+
|
33
|
+
static void
|
34
|
+
ossl_bn_free(void *ptr)
|
35
|
+
{
|
36
|
+
BN_clear_free(ptr);
|
37
|
+
}
|
38
|
+
|
39
|
+
static const rb_data_type_t ossl_bn_type = {
|
40
|
+
"OpenSSL/BN",
|
41
|
+
{
|
42
|
+
0, ossl_bn_free,
|
43
|
+
},
|
44
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
45
|
+
};
|
46
|
+
|
47
|
+
/*
|
48
|
+
* Classes
|
49
|
+
*/
|
50
|
+
VALUE cBN;
|
51
|
+
|
52
|
+
/* Document-class: OpenSSL::BNError
|
53
|
+
*
|
54
|
+
* Generic Error for all of OpenSSL::BN (big num)
|
55
|
+
*/
|
56
|
+
VALUE eBNError;
|
57
|
+
|
58
|
+
/*
|
59
|
+
* Public
|
60
|
+
*/
|
61
|
+
VALUE
|
62
|
+
ossl_bn_new(const BIGNUM *bn)
|
63
|
+
{
|
64
|
+
BIGNUM *newbn;
|
65
|
+
VALUE obj;
|
66
|
+
|
67
|
+
obj = NewBN(cBN);
|
68
|
+
newbn = bn ? BN_dup(bn) : BN_new();
|
69
|
+
if (!newbn) {
|
70
|
+
ossl_raise(eBNError, NULL);
|
71
|
+
}
|
72
|
+
SetBN(obj, newbn);
|
73
|
+
|
74
|
+
return obj;
|
75
|
+
}
|
76
|
+
|
77
|
+
static BIGNUM *
|
78
|
+
integer_to_bnptr(VALUE obj, BIGNUM *orig)
|
79
|
+
{
|
80
|
+
BIGNUM *bn;
|
81
|
+
|
82
|
+
if (FIXNUM_P(obj)) {
|
83
|
+
long i;
|
84
|
+
unsigned char bin[sizeof(long)];
|
85
|
+
long n = FIX2LONG(obj);
|
86
|
+
unsigned long un = labs(n);
|
87
|
+
|
88
|
+
for (i = sizeof(long) - 1; 0 <= i; i--) {
|
89
|
+
bin[i] = un & 0xff;
|
90
|
+
un >>= 8;
|
91
|
+
}
|
92
|
+
|
93
|
+
bn = BN_bin2bn(bin, sizeof(bin), orig);
|
94
|
+
if (!bn)
|
95
|
+
ossl_raise(eBNError, "BN_bin2bn");
|
96
|
+
if (n < 0)
|
97
|
+
BN_set_negative(bn, 1);
|
98
|
+
}
|
99
|
+
else { /* assuming Bignum */
|
100
|
+
size_t len = rb_absint_size(obj, NULL);
|
101
|
+
unsigned char *bin;
|
102
|
+
VALUE buf;
|
103
|
+
int sign;
|
104
|
+
|
105
|
+
if (INT_MAX < len) {
|
106
|
+
rb_raise(eBNError, "bignum too long");
|
107
|
+
}
|
108
|
+
bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len);
|
109
|
+
sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN);
|
110
|
+
|
111
|
+
bn = BN_bin2bn(bin, (int)len, orig);
|
112
|
+
ALLOCV_END(buf);
|
113
|
+
if (!bn)
|
114
|
+
ossl_raise(eBNError, "BN_bin2bn");
|
115
|
+
if (sign < 0)
|
116
|
+
BN_set_negative(bn, 1);
|
117
|
+
}
|
118
|
+
|
119
|
+
return bn;
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE
|
123
|
+
try_convert_to_bn(VALUE obj)
|
124
|
+
{
|
125
|
+
BIGNUM *bn;
|
126
|
+
VALUE newobj = Qnil;
|
127
|
+
|
128
|
+
if (rb_obj_is_kind_of(obj, cBN))
|
129
|
+
return obj;
|
130
|
+
if (RB_INTEGER_TYPE_P(obj)) {
|
131
|
+
newobj = NewBN(cBN); /* Handle potential mem leaks */
|
132
|
+
bn = integer_to_bnptr(obj, NULL);
|
133
|
+
SetBN(newobj, bn);
|
134
|
+
}
|
135
|
+
|
136
|
+
return newobj;
|
137
|
+
}
|
138
|
+
|
139
|
+
BIGNUM *
|
140
|
+
ossl_bn_value_ptr(volatile VALUE *ptr)
|
141
|
+
{
|
142
|
+
VALUE tmp;
|
143
|
+
BIGNUM *bn;
|
144
|
+
|
145
|
+
tmp = try_convert_to_bn(*ptr);
|
146
|
+
if (NIL_P(tmp))
|
147
|
+
ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN");
|
148
|
+
GetBN(tmp, bn);
|
149
|
+
*ptr = tmp;
|
150
|
+
|
151
|
+
return bn;
|
152
|
+
}
|
153
|
+
|
154
|
+
/*
|
155
|
+
* Private
|
156
|
+
*/
|
157
|
+
|
158
|
+
#if HAVE_RB_EXT_RACTOR_SAFE
|
159
|
+
void
|
160
|
+
ossl_bn_ctx_free(void *ptr)
|
161
|
+
{
|
162
|
+
BN_CTX *ctx = (BN_CTX *)ptr;
|
163
|
+
BN_CTX_free(ctx);
|
164
|
+
}
|
165
|
+
|
166
|
+
struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = {
|
167
|
+
NULL, // mark
|
168
|
+
ossl_bn_ctx_free,
|
169
|
+
};
|
170
|
+
|
171
|
+
rb_ractor_local_key_t ossl_bn_ctx_key;
|
172
|
+
|
173
|
+
BN_CTX *
|
174
|
+
ossl_bn_ctx_get(void)
|
175
|
+
{
|
176
|
+
// stored in ractor local storage
|
177
|
+
|
178
|
+
BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key);
|
179
|
+
if (!ctx) {
|
180
|
+
if (!(ctx = BN_CTX_new())) {
|
181
|
+
ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
|
182
|
+
}
|
183
|
+
rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx);
|
184
|
+
}
|
185
|
+
return ctx;
|
186
|
+
}
|
187
|
+
#else
|
188
|
+
// for ruby 2.x
|
189
|
+
static BN_CTX *gv_ossl_bn_ctx;
|
190
|
+
|
191
|
+
BN_CTX *
|
192
|
+
ossl_bn_ctx_get(void)
|
193
|
+
{
|
194
|
+
if (gv_ossl_bn_ctx == NULL) {
|
195
|
+
if (!(gv_ossl_bn_ctx = BN_CTX_new())) {
|
196
|
+
ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX");
|
197
|
+
}
|
198
|
+
}
|
199
|
+
return gv_ossl_bn_ctx;
|
200
|
+
}
|
201
|
+
|
202
|
+
void
|
203
|
+
ossl_bn_ctx_free(void)
|
204
|
+
{
|
205
|
+
BN_CTX_free(gv_ossl_bn_ctx);
|
206
|
+
gv_ossl_bn_ctx = NULL;
|
207
|
+
}
|
208
|
+
#endif
|
209
|
+
|
210
|
+
static VALUE
|
211
|
+
ossl_bn_alloc(VALUE klass)
|
212
|
+
{
|
213
|
+
BIGNUM *bn;
|
214
|
+
VALUE obj = NewBN(klass);
|
215
|
+
|
216
|
+
if (!(bn = BN_new())) {
|
217
|
+
ossl_raise(eBNError, NULL);
|
218
|
+
}
|
219
|
+
SetBN(obj, bn);
|
220
|
+
|
221
|
+
return obj;
|
222
|
+
}
|
223
|
+
|
224
|
+
/*
|
225
|
+
* call-seq:
|
226
|
+
* OpenSSL::BN.new(bn) => aBN
|
227
|
+
* OpenSSL::BN.new(integer) => aBN
|
228
|
+
* OpenSSL::BN.new(string) => aBN
|
229
|
+
* OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN
|
230
|
+
*
|
231
|
+
* Construct a new OpenSSL BIGNUM object.
|
232
|
+
*/
|
233
|
+
static VALUE
|
234
|
+
ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
|
235
|
+
{
|
236
|
+
BIGNUM *bn;
|
237
|
+
VALUE str, bs;
|
238
|
+
int base = 10;
|
239
|
+
char *ptr;
|
240
|
+
|
241
|
+
if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
|
242
|
+
base = NUM2INT(bs);
|
243
|
+
}
|
244
|
+
|
245
|
+
if (NIL_P(str)) {
|
246
|
+
ossl_raise(rb_eArgError, "invalid argument");
|
247
|
+
}
|
248
|
+
|
249
|
+
if (RB_INTEGER_TYPE_P(str)) {
|
250
|
+
GetBN(self, bn);
|
251
|
+
integer_to_bnptr(str, bn);
|
252
|
+
|
253
|
+
return self;
|
254
|
+
}
|
255
|
+
|
256
|
+
if (RTEST(rb_obj_is_kind_of(str, cBN))) {
|
257
|
+
BIGNUM *other;
|
258
|
+
|
259
|
+
GetBN(self, bn);
|
260
|
+
GetBN(str, other); /* Safe - we checked kind_of? above */
|
261
|
+
if (!BN_copy(bn, other)) {
|
262
|
+
ossl_raise(eBNError, NULL);
|
263
|
+
}
|
264
|
+
return self;
|
265
|
+
}
|
266
|
+
|
267
|
+
GetBN(self, bn);
|
268
|
+
switch (base) {
|
269
|
+
case 0:
|
270
|
+
ptr = StringValuePtr(str);
|
271
|
+
if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
|
272
|
+
ossl_raise(eBNError, NULL);
|
273
|
+
}
|
274
|
+
break;
|
275
|
+
case 2:
|
276
|
+
ptr = StringValuePtr(str);
|
277
|
+
if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
|
278
|
+
ossl_raise(eBNError, NULL);
|
279
|
+
}
|
280
|
+
break;
|
281
|
+
case 10:
|
282
|
+
if (!BN_dec2bn(&bn, StringValueCStr(str))) {
|
283
|
+
ossl_raise(eBNError, NULL);
|
284
|
+
}
|
285
|
+
break;
|
286
|
+
case 16:
|
287
|
+
if (!BN_hex2bn(&bn, StringValueCStr(str))) {
|
288
|
+
ossl_raise(eBNError, NULL);
|
289
|
+
}
|
290
|
+
break;
|
291
|
+
default:
|
292
|
+
ossl_raise(rb_eArgError, "invalid radix %d", base);
|
293
|
+
}
|
294
|
+
return self;
|
295
|
+
}
|
296
|
+
|
297
|
+
/*
|
298
|
+
* call-seq:
|
299
|
+
* bn.to_s => string
|
300
|
+
* bn.to_s(base) => string
|
301
|
+
*
|
302
|
+
* === Parameters
|
303
|
+
* * _base_ - Integer
|
304
|
+
* Valid values:
|
305
|
+
* * 0 - MPI
|
306
|
+
* * 2 - binary
|
307
|
+
* * 10 - the default
|
308
|
+
* * 16 - hex
|
309
|
+
*/
|
310
|
+
static VALUE
|
311
|
+
ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
|
312
|
+
{
|
313
|
+
BIGNUM *bn;
|
314
|
+
VALUE str, bs;
|
315
|
+
int base = 10, len;
|
316
|
+
char *buf;
|
317
|
+
|
318
|
+
if (rb_scan_args(argc, argv, "01", &bs) == 1) {
|
319
|
+
base = NUM2INT(bs);
|
320
|
+
}
|
321
|
+
GetBN(self, bn);
|
322
|
+
switch (base) {
|
323
|
+
case 0:
|
324
|
+
len = BN_bn2mpi(bn, NULL);
|
325
|
+
str = rb_str_new(0, len);
|
326
|
+
if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
|
327
|
+
ossl_raise(eBNError, NULL);
|
328
|
+
break;
|
329
|
+
case 2:
|
330
|
+
len = BN_num_bytes(bn);
|
331
|
+
str = rb_str_new(0, len);
|
332
|
+
if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
|
333
|
+
ossl_raise(eBNError, NULL);
|
334
|
+
break;
|
335
|
+
case 10:
|
336
|
+
if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
|
337
|
+
str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
|
338
|
+
break;
|
339
|
+
case 16:
|
340
|
+
if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
|
341
|
+
str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
|
342
|
+
break;
|
343
|
+
default:
|
344
|
+
ossl_raise(rb_eArgError, "invalid radix %d", base);
|
345
|
+
}
|
346
|
+
|
347
|
+
return str;
|
348
|
+
}
|
349
|
+
|
350
|
+
/*
|
351
|
+
* call-seq:
|
352
|
+
* bn.to_i => integer
|
353
|
+
*/
|
354
|
+
static VALUE
|
355
|
+
ossl_bn_to_i(VALUE self)
|
356
|
+
{
|
357
|
+
BIGNUM *bn;
|
358
|
+
char *txt;
|
359
|
+
VALUE num;
|
360
|
+
|
361
|
+
GetBN(self, bn);
|
362
|
+
|
363
|
+
if (!(txt = BN_bn2hex(bn))) {
|
364
|
+
ossl_raise(eBNError, NULL);
|
365
|
+
}
|
366
|
+
num = rb_cstr_to_inum(txt, 16, Qtrue);
|
367
|
+
OPENSSL_free(txt);
|
368
|
+
|
369
|
+
return num;
|
370
|
+
}
|
371
|
+
|
372
|
+
static VALUE
|
373
|
+
ossl_bn_to_bn(VALUE self)
|
374
|
+
{
|
375
|
+
return self;
|
376
|
+
}
|
377
|
+
|
378
|
+
static VALUE
|
379
|
+
ossl_bn_coerce(VALUE self, VALUE other)
|
380
|
+
{
|
381
|
+
switch(TYPE(other)) {
|
382
|
+
case T_STRING:
|
383
|
+
self = ossl_bn_to_s(0, NULL, self);
|
384
|
+
break;
|
385
|
+
case T_FIXNUM:
|
386
|
+
case T_BIGNUM:
|
387
|
+
self = ossl_bn_to_i(self);
|
388
|
+
break;
|
389
|
+
default:
|
390
|
+
if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
|
391
|
+
ossl_raise(rb_eTypeError, "Don't know how to coerce");
|
392
|
+
}
|
393
|
+
}
|
394
|
+
return rb_assoc_new(other, self);
|
395
|
+
}
|
396
|
+
|
397
|
+
#define BIGNUM_BOOL1(func) \
|
398
|
+
static VALUE \
|
399
|
+
ossl_bn_##func(VALUE self) \
|
400
|
+
{ \
|
401
|
+
BIGNUM *bn; \
|
402
|
+
GetBN(self, bn); \
|
403
|
+
if (BN_##func(bn)) { \
|
404
|
+
return Qtrue; \
|
405
|
+
} \
|
406
|
+
return Qfalse; \
|
407
|
+
}
|
408
|
+
|
409
|
+
/*
|
410
|
+
* Document-method: OpenSSL::BN#zero?
|
411
|
+
* call-seq:
|
412
|
+
* bn.zero? => true | false
|
413
|
+
*/
|
414
|
+
BIGNUM_BOOL1(is_zero)
|
415
|
+
|
416
|
+
/*
|
417
|
+
* Document-method: OpenSSL::BN#one?
|
418
|
+
* call-seq:
|
419
|
+
* bn.one? => true | false
|
420
|
+
*/
|
421
|
+
BIGNUM_BOOL1(is_one)
|
422
|
+
|
423
|
+
/*
|
424
|
+
* Document-method: OpenSSL::BN#odd?
|
425
|
+
* call-seq:
|
426
|
+
* bn.odd? => true | false
|
427
|
+
*/
|
428
|
+
BIGNUM_BOOL1(is_odd)
|
429
|
+
|
430
|
+
/*
|
431
|
+
* call-seq:
|
432
|
+
* bn.negative? => true | false
|
433
|
+
*/
|
434
|
+
static VALUE
|
435
|
+
ossl_bn_is_negative(VALUE self)
|
436
|
+
{
|
437
|
+
BIGNUM *bn;
|
438
|
+
|
439
|
+
GetBN(self, bn);
|
440
|
+
if (BN_is_zero(bn))
|
441
|
+
return Qfalse;
|
442
|
+
return BN_is_negative(bn) ? Qtrue : Qfalse;
|
443
|
+
}
|
444
|
+
|
445
|
+
#define BIGNUM_1c(func) \
|
446
|
+
static VALUE \
|
447
|
+
ossl_bn_##func(VALUE self) \
|
448
|
+
{ \
|
449
|
+
BIGNUM *bn, *result; \
|
450
|
+
VALUE obj; \
|
451
|
+
GetBN(self, bn); \
|
452
|
+
obj = NewBN(rb_obj_class(self)); \
|
453
|
+
if (!(result = BN_new())) { \
|
454
|
+
ossl_raise(eBNError, NULL); \
|
455
|
+
} \
|
456
|
+
if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \
|
457
|
+
BN_free(result); \
|
458
|
+
ossl_raise(eBNError, NULL); \
|
459
|
+
} \
|
460
|
+
SetBN(obj, result); \
|
461
|
+
return obj; \
|
462
|
+
}
|
463
|
+
|
464
|
+
/*
|
465
|
+
* Document-method: OpenSSL::BN#sqr
|
466
|
+
* call-seq:
|
467
|
+
* bn.sqr => aBN
|
468
|
+
*/
|
469
|
+
BIGNUM_1c(sqr)
|
470
|
+
|
471
|
+
#define BIGNUM_2(func) \
|
472
|
+
static VALUE \
|
473
|
+
ossl_bn_##func(VALUE self, VALUE other) \
|
474
|
+
{ \
|
475
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
|
476
|
+
VALUE obj; \
|
477
|
+
GetBN(self, bn1); \
|
478
|
+
obj = NewBN(rb_obj_class(self)); \
|
479
|
+
if (!(result = BN_new())) { \
|
480
|
+
ossl_raise(eBNError, NULL); \
|
481
|
+
} \
|
482
|
+
if (BN_##func(result, bn1, bn2) <= 0) { \
|
483
|
+
BN_free(result); \
|
484
|
+
ossl_raise(eBNError, NULL); \
|
485
|
+
} \
|
486
|
+
SetBN(obj, result); \
|
487
|
+
return obj; \
|
488
|
+
}
|
489
|
+
|
490
|
+
/*
|
491
|
+
* Document-method: OpenSSL::BN#+
|
492
|
+
* call-seq:
|
493
|
+
* bn + bn2 => aBN
|
494
|
+
*/
|
495
|
+
BIGNUM_2(add)
|
496
|
+
|
497
|
+
/*
|
498
|
+
* Document-method: OpenSSL::BN#-
|
499
|
+
* call-seq:
|
500
|
+
* bn - bn2 => aBN
|
501
|
+
*/
|
502
|
+
BIGNUM_2(sub)
|
503
|
+
|
504
|
+
#define BIGNUM_2c(func) \
|
505
|
+
static VALUE \
|
506
|
+
ossl_bn_##func(VALUE self, VALUE other) \
|
507
|
+
{ \
|
508
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
|
509
|
+
VALUE obj; \
|
510
|
+
GetBN(self, bn1); \
|
511
|
+
obj = NewBN(rb_obj_class(self)); \
|
512
|
+
if (!(result = BN_new())) { \
|
513
|
+
ossl_raise(eBNError, NULL); \
|
514
|
+
} \
|
515
|
+
if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \
|
516
|
+
BN_free(result); \
|
517
|
+
ossl_raise(eBNError, NULL); \
|
518
|
+
} \
|
519
|
+
SetBN(obj, result); \
|
520
|
+
return obj; \
|
521
|
+
}
|
522
|
+
|
523
|
+
/*
|
524
|
+
* Document-method: OpenSSL::BN#*
|
525
|
+
* call-seq:
|
526
|
+
* bn * bn2 => aBN
|
527
|
+
*/
|
528
|
+
BIGNUM_2c(mul)
|
529
|
+
|
530
|
+
/*
|
531
|
+
* Document-method: OpenSSL::BN#%
|
532
|
+
* call-seq:
|
533
|
+
* bn % bn2 => aBN
|
534
|
+
*/
|
535
|
+
BIGNUM_2c(mod)
|
536
|
+
|
537
|
+
/*
|
538
|
+
* Document-method: OpenSSL::BN#**
|
539
|
+
* call-seq:
|
540
|
+
* bn ** bn2 => aBN
|
541
|
+
*/
|
542
|
+
BIGNUM_2c(exp)
|
543
|
+
|
544
|
+
/*
|
545
|
+
* Document-method: OpenSSL::BN#gcd
|
546
|
+
* call-seq:
|
547
|
+
* bn.gcd(bn2) => aBN
|
548
|
+
*/
|
549
|
+
BIGNUM_2c(gcd)
|
550
|
+
|
551
|
+
/*
|
552
|
+
* Document-method: OpenSSL::BN#mod_sqr
|
553
|
+
* call-seq:
|
554
|
+
* bn.mod_sqr(bn2) => aBN
|
555
|
+
*/
|
556
|
+
BIGNUM_2c(mod_sqr)
|
557
|
+
|
558
|
+
/*
|
559
|
+
* call-seq:
|
560
|
+
* bn.mod_inverse(bn2) => aBN
|
561
|
+
*/
|
562
|
+
static VALUE
|
563
|
+
ossl_bn_mod_inverse(VALUE self, VALUE other)
|
564
|
+
{
|
565
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
|
566
|
+
VALUE obj;
|
567
|
+
GetBN(self, bn1);
|
568
|
+
obj = NewBN(rb_obj_class(self));
|
569
|
+
if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
|
570
|
+
ossl_raise(eBNError, "BN_mod_inverse");
|
571
|
+
SetBN(obj, result);
|
572
|
+
return obj;
|
573
|
+
}
|
574
|
+
|
575
|
+
/*
|
576
|
+
* call-seq:
|
577
|
+
* bn1 / bn2 => [result, remainder]
|
578
|
+
*
|
579
|
+
* Division of OpenSSL::BN instances
|
580
|
+
*/
|
581
|
+
static VALUE
|
582
|
+
ossl_bn_div(VALUE self, VALUE other)
|
583
|
+
{
|
584
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
|
585
|
+
VALUE klass, obj1, obj2;
|
586
|
+
|
587
|
+
GetBN(self, bn1);
|
588
|
+
|
589
|
+
klass = rb_obj_class(self);
|
590
|
+
obj1 = NewBN(klass);
|
591
|
+
obj2 = NewBN(klass);
|
592
|
+
if (!(r1 = BN_new())) {
|
593
|
+
ossl_raise(eBNError, NULL);
|
594
|
+
}
|
595
|
+
if (!(r2 = BN_new())) {
|
596
|
+
BN_free(r1);
|
597
|
+
ossl_raise(eBNError, NULL);
|
598
|
+
}
|
599
|
+
if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
|
600
|
+
BN_free(r1);
|
601
|
+
BN_free(r2);
|
602
|
+
ossl_raise(eBNError, NULL);
|
603
|
+
}
|
604
|
+
SetBN(obj1, r1);
|
605
|
+
SetBN(obj2, r2);
|
606
|
+
|
607
|
+
return rb_ary_new3(2, obj1, obj2);
|
608
|
+
}
|
609
|
+
|
610
|
+
#define BIGNUM_3c(func) \
|
611
|
+
static VALUE \
|
612
|
+
ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \
|
613
|
+
{ \
|
614
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other1); \
|
615
|
+
BIGNUM *bn3 = GetBNPtr(other2), *result; \
|
616
|
+
VALUE obj; \
|
617
|
+
GetBN(self, bn1); \
|
618
|
+
obj = NewBN(rb_obj_class(self)); \
|
619
|
+
if (!(result = BN_new())) { \
|
620
|
+
ossl_raise(eBNError, NULL); \
|
621
|
+
} \
|
622
|
+
if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \
|
623
|
+
BN_free(result); \
|
624
|
+
ossl_raise(eBNError, NULL); \
|
625
|
+
} \
|
626
|
+
SetBN(obj, result); \
|
627
|
+
return obj; \
|
628
|
+
}
|
629
|
+
|
630
|
+
/*
|
631
|
+
* Document-method: OpenSSL::BN#mod_add
|
632
|
+
* call-seq:
|
633
|
+
* bn.mod_add(bn1, bn2) -> aBN
|
634
|
+
*/
|
635
|
+
BIGNUM_3c(mod_add)
|
636
|
+
|
637
|
+
/*
|
638
|
+
* Document-method: OpenSSL::BN#mod_sub
|
639
|
+
* call-seq:
|
640
|
+
* bn.mod_sub(bn1, bn2) -> aBN
|
641
|
+
*/
|
642
|
+
BIGNUM_3c(mod_sub)
|
643
|
+
|
644
|
+
/*
|
645
|
+
* Document-method: OpenSSL::BN#mod_mul
|
646
|
+
* call-seq:
|
647
|
+
* bn.mod_mul(bn1, bn2) -> aBN
|
648
|
+
*/
|
649
|
+
BIGNUM_3c(mod_mul)
|
650
|
+
|
651
|
+
/*
|
652
|
+
* Document-method: OpenSSL::BN#mod_exp
|
653
|
+
* call-seq:
|
654
|
+
* bn.mod_exp(bn1, bn2) -> aBN
|
655
|
+
*/
|
656
|
+
BIGNUM_3c(mod_exp)
|
657
|
+
|
658
|
+
#define BIGNUM_BIT(func) \
|
659
|
+
static VALUE \
|
660
|
+
ossl_bn_##func(VALUE self, VALUE bit) \
|
661
|
+
{ \
|
662
|
+
BIGNUM *bn; \
|
663
|
+
GetBN(self, bn); \
|
664
|
+
if (BN_##func(bn, NUM2INT(bit)) <= 0) { \
|
665
|
+
ossl_raise(eBNError, NULL); \
|
666
|
+
} \
|
667
|
+
return self; \
|
668
|
+
}
|
669
|
+
|
670
|
+
/*
|
671
|
+
* Document-method: OpenSSL::BN#set_bit!
|
672
|
+
* call-seq:
|
673
|
+
* bn.set_bit!(bit) -> self
|
674
|
+
*/
|
675
|
+
BIGNUM_BIT(set_bit)
|
676
|
+
|
677
|
+
/*
|
678
|
+
* Document-method: OpenSSL::BN#clear_bit!
|
679
|
+
* call-seq:
|
680
|
+
* bn.clear_bit!(bit) -> self
|
681
|
+
*/
|
682
|
+
BIGNUM_BIT(clear_bit)
|
683
|
+
|
684
|
+
/*
|
685
|
+
* Document-method: OpenSSL::BN#mask_bit!
|
686
|
+
* call-seq:
|
687
|
+
* bn.mask_bit!(bit) -> self
|
688
|
+
*/
|
689
|
+
BIGNUM_BIT(mask_bits)
|
690
|
+
|
691
|
+
/*
|
692
|
+
* call-seq:
|
693
|
+
* bn.bit_set?(bit) => true | false
|
694
|
+
*
|
695
|
+
* Tests bit _bit_ in _bn_ and returns +true+ if set, +false+ if not set.
|
696
|
+
*/
|
697
|
+
static VALUE
|
698
|
+
ossl_bn_is_bit_set(VALUE self, VALUE bit)
|
699
|
+
{
|
700
|
+
int b;
|
701
|
+
BIGNUM *bn;
|
702
|
+
|
703
|
+
b = NUM2INT(bit);
|
704
|
+
GetBN(self, bn);
|
705
|
+
if (BN_is_bit_set(bn, b)) {
|
706
|
+
return Qtrue;
|
707
|
+
}
|
708
|
+
return Qfalse;
|
709
|
+
}
|
710
|
+
|
711
|
+
#define BIGNUM_SHIFT(func) \
|
712
|
+
static VALUE \
|
713
|
+
ossl_bn_##func(VALUE self, VALUE bits) \
|
714
|
+
{ \
|
715
|
+
BIGNUM *bn, *result; \
|
716
|
+
int b; \
|
717
|
+
VALUE obj; \
|
718
|
+
b = NUM2INT(bits); \
|
719
|
+
GetBN(self, bn); \
|
720
|
+
obj = NewBN(rb_obj_class(self)); \
|
721
|
+
if (!(result = BN_new())) { \
|
722
|
+
ossl_raise(eBNError, NULL); \
|
723
|
+
} \
|
724
|
+
if (BN_##func(result, bn, b) <= 0) { \
|
725
|
+
BN_free(result); \
|
726
|
+
ossl_raise(eBNError, NULL); \
|
727
|
+
} \
|
728
|
+
SetBN(obj, result); \
|
729
|
+
return obj; \
|
730
|
+
}
|
731
|
+
|
732
|
+
/*
|
733
|
+
* Document-method: OpenSSL::BN#<<
|
734
|
+
* call-seq:
|
735
|
+
* bn << bits -> aBN
|
736
|
+
*/
|
737
|
+
BIGNUM_SHIFT(lshift)
|
738
|
+
|
739
|
+
/*
|
740
|
+
* Document-method: OpenSSL::BN#>>
|
741
|
+
* call-seq:
|
742
|
+
* bn >> bits -> aBN
|
743
|
+
*/
|
744
|
+
BIGNUM_SHIFT(rshift)
|
745
|
+
|
746
|
+
#define BIGNUM_SELF_SHIFT(func) \
|
747
|
+
static VALUE \
|
748
|
+
ossl_bn_self_##func(VALUE self, VALUE bits) \
|
749
|
+
{ \
|
750
|
+
BIGNUM *bn; \
|
751
|
+
int b; \
|
752
|
+
b = NUM2INT(bits); \
|
753
|
+
GetBN(self, bn); \
|
754
|
+
if (BN_##func(bn, bn, b) <= 0) \
|
755
|
+
ossl_raise(eBNError, NULL); \
|
756
|
+
return self; \
|
757
|
+
}
|
758
|
+
|
759
|
+
/*
|
760
|
+
* Document-method: OpenSSL::BN#lshift!
|
761
|
+
* call-seq:
|
762
|
+
* bn.lshift!(bits) -> self
|
763
|
+
*/
|
764
|
+
BIGNUM_SELF_SHIFT(lshift)
|
765
|
+
|
766
|
+
/*
|
767
|
+
* Document-method: OpenSSL::BN#rshift!
|
768
|
+
* call-seq:
|
769
|
+
* bn.rshift!(bits) -> self
|
770
|
+
*/
|
771
|
+
BIGNUM_SELF_SHIFT(rshift)
|
772
|
+
|
773
|
+
#define BIGNUM_RAND(func) \
|
774
|
+
static VALUE \
|
775
|
+
ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \
|
776
|
+
{ \
|
777
|
+
BIGNUM *result; \
|
778
|
+
int bottom = 0, top = 0, b; \
|
779
|
+
VALUE bits, fill, odd, obj; \
|
780
|
+
\
|
781
|
+
switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \
|
782
|
+
case 3: \
|
783
|
+
bottom = (odd == Qtrue) ? 1 : 0; \
|
784
|
+
/* FALLTHROUGH */ \
|
785
|
+
case 2: \
|
786
|
+
top = NUM2INT(fill); \
|
787
|
+
} \
|
788
|
+
b = NUM2INT(bits); \
|
789
|
+
obj = NewBN(klass); \
|
790
|
+
if (!(result = BN_new())) { \
|
791
|
+
ossl_raise(eBNError, NULL); \
|
792
|
+
} \
|
793
|
+
if (BN_##func(result, b, top, bottom) <= 0) { \
|
794
|
+
BN_free(result); \
|
795
|
+
ossl_raise(eBNError, NULL); \
|
796
|
+
} \
|
797
|
+
SetBN(obj, result); \
|
798
|
+
return obj; \
|
799
|
+
}
|
800
|
+
|
801
|
+
/*
|
802
|
+
* Document-method: OpenSSL::BN.rand
|
803
|
+
* BN.rand(bits [, fill [, odd]]) -> aBN
|
804
|
+
*/
|
805
|
+
BIGNUM_RAND(rand)
|
806
|
+
|
807
|
+
/*
|
808
|
+
* Document-method: OpenSSL::BN.pseudo_rand
|
809
|
+
* BN.pseudo_rand(bits [, fill [, odd]]) -> aBN
|
810
|
+
*/
|
811
|
+
BIGNUM_RAND(pseudo_rand)
|
812
|
+
|
813
|
+
#define BIGNUM_RAND_RANGE(func) \
|
814
|
+
static VALUE \
|
815
|
+
ossl_bn_s_##func##_range(VALUE klass, VALUE range) \
|
816
|
+
{ \
|
817
|
+
BIGNUM *bn = GetBNPtr(range), *result; \
|
818
|
+
VALUE obj = NewBN(klass); \
|
819
|
+
if (!(result = BN_new())) { \
|
820
|
+
ossl_raise(eBNError, NULL); \
|
821
|
+
} \
|
822
|
+
if (BN_##func##_range(result, bn) <= 0) { \
|
823
|
+
BN_free(result); \
|
824
|
+
ossl_raise(eBNError, NULL); \
|
825
|
+
} \
|
826
|
+
SetBN(obj, result); \
|
827
|
+
return obj; \
|
828
|
+
}
|
829
|
+
|
830
|
+
/*
|
831
|
+
* Document-method: OpenSSL::BN.rand_range
|
832
|
+
* call-seq:
|
833
|
+
* BN.rand_range(range) -> aBN
|
834
|
+
*
|
835
|
+
*/
|
836
|
+
BIGNUM_RAND_RANGE(rand)
|
837
|
+
|
838
|
+
/*
|
839
|
+
* Document-method: OpenSSL::BN.pseudo_rand_range
|
840
|
+
* call-seq:
|
841
|
+
* BN.pseudo_rand_range(range) -> aBN
|
842
|
+
*
|
843
|
+
*/
|
844
|
+
BIGNUM_RAND_RANGE(pseudo_rand)
|
845
|
+
|
846
|
+
/*
|
847
|
+
* call-seq:
|
848
|
+
* BN.generate_prime(bits, [, safe [, add [, rem]]]) => bn
|
849
|
+
*
|
850
|
+
* Generates a random prime number of bit length _bits_. If _safe_ is set to
|
851
|
+
* +true+, generates a safe prime. If _add_ is specified, generates a prime that
|
852
|
+
* fulfills condition <tt>p % add = rem</tt>.
|
853
|
+
*
|
854
|
+
* === Parameters
|
855
|
+
* * _bits_ - integer
|
856
|
+
* * _safe_ - boolean
|
857
|
+
* * _add_ - BN
|
858
|
+
* * _rem_ - BN
|
859
|
+
*/
|
860
|
+
static VALUE
|
861
|
+
ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
|
862
|
+
{
|
863
|
+
BIGNUM *add = NULL, *rem = NULL, *result;
|
864
|
+
int safe = 1, num;
|
865
|
+
VALUE vnum, vsafe, vadd, vrem, obj;
|
866
|
+
|
867
|
+
rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);
|
868
|
+
|
869
|
+
num = NUM2INT(vnum);
|
870
|
+
|
871
|
+
if (vsafe == Qfalse) {
|
872
|
+
safe = 0;
|
873
|
+
}
|
874
|
+
if (!NIL_P(vadd)) {
|
875
|
+
add = GetBNPtr(vadd);
|
876
|
+
rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
|
877
|
+
}
|
878
|
+
obj = NewBN(klass);
|
879
|
+
if (!(result = BN_new())) {
|
880
|
+
ossl_raise(eBNError, NULL);
|
881
|
+
}
|
882
|
+
if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) {
|
883
|
+
BN_free(result);
|
884
|
+
ossl_raise(eBNError, NULL);
|
885
|
+
}
|
886
|
+
SetBN(obj, result);
|
887
|
+
|
888
|
+
return obj;
|
889
|
+
}
|
890
|
+
|
891
|
+
#define BIGNUM_NUM(func) \
|
892
|
+
static VALUE \
|
893
|
+
ossl_bn_##func(VALUE self) \
|
894
|
+
{ \
|
895
|
+
BIGNUM *bn; \
|
896
|
+
GetBN(self, bn); \
|
897
|
+
return INT2NUM(BN_##func(bn)); \
|
898
|
+
}
|
899
|
+
|
900
|
+
/*
|
901
|
+
* Document-method: OpenSSL::BN#num_bytes
|
902
|
+
* call-seq:
|
903
|
+
* bn.num_bytes => integer
|
904
|
+
*/
|
905
|
+
BIGNUM_NUM(num_bytes)
|
906
|
+
|
907
|
+
/*
|
908
|
+
* Document-method: OpenSSL::BN#num_bits
|
909
|
+
* call-seq:
|
910
|
+
* bn.num_bits => integer
|
911
|
+
*/
|
912
|
+
BIGNUM_NUM(num_bits)
|
913
|
+
|
914
|
+
static VALUE
|
915
|
+
ossl_bn_copy(VALUE self, VALUE other)
|
916
|
+
{
|
917
|
+
BIGNUM *bn1, *bn2;
|
918
|
+
|
919
|
+
rb_check_frozen(self);
|
920
|
+
|
921
|
+
if (self == other) return self;
|
922
|
+
|
923
|
+
GetBN(self, bn1);
|
924
|
+
bn2 = GetBNPtr(other);
|
925
|
+
|
926
|
+
if (!BN_copy(bn1, bn2)) {
|
927
|
+
ossl_raise(eBNError, NULL);
|
928
|
+
}
|
929
|
+
return self;
|
930
|
+
}
|
931
|
+
|
932
|
+
/*
|
933
|
+
* call-seq:
|
934
|
+
* +bn -> aBN
|
935
|
+
*/
|
936
|
+
static VALUE
|
937
|
+
ossl_bn_uplus(VALUE self)
|
938
|
+
{
|
939
|
+
return self;
|
940
|
+
}
|
941
|
+
|
942
|
+
/*
|
943
|
+
* call-seq:
|
944
|
+
* -bn -> aBN
|
945
|
+
*/
|
946
|
+
static VALUE
|
947
|
+
ossl_bn_uminus(VALUE self)
|
948
|
+
{
|
949
|
+
VALUE obj;
|
950
|
+
BIGNUM *bn1, *bn2;
|
951
|
+
|
952
|
+
GetBN(self, bn1);
|
953
|
+
obj = NewBN(cBN);
|
954
|
+
bn2 = BN_dup(bn1);
|
955
|
+
if (!bn2)
|
956
|
+
ossl_raise(eBNError, "BN_dup");
|
957
|
+
SetBN(obj, bn2);
|
958
|
+
BN_set_negative(bn2, !BN_is_negative(bn2));
|
959
|
+
|
960
|
+
return obj;
|
961
|
+
}
|
962
|
+
|
963
|
+
#define BIGNUM_CMP(func) \
|
964
|
+
static VALUE \
|
965
|
+
ossl_bn_##func(VALUE self, VALUE other) \
|
966
|
+
{ \
|
967
|
+
BIGNUM *bn1, *bn2 = GetBNPtr(other); \
|
968
|
+
GetBN(self, bn1); \
|
969
|
+
return INT2NUM(BN_##func(bn1, bn2)); \
|
970
|
+
}
|
971
|
+
|
972
|
+
/*
|
973
|
+
* Document-method: OpenSSL::BN#cmp
|
974
|
+
* call-seq:
|
975
|
+
* bn.cmp(bn2) => integer
|
976
|
+
*/
|
977
|
+
/*
|
978
|
+
* Document-method: OpenSSL::BN#<=>
|
979
|
+
* call-seq:
|
980
|
+
* bn <=> bn2 => integer
|
981
|
+
*/
|
982
|
+
BIGNUM_CMP(cmp)
|
983
|
+
|
984
|
+
/*
|
985
|
+
* Document-method: OpenSSL::BN#ucmp
|
986
|
+
* call-seq:
|
987
|
+
* bn.ucmp(bn2) => integer
|
988
|
+
*/
|
989
|
+
BIGNUM_CMP(ucmp)
|
990
|
+
|
991
|
+
/*
|
992
|
+
* call-seq:
|
993
|
+
* bn == obj => true or false
|
994
|
+
*
|
995
|
+
* Returns +true+ only if _obj_ has the same value as _bn_. Contrast this
|
996
|
+
* with OpenSSL::BN#eql?, which requires obj to be OpenSSL::BN.
|
997
|
+
*/
|
998
|
+
static VALUE
|
999
|
+
ossl_bn_eq(VALUE self, VALUE other)
|
1000
|
+
{
|
1001
|
+
BIGNUM *bn1, *bn2;
|
1002
|
+
|
1003
|
+
GetBN(self, bn1);
|
1004
|
+
other = try_convert_to_bn(other);
|
1005
|
+
if (NIL_P(other))
|
1006
|
+
return Qfalse;
|
1007
|
+
GetBN(other, bn2);
|
1008
|
+
|
1009
|
+
if (!BN_cmp(bn1, bn2)) {
|
1010
|
+
return Qtrue;
|
1011
|
+
}
|
1012
|
+
return Qfalse;
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
/*
|
1016
|
+
* call-seq:
|
1017
|
+
* bn.eql?(obj) => true or false
|
1018
|
+
*
|
1019
|
+
* Returns <code>true</code> only if <i>obj</i> is a
|
1020
|
+
* <code>OpenSSL::BN</code> with the same value as <i>bn</i>. Contrast this
|
1021
|
+
* with OpenSSL::BN#==, which performs type conversions.
|
1022
|
+
*/
|
1023
|
+
static VALUE
|
1024
|
+
ossl_bn_eql(VALUE self, VALUE other)
|
1025
|
+
{
|
1026
|
+
BIGNUM *bn1, *bn2;
|
1027
|
+
|
1028
|
+
if (!rb_obj_is_kind_of(other, cBN))
|
1029
|
+
return Qfalse;
|
1030
|
+
GetBN(self, bn1);
|
1031
|
+
GetBN(other, bn2);
|
1032
|
+
|
1033
|
+
return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
/*
|
1037
|
+
* call-seq:
|
1038
|
+
* bn.hash => Integer
|
1039
|
+
*
|
1040
|
+
* Returns a hash code for this object.
|
1041
|
+
*
|
1042
|
+
* See also Object#hash.
|
1043
|
+
*/
|
1044
|
+
static VALUE
|
1045
|
+
ossl_bn_hash(VALUE self)
|
1046
|
+
{
|
1047
|
+
BIGNUM *bn;
|
1048
|
+
VALUE tmp, hash;
|
1049
|
+
unsigned char *buf;
|
1050
|
+
int len;
|
1051
|
+
|
1052
|
+
GetBN(self, bn);
|
1053
|
+
len = BN_num_bytes(bn);
|
1054
|
+
buf = ALLOCV(tmp, len);
|
1055
|
+
if (BN_bn2bin(bn, buf) != len) {
|
1056
|
+
ALLOCV_END(tmp);
|
1057
|
+
ossl_raise(eBNError, "BN_bn2bin");
|
1058
|
+
}
|
1059
|
+
|
1060
|
+
hash = ST2FIX(rb_memhash(buf, len));
|
1061
|
+
ALLOCV_END(tmp);
|
1062
|
+
|
1063
|
+
return hash;
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
/*
|
1067
|
+
* call-seq:
|
1068
|
+
* bn.prime? => true | false
|
1069
|
+
* bn.prime?(checks) => true | false
|
1070
|
+
*
|
1071
|
+
* Performs a Miller-Rabin probabilistic primality test with _checks_
|
1072
|
+
* iterations. If _checks_ is not specified, a number of iterations is used
|
1073
|
+
* that yields a false positive rate of at most 2^-80 for random input.
|
1074
|
+
*
|
1075
|
+
* === Parameters
|
1076
|
+
* * _checks_ - integer
|
1077
|
+
*/
|
1078
|
+
static VALUE
|
1079
|
+
ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
|
1080
|
+
{
|
1081
|
+
BIGNUM *bn;
|
1082
|
+
VALUE vchecks;
|
1083
|
+
int checks = BN_prime_checks;
|
1084
|
+
|
1085
|
+
if (rb_scan_args(argc, argv, "01", &vchecks) == 1) {
|
1086
|
+
checks = NUM2INT(vchecks);
|
1087
|
+
}
|
1088
|
+
GetBN(self, bn);
|
1089
|
+
switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) {
|
1090
|
+
case 1:
|
1091
|
+
return Qtrue;
|
1092
|
+
case 0:
|
1093
|
+
return Qfalse;
|
1094
|
+
default:
|
1095
|
+
ossl_raise(eBNError, NULL);
|
1096
|
+
}
|
1097
|
+
/* not reachable */
|
1098
|
+
return Qnil;
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
/*
|
1102
|
+
* call-seq:
|
1103
|
+
* bn.prime_fasttest? => true | false
|
1104
|
+
* bn.prime_fasttest?(checks) => true | false
|
1105
|
+
* bn.prime_fasttest?(checks, trial_div) => true | false
|
1106
|
+
*
|
1107
|
+
* Performs a Miller-Rabin primality test. This is same as #prime? except this
|
1108
|
+
* first attempts trial divisions with some small primes.
|
1109
|
+
*
|
1110
|
+
* === Parameters
|
1111
|
+
* * _checks_ - integer
|
1112
|
+
* * _trial_div_ - boolean
|
1113
|
+
*/
|
1114
|
+
static VALUE
|
1115
|
+
ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
|
1116
|
+
{
|
1117
|
+
BIGNUM *bn;
|
1118
|
+
VALUE vchecks, vtrivdiv;
|
1119
|
+
int checks = BN_prime_checks, do_trial_division = 1;
|
1120
|
+
|
1121
|
+
rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv);
|
1122
|
+
|
1123
|
+
if (!NIL_P(vchecks)) {
|
1124
|
+
checks = NUM2INT(vchecks);
|
1125
|
+
}
|
1126
|
+
GetBN(self, bn);
|
1127
|
+
/* handle true/false */
|
1128
|
+
if (vtrivdiv == Qfalse) {
|
1129
|
+
do_trial_division = 0;
|
1130
|
+
}
|
1131
|
+
switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) {
|
1132
|
+
case 1:
|
1133
|
+
return Qtrue;
|
1134
|
+
case 0:
|
1135
|
+
return Qfalse;
|
1136
|
+
default:
|
1137
|
+
ossl_raise(eBNError, NULL);
|
1138
|
+
}
|
1139
|
+
/* not reachable */
|
1140
|
+
return Qnil;
|
1141
|
+
}
|
1142
|
+
|
1143
|
+
/*
|
1144
|
+
* INIT
|
1145
|
+
* (NOTE: ordering of methods is the same as in 'man bn')
|
1146
|
+
*/
|
1147
|
+
void
|
1148
|
+
Init_ossl_bn(void)
|
1149
|
+
{
|
1150
|
+
#if 0
|
1151
|
+
mOSSL = rb_define_module("OpenSSL");
|
1152
|
+
eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError);
|
1153
|
+
#endif
|
1154
|
+
|
1155
|
+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
1156
|
+
ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type);
|
1157
|
+
#else
|
1158
|
+
ossl_bn_ctx_get();
|
1159
|
+
#endif
|
1160
|
+
|
1161
|
+
eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError);
|
1162
|
+
|
1163
|
+
cBN = rb_define_class_under(mOSSL, "BN", rb_cObject);
|
1164
|
+
|
1165
|
+
rb_define_alloc_func(cBN, ossl_bn_alloc);
|
1166
|
+
rb_define_method(cBN, "initialize", ossl_bn_initialize, -1);
|
1167
|
+
|
1168
|
+
rb_define_method(cBN, "initialize_copy", ossl_bn_copy, 1);
|
1169
|
+
rb_define_method(cBN, "copy", ossl_bn_copy, 1);
|
1170
|
+
|
1171
|
+
/* swap (=coerce?) */
|
1172
|
+
|
1173
|
+
rb_define_method(cBN, "num_bytes", ossl_bn_num_bytes, 0);
|
1174
|
+
rb_define_method(cBN, "num_bits", ossl_bn_num_bits, 0);
|
1175
|
+
/* num_bits_word */
|
1176
|
+
|
1177
|
+
rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
|
1178
|
+
rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
|
1179
|
+
|
1180
|
+
rb_define_method(cBN, "+", ossl_bn_add, 1);
|
1181
|
+
rb_define_method(cBN, "-", ossl_bn_sub, 1);
|
1182
|
+
rb_define_method(cBN, "*", ossl_bn_mul, 1);
|
1183
|
+
rb_define_method(cBN, "sqr", ossl_bn_sqr, 0);
|
1184
|
+
rb_define_method(cBN, "/", ossl_bn_div, 1);
|
1185
|
+
rb_define_method(cBN, "%", ossl_bn_mod, 1);
|
1186
|
+
/* nnmod */
|
1187
|
+
|
1188
|
+
rb_define_method(cBN, "mod_add", ossl_bn_mod_add, 2);
|
1189
|
+
rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2);
|
1190
|
+
rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2);
|
1191
|
+
rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1);
|
1192
|
+
rb_define_method(cBN, "**", ossl_bn_exp, 1);
|
1193
|
+
rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2);
|
1194
|
+
rb_define_method(cBN, "gcd", ossl_bn_gcd, 1);
|
1195
|
+
|
1196
|
+
/* add_word
|
1197
|
+
* sub_word
|
1198
|
+
* mul_word
|
1199
|
+
* div_word
|
1200
|
+
* mod_word */
|
1201
|
+
|
1202
|
+
rb_define_method(cBN, "cmp", ossl_bn_cmp, 1);
|
1203
|
+
rb_define_alias(cBN, "<=>", "cmp");
|
1204
|
+
rb_define_method(cBN, "ucmp", ossl_bn_ucmp, 1);
|
1205
|
+
rb_define_method(cBN, "eql?", ossl_bn_eql, 1);
|
1206
|
+
rb_define_method(cBN, "hash", ossl_bn_hash, 0);
|
1207
|
+
rb_define_method(cBN, "==", ossl_bn_eq, 1);
|
1208
|
+
rb_define_alias(cBN, "===", "==");
|
1209
|
+
rb_define_method(cBN, "zero?", ossl_bn_is_zero, 0);
|
1210
|
+
rb_define_method(cBN, "one?", ossl_bn_is_one, 0);
|
1211
|
+
/* is_word */
|
1212
|
+
rb_define_method(cBN, "odd?", ossl_bn_is_odd, 0);
|
1213
|
+
rb_define_method(cBN, "negative?", ossl_bn_is_negative, 0);
|
1214
|
+
|
1215
|
+
/* zero
|
1216
|
+
* one
|
1217
|
+
* value_one - DON'T IMPL.
|
1218
|
+
* set_word
|
1219
|
+
* get_word */
|
1220
|
+
|
1221
|
+
rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1);
|
1222
|
+
rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1);
|
1223
|
+
rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1);
|
1224
|
+
rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1);
|
1225
|
+
|
1226
|
+
rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1);
|
1227
|
+
rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1);
|
1228
|
+
rb_define_method(cBN, "prime_fasttest?", ossl_bn_is_prime_fasttest, -1);
|
1229
|
+
|
1230
|
+
rb_define_method(cBN, "set_bit!", ossl_bn_set_bit, 1);
|
1231
|
+
rb_define_method(cBN, "clear_bit!", ossl_bn_clear_bit, 1);
|
1232
|
+
rb_define_method(cBN, "bit_set?", ossl_bn_is_bit_set, 1);
|
1233
|
+
rb_define_method(cBN, "mask_bits!", ossl_bn_mask_bits, 1);
|
1234
|
+
rb_define_method(cBN, "<<", ossl_bn_lshift, 1);
|
1235
|
+
rb_define_method(cBN, ">>", ossl_bn_rshift, 1);
|
1236
|
+
rb_define_method(cBN, "lshift!", ossl_bn_self_lshift, 1);
|
1237
|
+
rb_define_method(cBN, "rshift!", ossl_bn_self_rshift, 1);
|
1238
|
+
/* lshift1 - DON'T IMPL. */
|
1239
|
+
/* rshift1 - DON'T IMPL. */
|
1240
|
+
|
1241
|
+
/*
|
1242
|
+
* bn2bin
|
1243
|
+
* bin2bn
|
1244
|
+
* bn2hex
|
1245
|
+
* bn2dec
|
1246
|
+
* hex2bn
|
1247
|
+
* dec2bn - all these are implemented in ossl_bn_initialize, and ossl_bn_to_s
|
1248
|
+
* print - NOT IMPL.
|
1249
|
+
* print_fp - NOT IMPL.
|
1250
|
+
* bn2mpi
|
1251
|
+
* mpi2bn
|
1252
|
+
*/
|
1253
|
+
rb_define_method(cBN, "to_s", ossl_bn_to_s, -1);
|
1254
|
+
rb_define_method(cBN, "to_i", ossl_bn_to_i, 0);
|
1255
|
+
rb_define_alias(cBN, "to_int", "to_i");
|
1256
|
+
rb_define_method(cBN, "to_bn", ossl_bn_to_bn, 0);
|
1257
|
+
rb_define_method(cBN, "coerce", ossl_bn_coerce, 1);
|
1258
|
+
|
1259
|
+
/*
|
1260
|
+
* TODO:
|
1261
|
+
* But how to: from_bin, from_mpi? PACK?
|
1262
|
+
* to_bin
|
1263
|
+
* to_mpi
|
1264
|
+
*/
|
1265
|
+
|
1266
|
+
rb_define_method(cBN, "mod_inverse", ossl_bn_mod_inverse, 1);
|
1267
|
+
|
1268
|
+
/* RECiProcal
|
1269
|
+
* MONTgomery */
|
1270
|
+
}
|