rubysl-openssl 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -6
- data/ext/rubysl/openssl/.gitignore +3 -0
- data/ext/rubysl/openssl/deprecation.rb +21 -0
- data/ext/rubysl/openssl/extconf.rb +45 -32
- data/ext/rubysl/openssl/openssl_missing.c +20 -7
- data/ext/rubysl/openssl/openssl_missing.h +22 -15
- data/ext/rubysl/openssl/ossl.c +610 -61
- data/ext/rubysl/openssl/ossl.h +31 -17
- data/ext/rubysl/openssl/ossl_asn1.c +974 -183
- data/ext/rubysl/openssl/ossl_asn1.h +3 -3
- data/ext/rubysl/openssl/ossl_bio.c +4 -3
- data/ext/rubysl/openssl/ossl_bio.h +1 -1
- data/ext/rubysl/openssl/ossl_bn.c +32 -28
- data/ext/rubysl/openssl/ossl_bn.h +1 -1
- data/ext/rubysl/openssl/ossl_cipher.c +494 -93
- data/ext/rubysl/openssl/ossl_cipher.h +1 -1
- data/ext/rubysl/openssl/ossl_config.c +4 -5
- data/ext/rubysl/openssl/ossl_config.h +1 -1
- data/ext/rubysl/openssl/ossl_digest.c +206 -24
- data/ext/rubysl/openssl/ossl_digest.h +1 -1
- data/ext/rubysl/openssl/ossl_engine.c +48 -26
- data/ext/rubysl/openssl/ossl_engine.h +1 -1
- data/ext/rubysl/openssl/ossl_hmac.c +40 -38
- data/ext/rubysl/openssl/ossl_hmac.h +1 -1
- data/ext/rubysl/openssl/ossl_ns_spki.c +157 -25
- data/ext/rubysl/openssl/ossl_ns_spki.h +1 -1
- data/ext/rubysl/openssl/ossl_ocsp.c +57 -40
- data/ext/rubysl/openssl/ossl_ocsp.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs12.c +15 -13
- data/ext/rubysl/openssl/ossl_pkcs12.h +1 -1
- data/ext/rubysl/openssl/ossl_pkcs5.c +108 -18
- data/ext/rubysl/openssl/ossl_pkcs7.c +44 -37
- data/ext/rubysl/openssl/ossl_pkcs7.h +1 -1
- data/ext/rubysl/openssl/ossl_pkey.c +211 -15
- data/ext/rubysl/openssl/ossl_pkey.h +19 -9
- data/ext/rubysl/openssl/ossl_pkey_dh.c +180 -47
- data/ext/rubysl/openssl/ossl_pkey_dsa.c +184 -47
- data/ext/rubysl/openssl/ossl_pkey_ec.c +177 -93
- data/ext/rubysl/openssl/ossl_pkey_rsa.c +209 -102
- data/ext/rubysl/openssl/ossl_rand.c +15 -15
- data/ext/rubysl/openssl/ossl_rand.h +1 -1
- data/ext/rubysl/openssl/ossl_ssl.c +939 -192
- data/ext/rubysl/openssl/ossl_ssl.h +6 -6
- data/ext/rubysl/openssl/ossl_ssl_session.c +78 -62
- data/ext/rubysl/openssl/ossl_version.h +2 -2
- data/ext/rubysl/openssl/ossl_x509.c +1 -1
- data/ext/rubysl/openssl/ossl_x509.h +1 -1
- data/ext/rubysl/openssl/ossl_x509attr.c +20 -19
- data/ext/rubysl/openssl/ossl_x509cert.c +169 -67
- data/ext/rubysl/openssl/ossl_x509crl.c +41 -39
- data/ext/rubysl/openssl/ossl_x509ext.c +51 -38
- data/ext/rubysl/openssl/ossl_x509name.c +139 -29
- data/ext/rubysl/openssl/ossl_x509req.c +42 -40
- data/ext/rubysl/openssl/ossl_x509revoked.c +20 -20
- data/ext/rubysl/openssl/ossl_x509store.c +99 -47
- data/ext/rubysl/openssl/ruby_missing.h +3 -16
- data/lib/openssl/bn.rb +19 -19
- data/lib/openssl/buffering.rb +222 -14
- data/lib/openssl/cipher.rb +20 -20
- data/lib/openssl/config.rb +1 -4
- data/lib/openssl/digest.rb +47 -19
- data/lib/openssl/ssl.rb +197 -1
- data/lib/openssl/x509.rb +162 -1
- data/lib/rubysl/openssl.rb +4 -8
- data/lib/rubysl/openssl/version.rb +1 -1
- data/rubysl-openssl.gemspec +1 -2
- metadata +16 -34
- data/ext/rubysl/openssl/extconf.h +0 -50
- data/lib/openssl/net/ftptls.rb +0 -53
- data/lib/openssl/net/telnets.rb +0 -251
- data/lib/openssl/pkcs7.rb +0 -25
- data/lib/openssl/ssl-internal.rb +0 -187
- data/lib/openssl/x509-internal.rb +0 -153
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* $Id
|
2
|
+
* $Id$
|
3
3
|
* 'OpenSSL for Ruby' project
|
4
4
|
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
|
5
5
|
* All rights reserved.
|
@@ -13,8 +13,8 @@
|
|
13
13
|
#include "ossl.h"
|
14
14
|
|
15
15
|
#define GetPKeyDSA(obj, pkey) do { \
|
16
|
-
GetPKey(obj, pkey); \
|
17
|
-
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_DSA) { /* PARANOIA? */ \
|
16
|
+
GetPKey((obj), (pkey)); \
|
17
|
+
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_DSA) { /* PARANOIA? */ \
|
18
18
|
ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \
|
19
19
|
} \
|
20
20
|
} while (0)
|
@@ -36,7 +36,7 @@ dsa_instance(VALUE klass, DSA *dsa)
|
|
36
36
|
{
|
37
37
|
EVP_PKEY *pkey;
|
38
38
|
VALUE obj;
|
39
|
-
|
39
|
+
|
40
40
|
if (!dsa) {
|
41
41
|
return Qfalse;
|
42
42
|
}
|
@@ -75,9 +75,69 @@ ossl_dsa_new(EVP_PKEY *pkey)
|
|
75
75
|
/*
|
76
76
|
* Private
|
77
77
|
*/
|
78
|
+
#if defined(HAVE_DSA_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB
|
79
|
+
struct dsa_blocking_gen_arg {
|
80
|
+
DSA *dsa;
|
81
|
+
int size;
|
82
|
+
unsigned char* seed;
|
83
|
+
int seed_len;
|
84
|
+
int *counter;
|
85
|
+
unsigned long *h;
|
86
|
+
BN_GENCB *cb;
|
87
|
+
int result;
|
88
|
+
};
|
89
|
+
|
90
|
+
static void *
|
91
|
+
dsa_blocking_gen(void *arg)
|
92
|
+
{
|
93
|
+
struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg;
|
94
|
+
gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, gen->seed, gen->seed_len, gen->counter, gen->h, gen->cb);
|
95
|
+
return 0;
|
96
|
+
}
|
97
|
+
#endif
|
98
|
+
|
78
99
|
static DSA *
|
79
100
|
dsa_generate(int size)
|
80
101
|
{
|
102
|
+
#if defined(HAVE_DSA_GENERATE_PARAMETERS_EX) && HAVE_BN_GENCB
|
103
|
+
BN_GENCB cb;
|
104
|
+
struct ossl_generate_cb_arg cb_arg;
|
105
|
+
struct dsa_blocking_gen_arg gen_arg;
|
106
|
+
DSA *dsa = DSA_new();
|
107
|
+
unsigned char seed[20];
|
108
|
+
int seed_len = 20, counter;
|
109
|
+
unsigned long h;
|
110
|
+
|
111
|
+
if (!dsa) return 0;
|
112
|
+
if (!RAND_bytes(seed, seed_len)) {
|
113
|
+
DSA_free(dsa);
|
114
|
+
return 0;
|
115
|
+
}
|
116
|
+
|
117
|
+
memset(&cb_arg, 0, sizeof(struct ossl_generate_cb_arg));
|
118
|
+
if (rb_block_given_p())
|
119
|
+
cb_arg.yield = 1;
|
120
|
+
BN_GENCB_set(&cb, ossl_generate_cb_2, &cb_arg);
|
121
|
+
gen_arg.dsa = dsa;
|
122
|
+
gen_arg.size = size;
|
123
|
+
gen_arg.seed = seed;
|
124
|
+
gen_arg.seed_len = seed_len;
|
125
|
+
gen_arg.counter = &counter;
|
126
|
+
gen_arg.h = &h;
|
127
|
+
gen_arg.cb = &cb;
|
128
|
+
if (cb_arg.yield == 1) {
|
129
|
+
/* we cannot release GVL when callback proc is supplied */
|
130
|
+
dsa_blocking_gen(&gen_arg);
|
131
|
+
} else {
|
132
|
+
/* there's a chance to unblock */
|
133
|
+
rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg);
|
134
|
+
}
|
135
|
+
if (!gen_arg.result) {
|
136
|
+
DSA_free(dsa);
|
137
|
+
if (cb_arg.state) rb_jump_tag(cb_arg.state);
|
138
|
+
return 0;
|
139
|
+
}
|
140
|
+
#else
|
81
141
|
DSA *dsa;
|
82
142
|
unsigned char seed[20];
|
83
143
|
int seed_len = 20, counter;
|
@@ -87,9 +147,9 @@ dsa_generate(int size)
|
|
87
147
|
return 0;
|
88
148
|
}
|
89
149
|
dsa = DSA_generate_parameters(size, seed, seed_len, &counter, &h,
|
90
|
-
rb_block_given_p() ? ossl_generate_cb : NULL,
|
91
|
-
NULL);
|
150
|
+
rb_block_given_p() ? ossl_generate_cb : NULL, NULL);
|
92
151
|
if(!dsa) return 0;
|
152
|
+
#endif
|
93
153
|
|
94
154
|
if (!DSA_generate_key(dsa)) {
|
95
155
|
DSA_free(dsa);
|
@@ -103,8 +163,11 @@ dsa_generate(int size)
|
|
103
163
|
* call-seq:
|
104
164
|
* DSA.generate(size) -> dsa
|
105
165
|
*
|
106
|
-
*
|
107
|
-
*
|
166
|
+
* Creates a new DSA instance by generating a private/public key pair
|
167
|
+
* from scratch.
|
168
|
+
*
|
169
|
+
* === Parameters
|
170
|
+
* * +size+ is an integer representing the desired key size.
|
108
171
|
*
|
109
172
|
*/
|
110
173
|
static VALUE
|
@@ -125,16 +188,18 @@ ossl_dsa_s_generate(VALUE klass, VALUE size)
|
|
125
188
|
* call-seq:
|
126
189
|
* DSA.new([size | string [, pass]) -> dsa
|
127
190
|
*
|
128
|
-
*
|
129
|
-
* * +size+ is an integer representing the desired key size.
|
130
|
-
* * +string+ contains a DER or PEM encoded key.
|
131
|
-
* * +pass+ is a string that contains a optional password.
|
191
|
+
* Creates a new DSA instance by reading an existing key from +string+.
|
132
192
|
*
|
133
|
-
*
|
134
|
-
*
|
135
|
-
*
|
136
|
-
*
|
137
|
-
*
|
193
|
+
* === Parameters
|
194
|
+
* * +size+ is an integer representing the desired key size.
|
195
|
+
* * +string+ contains a DER or PEM encoded key.
|
196
|
+
* * +pass+ is a string that contains an optional password.
|
197
|
+
*
|
198
|
+
* === Examples
|
199
|
+
* DSA.new -> dsa
|
200
|
+
* DSA.new(1024) -> dsa
|
201
|
+
* DSA.new(File.read('dsa.pem')) -> dsa
|
202
|
+
* DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa
|
138
203
|
*
|
139
204
|
*/
|
140
205
|
static VALUE
|
@@ -145,7 +210,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
|
145
210
|
BIO *in;
|
146
211
|
char *passwd = NULL;
|
147
212
|
VALUE arg, pass;
|
148
|
-
|
213
|
+
|
149
214
|
GetPKey(self, pkey);
|
150
215
|
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
|
151
216
|
dsa = DSA_new();
|
@@ -161,23 +226,26 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
|
161
226
|
in = ossl_obj2bio(arg);
|
162
227
|
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
|
163
228
|
if (!dsa) {
|
164
|
-
|
165
|
-
dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
|
166
|
-
}
|
167
|
-
if (!dsa) {
|
168
|
-
BIO_reset(in);
|
229
|
+
OSSL_BIO_reset(in);
|
169
230
|
dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
|
170
231
|
}
|
171
232
|
if (!dsa) {
|
172
|
-
|
233
|
+
OSSL_BIO_reset(in);
|
173
234
|
dsa = d2i_DSAPrivateKey_bio(in, NULL);
|
174
235
|
}
|
175
236
|
if (!dsa) {
|
176
|
-
|
237
|
+
OSSL_BIO_reset(in);
|
177
238
|
dsa = d2i_DSA_PUBKEY_bio(in, NULL);
|
178
239
|
}
|
240
|
+
if (!dsa) {
|
241
|
+
OSSL_BIO_reset(in);
|
242
|
+
dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
|
243
|
+
}
|
179
244
|
BIO_free(in);
|
180
|
-
if (!dsa)
|
245
|
+
if (!dsa) {
|
246
|
+
ERR_clear_error();
|
247
|
+
ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
|
248
|
+
}
|
181
249
|
}
|
182
250
|
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
|
183
251
|
DSA_free(dsa);
|
@@ -191,6 +259,8 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
|
|
191
259
|
* call-seq:
|
192
260
|
* dsa.public? -> true | false
|
193
261
|
*
|
262
|
+
* Indicates whether this DSA instance has a public key associated with it or
|
263
|
+
* not. The public key may be retrieved with DSA#public_key.
|
194
264
|
*/
|
195
265
|
static VALUE
|
196
266
|
ossl_dsa_is_public(VALUE self)
|
@@ -206,14 +276,16 @@ ossl_dsa_is_public(VALUE self)
|
|
206
276
|
* call-seq:
|
207
277
|
* dsa.private? -> true | false
|
208
278
|
*
|
279
|
+
* Indicates whether this DSA instance has a private key associated with it or
|
280
|
+
* not. The private key may be retrieved with DSA#private_key.
|
209
281
|
*/
|
210
282
|
static VALUE
|
211
283
|
ossl_dsa_is_private(VALUE self)
|
212
284
|
{
|
213
285
|
EVP_PKEY *pkey;
|
214
|
-
|
286
|
+
|
215
287
|
GetPKeyDSA(self, pkey);
|
216
|
-
|
288
|
+
|
217
289
|
return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
|
218
290
|
}
|
219
291
|
|
@@ -221,13 +293,15 @@ ossl_dsa_is_private(VALUE self)
|
|
221
293
|
* call-seq:
|
222
294
|
* dsa.to_pem([cipher, password]) -> aString
|
223
295
|
*
|
224
|
-
*
|
225
|
-
* +cipher+ is an OpenSSL::Cipher.
|
226
|
-
* +password+ is a string containing your password.
|
296
|
+
* Encodes this DSA to its PEM encoding.
|
227
297
|
*
|
228
|
-
*
|
229
|
-
*
|
230
|
-
*
|
298
|
+
* === Parameters
|
299
|
+
* * +cipher+ is an OpenSSL::Cipher.
|
300
|
+
* * +password+ is a string containing your password.
|
301
|
+
*
|
302
|
+
* === Examples
|
303
|
+
* DSA.to_pem -> aString
|
304
|
+
* DSA.to_pem(cipher, 'mypassword') -> aString
|
231
305
|
*
|
232
306
|
*/
|
233
307
|
static VALUE
|
@@ -244,7 +318,10 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
|
|
244
318
|
if (!NIL_P(cipher)) {
|
245
319
|
ciph = GetCipherPtr(cipher);
|
246
320
|
if (!NIL_P(pass)) {
|
247
|
-
|
321
|
+
StringValue(pass);
|
322
|
+
if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
|
323
|
+
ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
|
324
|
+
passwd = RSTRING_PTR(pass);
|
248
325
|
}
|
249
326
|
}
|
250
327
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
@@ -257,7 +334,7 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
|
|
257
334
|
ossl_raise(eDSAError, NULL);
|
258
335
|
}
|
259
336
|
} else {
|
260
|
-
if (!
|
337
|
+
if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.dsa)) {
|
261
338
|
BIO_free(out);
|
262
339
|
ossl_raise(eDSAError, NULL);
|
263
340
|
}
|
@@ -271,6 +348,8 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self)
|
|
271
348
|
* call-seq:
|
272
349
|
* dsa.to_der -> aString
|
273
350
|
*
|
351
|
+
* Encodes this DSA to its DER encoding.
|
352
|
+
*
|
274
353
|
*/
|
275
354
|
static VALUE
|
276
355
|
ossl_dsa_to_der(VALUE self)
|
@@ -289,7 +368,7 @@ ossl_dsa_to_der(VALUE self)
|
|
289
368
|
if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
|
290
369
|
ossl_raise(eDSAError, NULL);
|
291
370
|
str = rb_str_new(0, len);
|
292
|
-
p = RSTRING_PTR(str);
|
371
|
+
p = (unsigned char *)RSTRING_PTR(str);
|
293
372
|
if(i2d_func(pkey->pkey.dsa, &p) < 0)
|
294
373
|
ossl_raise(eDSAError, NULL);
|
295
374
|
ossl_str_adjust(str, p);
|
@@ -320,7 +399,7 @@ ossl_dsa_get_params(VALUE self)
|
|
320
399
|
rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g));
|
321
400
|
rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key));
|
322
401
|
rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key));
|
323
|
-
|
402
|
+
|
324
403
|
return hash;
|
325
404
|
}
|
326
405
|
|
@@ -356,7 +435,18 @@ ossl_dsa_to_text(VALUE self)
|
|
356
435
|
* call-seq:
|
357
436
|
* dsa.public_key -> aDSA
|
358
437
|
*
|
359
|
-
*
|
438
|
+
* Returns a new DSA instance that carries just the public key information.
|
439
|
+
* If the current instance has also private key information, this will no
|
440
|
+
* longer be present in the new instance. This feature is helpful for
|
441
|
+
* publishing the public key information without leaking any of the private
|
442
|
+
* information.
|
443
|
+
*
|
444
|
+
* === Example
|
445
|
+
* dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information
|
446
|
+
* pub_key = dsa.public_key # has only the public part available
|
447
|
+
* pub_key_der = pub_key.to_der # it's safe to publish this
|
448
|
+
*
|
449
|
+
*
|
360
450
|
*/
|
361
451
|
static VALUE
|
362
452
|
ossl_dsa_to_public_key(VALUE self)
|
@@ -364,7 +454,7 @@ ossl_dsa_to_public_key(VALUE self)
|
|
364
454
|
EVP_PKEY *pkey;
|
365
455
|
DSA *dsa;
|
366
456
|
VALUE obj;
|
367
|
-
|
457
|
+
|
368
458
|
GetPKeyDSA(self, pkey);
|
369
459
|
/* err check performed by dsa_instance */
|
370
460
|
dsa = DSAPublicKey_dup(pkey->pkey.dsa);
|
@@ -382,12 +472,26 @@ ossl_dsa_to_public_key(VALUE self)
|
|
382
472
|
* call-seq:
|
383
473
|
* dsa.syssign(string) -> aString
|
384
474
|
*
|
475
|
+
* Computes and returns the DSA signature of +string+, where +string+ is
|
476
|
+
* expected to be an already-computed message digest of the original input
|
477
|
+
* data. The signature is issued using the private key of this DSA instance.
|
478
|
+
*
|
479
|
+
* === Parameters
|
480
|
+
* * +string+ is a message digest of the original input data to be signed
|
481
|
+
*
|
482
|
+
* === Example
|
483
|
+
* dsa = OpenSSL::PKey::DSA.new(2048)
|
484
|
+
* doc = "Sign me"
|
485
|
+
* digest = OpenSSL::Digest::SHA1.digest(doc)
|
486
|
+
* sig = dsa.syssign(digest)
|
487
|
+
*
|
488
|
+
*
|
385
489
|
*/
|
386
490
|
static VALUE
|
387
491
|
ossl_dsa_sign(VALUE self, VALUE data)
|
388
492
|
{
|
389
493
|
EVP_PKEY *pkey;
|
390
|
-
int buf_len;
|
494
|
+
unsigned int buf_len;
|
391
495
|
VALUE str;
|
392
496
|
|
393
497
|
GetPKeyDSA(self, pkey);
|
@@ -396,7 +500,8 @@ ossl_dsa_sign(VALUE self, VALUE data)
|
|
396
500
|
ossl_raise(eDSAError, "Private DSA key needed!");
|
397
501
|
}
|
398
502
|
str = rb_str_new(0, ossl_dsa_buf_size(pkey));
|
399
|
-
if (!DSA_sign(0, RSTRING_PTR(data),
|
503
|
+
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
|
504
|
+
(unsigned char *)RSTRING_PTR(str),
|
400
505
|
&buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */
|
401
506
|
ossl_raise(eDSAError, NULL);
|
402
507
|
}
|
@@ -409,6 +514,20 @@ ossl_dsa_sign(VALUE self, VALUE data)
|
|
409
514
|
* call-seq:
|
410
515
|
* dsa.sysverify(digest, sig) -> true | false
|
411
516
|
*
|
517
|
+
* Verifies whether the signature is valid given the message digest input. It
|
518
|
+
* does so by validating +sig+ using the public key of this DSA instance.
|
519
|
+
*
|
520
|
+
* === Parameters
|
521
|
+
* * +digest+ is a message digest of the original input data to be signed
|
522
|
+
* * +sig+ is a DSA signature value
|
523
|
+
*
|
524
|
+
* === Example
|
525
|
+
* dsa = OpenSSL::PKey::DSA.new(2048)
|
526
|
+
* doc = "Sign me"
|
527
|
+
* digest = OpenSSL::Digest::SHA1.digest(doc)
|
528
|
+
* sig = dsa.syssign(digest)
|
529
|
+
* puts dsa.sysverify(digest, sig) # => true
|
530
|
+
*
|
412
531
|
*/
|
413
532
|
static VALUE
|
414
533
|
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
|
@@ -420,8 +539,8 @@ ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
|
|
420
539
|
StringValue(digest);
|
421
540
|
StringValue(sig);
|
422
541
|
/* type is ignored (0) */
|
423
|
-
ret = DSA_verify(0, RSTRING_PTR(digest),
|
424
|
-
RSTRING_PTR(sig),
|
542
|
+
ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
|
543
|
+
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey->pkey.dsa);
|
425
544
|
if (ret < 0) {
|
426
545
|
ossl_raise(eDSAError, NULL);
|
427
546
|
}
|
@@ -444,15 +563,33 @@ OSSL_PKEY_BN(dsa, priv_key)
|
|
444
563
|
void
|
445
564
|
Init_ossl_dsa()
|
446
565
|
{
|
447
|
-
#if 0
|
448
|
-
mOSSL = rb_define_module("OpenSSL");
|
566
|
+
#if 0
|
567
|
+
mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
|
449
568
|
mPKey = rb_define_module_under(mOSSL, "PKey");
|
450
569
|
#endif
|
451
570
|
|
571
|
+
/* Document-class: OpenSSL::PKey::DSAError
|
572
|
+
*
|
573
|
+
* Generic exception that is raised if an operation on a DSA PKey
|
574
|
+
* fails unexpectedly or in case an instantiation of an instance of DSA
|
575
|
+
* fails due to non-conformant input data.
|
576
|
+
*/
|
452
577
|
eDSAError = rb_define_class_under(mPKey, "DSAError", ePKeyError);
|
453
578
|
|
579
|
+
/* Document-class: OpenSSL::PKey::DSA
|
580
|
+
*
|
581
|
+
* DSA, the Digital Signature Algorithm, is specified in NIST's
|
582
|
+
* FIPS 186-3. It is an asymmetric public key algorithm that may be used
|
583
|
+
* similar to e.g. RSA.
|
584
|
+
* Please note that for OpenSSL versions prior to 1.0.0 the digest
|
585
|
+
* algorithms OpenSSL::Digest::DSS (equivalent to SHA) or
|
586
|
+
* OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing
|
587
|
+
* signatures with a DSA key using OpenSSL::PKey#sign.
|
588
|
+
* Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted,
|
589
|
+
* any Digest may be used for signing.
|
590
|
+
*/
|
454
591
|
cDSA = rb_define_class_under(mPKey, "DSA", cPKey);
|
455
|
-
|
592
|
+
|
456
593
|
rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1);
|
457
594
|
rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1);
|
458
595
|
|
@@ -22,70 +22,70 @@ typedef struct {
|
|
22
22
|
|
23
23
|
|
24
24
|
#define GetPKeyEC(obj, pkey) do { \
|
25
|
-
GetPKey(obj, pkey); \
|
26
|
-
if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) { \
|
25
|
+
GetPKey((obj), (pkey)); \
|
26
|
+
if (EVP_PKEY_type((pkey)->type) != EVP_PKEY_EC) { \
|
27
27
|
ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \
|
28
28
|
} \
|
29
29
|
} while (0)
|
30
30
|
|
31
31
|
#define SafeGet_ec_group(obj, group) do { \
|
32
|
-
OSSL_Check_Kind(obj, cEC_GROUP); \
|
33
|
-
Data_Get_Struct(obj, ossl_ec_group, group); \
|
32
|
+
OSSL_Check_Kind((obj), cEC_GROUP); \
|
33
|
+
Data_Get_Struct((obj), ossl_ec_group, (group)); \
|
34
34
|
} while(0)
|
35
35
|
|
36
36
|
#define Get_EC_KEY(obj, key) do { \
|
37
37
|
EVP_PKEY *pkey; \
|
38
|
-
GetPKeyEC(obj, pkey); \
|
39
|
-
key = pkey->pkey.ec; \
|
38
|
+
GetPKeyEC((obj), pkey); \
|
39
|
+
(key) = pkey->pkey.ec; \
|
40
40
|
} while(0)
|
41
41
|
|
42
42
|
#define Require_EC_KEY(obj, key) do { \
|
43
|
-
Get_EC_KEY(obj, key); \
|
44
|
-
if (key == NULL) \
|
45
|
-
|
43
|
+
Get_EC_KEY((obj), (key)); \
|
44
|
+
if ((key) == NULL) \
|
45
|
+
ossl_raise(eECError, "EC_KEY is not initialized"); \
|
46
46
|
} while(0)
|
47
47
|
|
48
48
|
#define SafeRequire_EC_KEY(obj, key) do { \
|
49
|
-
OSSL_Check_Kind(obj, cEC); \
|
50
|
-
Require_EC_KEY(obj, key); \
|
49
|
+
OSSL_Check_Kind((obj), cEC); \
|
50
|
+
Require_EC_KEY((obj), (key)); \
|
51
51
|
} while (0)
|
52
52
|
|
53
53
|
#define Get_EC_GROUP(obj, g) do { \
|
54
54
|
ossl_ec_group *ec_group; \
|
55
|
-
Data_Get_Struct(obj, ossl_ec_group, ec_group); \
|
55
|
+
Data_Get_Struct((obj), ossl_ec_group, ec_group); \
|
56
56
|
if (ec_group == NULL) \
|
57
|
-
|
58
|
-
g = ec_group->group; \
|
57
|
+
ossl_raise(eEC_GROUP, "missing ossl_ec_group structure"); \
|
58
|
+
(g) = ec_group->group; \
|
59
59
|
} while(0)
|
60
60
|
|
61
61
|
#define Require_EC_GROUP(obj, group) do { \
|
62
|
-
Get_EC_GROUP(obj, group); \
|
63
|
-
if (group == NULL) \
|
64
|
-
|
62
|
+
Get_EC_GROUP((obj), (group)); \
|
63
|
+
if ((group) == NULL) \
|
64
|
+
ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \
|
65
65
|
} while(0)
|
66
66
|
|
67
67
|
#define SafeRequire_EC_GROUP(obj, group) do { \
|
68
|
-
OSSL_Check_Kind(obj, cEC_GROUP); \
|
69
|
-
Require_EC_GROUP(obj, group); \
|
68
|
+
OSSL_Check_Kind((obj), cEC_GROUP); \
|
69
|
+
Require_EC_GROUP((obj), (group)); \
|
70
70
|
} while(0)
|
71
71
|
|
72
72
|
#define Get_EC_POINT(obj, p) do { \
|
73
73
|
ossl_ec_point *ec_point; \
|
74
|
-
Data_Get_Struct(obj, ossl_ec_point, ec_point); \
|
74
|
+
Data_Get_Struct((obj), ossl_ec_point, ec_point); \
|
75
75
|
if (ec_point == NULL) \
|
76
|
-
|
77
|
-
p = ec_point->point; \
|
76
|
+
ossl_raise(eEC_POINT, "missing ossl_ec_point structure"); \
|
77
|
+
(p) = ec_point->point; \
|
78
78
|
} while(0)
|
79
79
|
|
80
80
|
#define Require_EC_POINT(obj, point) do { \
|
81
|
-
Get_EC_POINT(obj, point); \
|
82
|
-
if (point == NULL) \
|
83
|
-
|
81
|
+
Get_EC_POINT((obj), (point)); \
|
82
|
+
if ((point) == NULL) \
|
83
|
+
ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \
|
84
84
|
} while(0)
|
85
85
|
|
86
86
|
#define SafeRequire_EC_POINT(obj, point) do { \
|
87
|
-
OSSL_Check_Kind(obj, cEC_POINT); \
|
88
|
-
Require_EC_POINT(obj, point); \
|
87
|
+
OSSL_Check_Kind((obj), cEC_POINT); \
|
88
|
+
Require_EC_POINT((obj), (point)); \
|
89
89
|
} while(0)
|
90
90
|
|
91
91
|
VALUE cEC;
|
@@ -110,7 +110,7 @@ static VALUE ec_instance(VALUE klass, EC_KEY *ec)
|
|
110
110
|
{
|
111
111
|
EVP_PKEY *pkey;
|
112
112
|
VALUE obj;
|
113
|
-
|
113
|
+
|
114
114
|
if (!ec) {
|
115
115
|
return Qfalse;
|
116
116
|
}
|
@@ -152,6 +152,7 @@ VALUE ossl_ec_new(EVP_PKEY *pkey)
|
|
152
152
|
* OpenSSL::PKey::EC.new(ec_group)
|
153
153
|
* OpenSSL::PKey::EC.new("secp112r1")
|
154
154
|
* OpenSSL::PKey::EC.new(pem_string)
|
155
|
+
* OpenSSL::PKey::EC.new(pem_string [, pwd])
|
155
156
|
* OpenSSL::PKey::EC.new(der_string)
|
156
157
|
*
|
157
158
|
* See the OpenSSL documentation for:
|
@@ -163,10 +164,11 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|
163
164
|
EC_KEY *ec = NULL;
|
164
165
|
VALUE arg, pass;
|
165
166
|
VALUE group = Qnil;
|
166
|
-
|
167
|
+
char *passwd = NULL;
|
168
|
+
|
167
169
|
GetPKey(self, pkey);
|
168
170
|
if (pkey->pkey.ec)
|
169
|
-
|
171
|
+
ossl_raise(eECError, "EC_KEY already initialized");
|
170
172
|
|
171
173
|
rb_scan_args(argc, argv, "02", &arg, &pass);
|
172
174
|
|
@@ -184,26 +186,30 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
|
|
184
186
|
} else {
|
185
187
|
BIO *in = ossl_obj2bio(arg);
|
186
188
|
|
187
|
-
|
189
|
+
if (!NIL_P(pass)) {
|
190
|
+
passwd = StringValuePtr(pass);
|
191
|
+
}
|
192
|
+
ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
|
188
193
|
if (!ec) {
|
189
|
-
|
190
|
-
|
194
|
+
OSSL_BIO_reset(in);
|
195
|
+
ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd);
|
191
196
|
}
|
192
197
|
if (!ec) {
|
193
|
-
|
198
|
+
OSSL_BIO_reset(in);
|
194
199
|
ec = d2i_ECPrivateKey_bio(in, NULL);
|
195
200
|
}
|
196
201
|
if (!ec) {
|
197
|
-
|
202
|
+
OSSL_BIO_reset(in);
|
198
203
|
ec = d2i_EC_PUBKEY_bio(in, NULL);
|
199
204
|
}
|
200
205
|
|
201
206
|
BIO_free(in);
|
202
207
|
|
203
208
|
if (ec == NULL) {
|
204
|
-
const char *name =
|
209
|
+
const char *name = StringValueCStr(arg);
|
205
210
|
int nid = OBJ_sn2nid(name);
|
206
211
|
|
212
|
+
(void)ERR_get_error();
|
207
213
|
if (nid == NID_undef)
|
208
214
|
ossl_raise(eECError, "unknown curve name (%s)\n", name);
|
209
215
|
|
@@ -274,7 +280,7 @@ static VALUE ossl_ec_key_get_group(VALUE self)
|
|
274
280
|
* the group.
|
275
281
|
*
|
276
282
|
* Setting the group will immediately destroy any previously assigned group object.
|
277
|
-
* The group is internally copied by OpenSSL. Modifying the original group after
|
283
|
+
* The group is internally copied by OpenSSL. Modifying the original group after
|
278
284
|
* assignment will not effect the internal key structure.
|
279
285
|
* (your changes may be lost). BE CAREFUL.
|
280
286
|
*
|
@@ -457,22 +463,19 @@ static VALUE ossl_ec_key_is_private_key(VALUE self)
|
|
457
463
|
return (EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse);
|
458
464
|
}
|
459
465
|
|
460
|
-
static VALUE ossl_ec_key_to_string(VALUE self, int format)
|
466
|
+
static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format)
|
461
467
|
{
|
462
468
|
EC_KEY *ec;
|
463
469
|
BIO *out;
|
464
470
|
int i = -1;
|
465
471
|
int private = 0;
|
466
|
-
#if 0 /* unused now */
|
467
|
-
EVP_CIPHER *cipher = NULL;
|
468
472
|
char *password = NULL;
|
469
|
-
#endif
|
470
473
|
VALUE str;
|
471
474
|
|
472
475
|
Require_EC_KEY(self, ec);
|
473
476
|
|
474
477
|
if (EC_KEY_get0_public_key(ec) == NULL)
|
475
|
-
|
478
|
+
ossl_raise(eECError, "can't export - no public key set");
|
476
479
|
|
477
480
|
if (EC_KEY_check_key(ec) != 1)
|
478
481
|
ossl_raise(eECError, "can't export - EC_KEY_check_key failed");
|
@@ -486,44 +489,36 @@ static VALUE ossl_ec_key_to_string(VALUE self, int format)
|
|
486
489
|
switch(format) {
|
487
490
|
case EXPORT_PEM:
|
488
491
|
if (private) {
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
492
|
+
const EVP_CIPHER *cipher;
|
493
|
+
if (!NIL_P(ciph)) {
|
494
|
+
cipher = GetCipherPtr(ciph);
|
495
|
+
if (!NIL_P(pass)) {
|
496
|
+
StringValue(pass);
|
497
|
+
if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
|
498
|
+
ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
|
499
|
+
password = RSTRING_PTR(pass);
|
500
|
+
}
|
501
|
+
}
|
502
|
+
else {
|
503
|
+
cipher = NULL;
|
504
|
+
}
|
493
505
|
i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, NULL, password);
|
494
|
-
#endif
|
495
|
-
i = PEM_write_bio_ECPrivateKey(out, ec, NULL, NULL, 0, NULL, NULL);
|
496
506
|
} else {
|
497
|
-
#if 0 /* unused now */
|
498
|
-
if (cipher || password)
|
499
|
-
rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
|
500
|
-
#endif
|
501
|
-
|
502
507
|
i = PEM_write_bio_EC_PUBKEY(out, ec);
|
503
508
|
}
|
504
509
|
|
505
510
|
break;
|
506
511
|
case EXPORT_DER:
|
507
512
|
if (private) {
|
508
|
-
#if 0 /* unused now */
|
509
|
-
if (cipher || password)
|
510
|
-
rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
|
511
|
-
#endif
|
512
|
-
|
513
513
|
i = i2d_ECPrivateKey_bio(out, ec);
|
514
514
|
} else {
|
515
|
-
#if 0 /* unused now */
|
516
|
-
if (cipher || password)
|
517
|
-
rb_raise(rb_eArgError, "encryption is not supported when exporting this key type");
|
518
|
-
#endif
|
519
|
-
|
520
515
|
i = i2d_EC_PUBKEY_bio(out, ec);
|
521
516
|
}
|
522
517
|
|
523
518
|
break;
|
524
519
|
default:
|
525
520
|
BIO_free(out);
|
526
|
-
|
521
|
+
ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
|
527
522
|
}
|
528
523
|
|
529
524
|
if (i != 1) {
|
@@ -538,13 +533,21 @@ static VALUE ossl_ec_key_to_string(VALUE self, int format)
|
|
538
533
|
|
539
534
|
/*
|
540
535
|
* call-seq:
|
541
|
-
* key.
|
536
|
+
* key.export => String
|
537
|
+
* key.export(cipher, pass_phrase) => String
|
538
|
+
*
|
539
|
+
* Outputs the EC key in PEM encoding. If +cipher+ and +pass_phrase+ are
|
540
|
+
* given they will be used to encrypt the key. +cipher+ must be an
|
541
|
+
* OpenSSL::Cipher::Cipher instance. Note that encryption will only be
|
542
|
+
* effective for a private key, public keys will always be encoded in plain
|
543
|
+
* text.
|
542
544
|
*
|
543
|
-
* See the OpenSSL documentation for PEM_write_bio_ECPrivateKey()
|
544
545
|
*/
|
545
|
-
static VALUE
|
546
|
+
static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self)
|
546
547
|
{
|
547
|
-
|
548
|
+
VALUE cipher, passwd;
|
549
|
+
rb_scan_args(argc, argv, "02", &cipher, &passwd);
|
550
|
+
return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM);
|
548
551
|
}
|
549
552
|
|
550
553
|
/*
|
@@ -555,7 +558,7 @@ static VALUE ossl_ec_key_to_pem(VALUE self)
|
|
555
558
|
*/
|
556
559
|
static VALUE ossl_ec_key_to_der(VALUE self)
|
557
560
|
{
|
558
|
-
return ossl_ec_key_to_string(self, EXPORT_DER);
|
561
|
+
return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER);
|
559
562
|
}
|
560
563
|
|
561
564
|
/*
|
@@ -671,7 +674,7 @@ static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
|
|
671
674
|
ossl_raise(eECError, "Private EC key needed!");
|
672
675
|
|
673
676
|
str = rb_str_new(0, ECDSA_size(ec) + 16);
|
674
|
-
if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data),
|
677
|
+
if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
|
675
678
|
ossl_raise(eECError, "ECDSA_sign");
|
676
679
|
|
677
680
|
rb_str_resize(str, buf_len);
|
@@ -693,13 +696,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
|
|
693
696
|
StringValue(data);
|
694
697
|
StringValue(sig);
|
695
698
|
|
696
|
-
switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data),
|
699
|
+
switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
|
697
700
|
case 1: return Qtrue;
|
698
701
|
case 0: return Qfalse;
|
699
702
|
default: break;
|
700
703
|
}
|
701
704
|
|
702
705
|
ossl_raise(eECError, "ECDSA_verify");
|
706
|
+
|
707
|
+
UNREACHABLE;
|
703
708
|
}
|
704
709
|
|
705
710
|
static void ossl_ec_group_free(ossl_ec_group *ec_group)
|
@@ -743,7 +748,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
743
748
|
|
744
749
|
Data_Get_Struct(self, ossl_ec_group, ec_group);
|
745
750
|
if (ec_group->group != NULL)
|
746
|
-
|
751
|
+
ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized");
|
747
752
|
|
748
753
|
switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
|
749
754
|
case 1:
|
@@ -765,7 +770,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
765
770
|
if ((group = EC_GROUP_new(method)) == NULL)
|
766
771
|
ossl_raise(eEC_GROUP, "EC_GROUP_new");
|
767
772
|
} else {
|
768
|
-
|
773
|
+
ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple");
|
769
774
|
}
|
770
775
|
} else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
|
771
776
|
const EC_GROUP *arg1_group;
|
@@ -778,16 +783,17 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
778
783
|
|
779
784
|
group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
|
780
785
|
if (!group) {
|
781
|
-
|
786
|
+
OSSL_BIO_reset(in);
|
782
787
|
group = d2i_ECPKParameters_bio(in, NULL);
|
783
788
|
}
|
784
789
|
|
785
790
|
BIO_free(in);
|
786
791
|
|
787
792
|
if (!group) {
|
788
|
-
const char *name =
|
793
|
+
const char *name = StringValueCStr(arg1);
|
789
794
|
int nid = OBJ_sn2nid(name);
|
790
795
|
|
796
|
+
(void)ERR_get_error();
|
791
797
|
if (nid == NID_undef)
|
792
798
|
ossl_raise(eEC_GROUP, "unknown curve name (%s)", name);
|
793
799
|
|
@@ -814,18 +820,18 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
|
|
814
820
|
} else if (id == s_GF2m) {
|
815
821
|
new_curve = EC_GROUP_new_curve_GF2m;
|
816
822
|
} else {
|
817
|
-
|
823
|
+
ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
|
818
824
|
}
|
819
825
|
|
820
826
|
if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
|
821
827
|
ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
|
822
828
|
} else {
|
823
|
-
|
829
|
+
ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
|
824
830
|
}
|
825
831
|
|
826
832
|
break;
|
827
833
|
default:
|
828
|
-
|
834
|
+
ossl_raise(rb_eArgError, "wrong number of arguments");
|
829
835
|
}
|
830
836
|
|
831
837
|
if (group == NULL)
|
@@ -965,7 +971,7 @@ static VALUE ossl_s_builtin_curves(VALUE self)
|
|
965
971
|
{
|
966
972
|
EC_builtin_curve *curves = NULL;
|
967
973
|
int n;
|
968
|
-
int crv_len = EC_get_builtin_curves(NULL, 0);
|
974
|
+
int crv_len = rb_long2int(EC_get_builtin_curves(NULL, 0));
|
969
975
|
VALUE ary, ret;
|
970
976
|
|
971
977
|
curves = ALLOCA_N(EC_builtin_curve, crv_len);
|
@@ -1023,7 +1029,7 @@ static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
|
|
1023
1029
|
}
|
1024
1030
|
|
1025
1031
|
/* call-seq:
|
1026
|
-
* group.point_conversion_form => :uncompressed | :compressed | :hybrid
|
1032
|
+
* group.point_conversion_form => :uncompressed | :compressed | :hybrid
|
1027
1033
|
*
|
1028
1034
|
* See the OpenSSL documentation for EC_GROUP_get_point_conversion_form()
|
1029
1035
|
*/
|
@@ -1041,9 +1047,9 @@ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
|
|
1041
1047
|
case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break;
|
1042
1048
|
case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break;
|
1043
1049
|
case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break;
|
1044
|
-
default:
|
1050
|
+
default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
|
1045
1051
|
}
|
1046
|
-
|
1052
|
+
|
1047
1053
|
return ID2SYM(ret);
|
1048
1054
|
}
|
1049
1055
|
|
@@ -1067,7 +1073,7 @@ static VALUE ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
|
|
1067
1073
|
} else if (form_id == ID_hybrid) {
|
1068
1074
|
form = POINT_CONVERSION_HYBRID;
|
1069
1075
|
} else {
|
1070
|
-
|
1076
|
+
ossl_raise(rb_eArgError, "form must be :compressed, :uncompressed, or :hybrid");
|
1071
1077
|
}
|
1072
1078
|
|
1073
1079
|
EC_GROUP_set_point_conversion_form(group, form);
|
@@ -1092,7 +1098,7 @@ static VALUE ossl_ec_group_get_seed(VALUE self)
|
|
1092
1098
|
if (seed_len == 0)
|
1093
1099
|
return Qnil;
|
1094
1100
|
|
1095
|
-
return rb_str_new(EC_GROUP_get0_seed(group), seed_len);
|
1101
|
+
return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
|
1096
1102
|
}
|
1097
1103
|
|
1098
1104
|
/* call-seq:
|
@@ -1107,7 +1113,7 @@ static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
|
|
1107
1113
|
Require_EC_GROUP(self, group);
|
1108
1114
|
StringValue(seed);
|
1109
1115
|
|
1110
|
-
if (EC_GROUP_set_seed(group, RSTRING_PTR(seed), RSTRING_LEN(seed)) != RSTRING_LEN(seed))
|
1116
|
+
if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
|
1111
1117
|
ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");
|
1112
1118
|
|
1113
1119
|
return seed;
|
@@ -1150,7 +1156,7 @@ static VALUE ossl_ec_group_to_string(VALUE self, int format)
|
|
1150
1156
|
break;
|
1151
1157
|
default:
|
1152
1158
|
BIO_free(out);
|
1153
|
-
|
1159
|
+
ossl_raise(rb_eRuntimeError, "unknown format (internal error)");
|
1154
1160
|
}
|
1155
1161
|
|
1156
1162
|
if (i != 1) {
|
@@ -1243,7 +1249,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
|
|
1243
1249
|
|
1244
1250
|
Data_Get_Struct(self, ossl_ec_point, ec_point);
|
1245
1251
|
if (ec_point->point)
|
1246
|
-
|
1252
|
+
ossl_raise(eEC_POINT, "EC_POINT already initialized");
|
1247
1253
|
|
1248
1254
|
switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
|
1249
1255
|
case 1:
|
@@ -1261,16 +1267,16 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
|
|
1261
1267
|
|
1262
1268
|
point = EC_POINT_new(group);
|
1263
1269
|
} else {
|
1264
|
-
|
1270
|
+
ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
|
1265
1271
|
}
|
1266
1272
|
|
1267
1273
|
break;
|
1268
1274
|
case 2:
|
1269
1275
|
if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
|
1270
|
-
|
1276
|
+
ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
|
1271
1277
|
group_v = arg1;
|
1272
1278
|
SafeRequire_EC_GROUP(group_v, group);
|
1273
|
-
|
1279
|
+
|
1274
1280
|
if (rb_obj_is_kind_of(arg2, cBN)) {
|
1275
1281
|
const BIGNUM *bn = GetBNPtr(arg2);
|
1276
1282
|
|
@@ -1288,14 +1294,14 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
|
|
1288
1294
|
}
|
1289
1295
|
break;
|
1290
1296
|
default:
|
1291
|
-
|
1297
|
+
ossl_raise(rb_eArgError, "wrong number of arguments");
|
1292
1298
|
}
|
1293
1299
|
|
1294
1300
|
if (point == NULL)
|
1295
1301
|
ossl_raise(eEC_POINT, NULL);
|
1296
1302
|
|
1297
1303
|
if (NIL_P(group_v))
|
1298
|
-
|
1304
|
+
ossl_raise(rb_eRuntimeError, "missing group (internal error)");
|
1299
1305
|
|
1300
1306
|
ec_point->point = point;
|
1301
1307
|
|
@@ -1348,6 +1354,8 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self)
|
|
1348
1354
|
case 0: return Qfalse;
|
1349
1355
|
default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity");
|
1350
1356
|
}
|
1357
|
+
|
1358
|
+
UNREACHABLE;
|
1351
1359
|
}
|
1352
1360
|
|
1353
1361
|
/*
|
@@ -1369,6 +1377,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self)
|
|
1369
1377
|
case 0: return Qfalse;
|
1370
1378
|
default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve");
|
1371
1379
|
}
|
1380
|
+
|
1381
|
+
UNREACHABLE;
|
1372
1382
|
}
|
1373
1383
|
|
1374
1384
|
/*
|
@@ -1460,6 +1470,78 @@ static VALUE ossl_ec_point_to_bn(VALUE self)
|
|
1460
1470
|
return bn_obj;
|
1461
1471
|
}
|
1462
1472
|
|
1473
|
+
/*
|
1474
|
+
* call-seq:
|
1475
|
+
* point.mul(bn) => point
|
1476
|
+
* point.mul(bn, bn) => point
|
1477
|
+
* point.mul([bn], [point]) => point
|
1478
|
+
* point.mul([bn], [point], bn) => point
|
1479
|
+
*/
|
1480
|
+
static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
|
1481
|
+
{
|
1482
|
+
EC_POINT *point1, *point2;
|
1483
|
+
const EC_GROUP *group;
|
1484
|
+
VALUE group_v = rb_iv_get(self, "@group");
|
1485
|
+
VALUE bn_v1, bn_v2, r, points_v;
|
1486
|
+
BIGNUM *bn1 = NULL, *bn2 = NULL;
|
1487
|
+
|
1488
|
+
Require_EC_POINT(self, point1);
|
1489
|
+
SafeRequire_EC_GROUP(group_v, group);
|
1490
|
+
|
1491
|
+
r = rb_obj_alloc(cEC_POINT);
|
1492
|
+
ossl_ec_point_initialize(1, &group_v, r);
|
1493
|
+
Require_EC_POINT(r, point2);
|
1494
|
+
|
1495
|
+
argc = rb_scan_args(argc, argv, "12", &bn_v1, &points_v, &bn_v2);
|
1496
|
+
|
1497
|
+
if (rb_obj_is_kind_of(bn_v1, cBN)) {
|
1498
|
+
bn1 = GetBNPtr(bn_v1);
|
1499
|
+
if (argc >= 2) {
|
1500
|
+
bn2 = GetBNPtr(points_v);
|
1501
|
+
}
|
1502
|
+
if (EC_POINT_mul(group, point2, bn2, point1, bn1, ossl_bn_ctx) != 1)
|
1503
|
+
ossl_raise(eEC_POINT, "Multiplication failed");
|
1504
|
+
} else {
|
1505
|
+
size_t i, points_len, bignums_len;
|
1506
|
+
const EC_POINT **points;
|
1507
|
+
const BIGNUM **bignums;
|
1508
|
+
|
1509
|
+
Check_Type(bn_v1, T_ARRAY);
|
1510
|
+
bignums_len = RARRAY_LEN(bn_v1);
|
1511
|
+
bignums = (const BIGNUM **)OPENSSL_malloc(bignums_len * (int)sizeof(BIGNUM *));
|
1512
|
+
|
1513
|
+
for (i = 0; i < bignums_len; ++i) {
|
1514
|
+
bignums[i] = GetBNPtr(rb_ary_entry(bn_v1, i));
|
1515
|
+
}
|
1516
|
+
|
1517
|
+
if (!rb_obj_is_kind_of(points_v, rb_cArray)) {
|
1518
|
+
OPENSSL_free((void *)bignums);
|
1519
|
+
rb_raise(rb_eTypeError, "Argument2 must be an array");
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
rb_ary_unshift(points_v, self);
|
1523
|
+
points_len = RARRAY_LEN(points_v);
|
1524
|
+
points = (const EC_POINT **)OPENSSL_malloc(points_len * (int)sizeof(EC_POINT *));
|
1525
|
+
|
1526
|
+
for (i = 0; i < points_len; ++i) {
|
1527
|
+
Get_EC_POINT(rb_ary_entry(points_v, i), points[i]);
|
1528
|
+
}
|
1529
|
+
|
1530
|
+
if (argc >= 3) {
|
1531
|
+
bn2 = GetBNPtr(bn_v2);
|
1532
|
+
}
|
1533
|
+
if (EC_POINTs_mul(group, point2, bn2, points_len, points, bignums, ossl_bn_ctx) != 1) {
|
1534
|
+
OPENSSL_free((void *)bignums);
|
1535
|
+
OPENSSL_free((void *)points);
|
1536
|
+
ossl_raise(eEC_POINT, "Multiplication failed");
|
1537
|
+
}
|
1538
|
+
OPENSSL_free((void *)bignums);
|
1539
|
+
OPENSSL_free((void *)points);
|
1540
|
+
}
|
1541
|
+
|
1542
|
+
return r;
|
1543
|
+
}
|
1544
|
+
|
1463
1545
|
static void no_copy(VALUE klass)
|
1464
1546
|
{
|
1465
1547
|
rb_undef_method(klass, "copy");
|
@@ -1526,7 +1608,8 @@ void Init_ossl_ec()
|
|
1526
1608
|
rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
|
1527
1609
|
/* do_sign/do_verify */
|
1528
1610
|
|
1529
|
-
rb_define_method(cEC, "
|
1611
|
+
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
|
1612
|
+
rb_define_alias(cEC, "to_pem", "export");
|
1530
1613
|
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);
|
1531
1614
|
rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0);
|
1532
1615
|
|
@@ -1580,6 +1663,7 @@ void Init_ossl_ec()
|
|
1580
1663
|
/* all the other methods */
|
1581
1664
|
|
1582
1665
|
rb_define_method(cEC_POINT, "to_bn", ossl_ec_point_to_bn, 0);
|
1666
|
+
rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1);
|
1583
1667
|
|
1584
1668
|
no_copy(cEC);
|
1585
1669
|
no_copy(cEC_GROUP);
|