openssl 2.0.0.beta.2 → 2.0.0
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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/History.md +4 -1
- data/README.md +4 -8
- data/ext/openssl/extconf.rb +0 -6
- data/ext/openssl/ossl.c +27 -88
- data/ext/openssl/ossl.h +3 -39
- data/ext/openssl/ossl_asn1.c +69 -129
- data/ext/openssl/ossl_bio.c +0 -3
- data/ext/openssl/ossl_bn.c +9 -8
- data/ext/openssl/ossl_cipher.c +39 -40
- data/ext/openssl/ossl_digest.c +22 -15
- data/ext/openssl/ossl_engine.c +1 -18
- data/ext/openssl/ossl_ns_spki.c +1 -6
- data/ext/openssl/ossl_pkcs7.c +1 -1
- data/ext/openssl/ossl_pkey.c +75 -32
- data/ext/openssl/ossl_pkey.h +0 -1
- data/ext/openssl/ossl_pkey_dh.c +1 -1
- data/ext/openssl/ossl_pkey_dsa.c +2 -4
- data/ext/openssl/ossl_pkey_ec.c +39 -25
- data/ext/openssl/ossl_pkey_rsa.c +5 -7
- data/ext/openssl/ossl_ssl.c +105 -79
- data/ext/openssl/ossl_ssl_session.c +19 -36
- data/ext/openssl/ossl_x509.h +6 -3
- data/ext/openssl/ossl_x509cert.c +1 -1
- data/ext/openssl/ossl_x509crl.c +5 -24
- data/ext/openssl/ossl_x509name.c +3 -5
- data/ext/openssl/ossl_x509req.c +4 -18
- data/ext/openssl/ossl_x509store.c +83 -25
- data/ext/openssl/ruby_missing.h +0 -9
- data/lib/openssl/buffering.rb +9 -1
- data/lib/openssl/ssl.rb +8 -12
- metadata +17 -17
data/ext/openssl/ossl_bio.c
CHANGED
data/ext/openssl/ossl_bn.c
CHANGED
@@ -380,7 +380,7 @@ BIGNUM_BOOL1(is_odd)
|
|
380
380
|
BIGNUM *bn, *result; \
|
381
381
|
VALUE obj; \
|
382
382
|
GetBN(self, bn); \
|
383
|
-
obj = NewBN(
|
383
|
+
obj = NewBN(rb_obj_class(self)); \
|
384
384
|
if (!(result = BN_new())) { \
|
385
385
|
ossl_raise(eBNError, NULL); \
|
386
386
|
} \
|
@@ -406,7 +406,7 @@ BIGNUM_1c(sqr)
|
|
406
406
|
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
|
407
407
|
VALUE obj; \
|
408
408
|
GetBN(self, bn1); \
|
409
|
-
obj = NewBN(
|
409
|
+
obj = NewBN(rb_obj_class(self)); \
|
410
410
|
if (!(result = BN_new())) { \
|
411
411
|
ossl_raise(eBNError, NULL); \
|
412
412
|
} \
|
@@ -439,7 +439,7 @@ BIGNUM_2(sub)
|
|
439
439
|
BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \
|
440
440
|
VALUE obj; \
|
441
441
|
GetBN(self, bn1); \
|
442
|
-
obj = NewBN(
|
442
|
+
obj = NewBN(rb_obj_class(self)); \
|
443
443
|
if (!(result = BN_new())) { \
|
444
444
|
ossl_raise(eBNError, NULL); \
|
445
445
|
} \
|
@@ -504,12 +504,13 @@ static VALUE
|
|
504
504
|
ossl_bn_div(VALUE self, VALUE other)
|
505
505
|
{
|
506
506
|
BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
|
507
|
-
VALUE obj1, obj2;
|
507
|
+
VALUE klass, obj1, obj2;
|
508
508
|
|
509
509
|
GetBN(self, bn1);
|
510
510
|
|
511
|
-
|
512
|
-
|
511
|
+
klass = rb_obj_class(self);
|
512
|
+
obj1 = NewBN(klass);
|
513
|
+
obj2 = NewBN(klass);
|
513
514
|
if (!(r1 = BN_new())) {
|
514
515
|
ossl_raise(eBNError, NULL);
|
515
516
|
}
|
@@ -536,7 +537,7 @@ ossl_bn_div(VALUE self, VALUE other)
|
|
536
537
|
BIGNUM *bn3 = GetBNPtr(other2), *result; \
|
537
538
|
VALUE obj; \
|
538
539
|
GetBN(self, bn1); \
|
539
|
-
obj = NewBN(
|
540
|
+
obj = NewBN(rb_obj_class(self)); \
|
540
541
|
if (!(result = BN_new())) { \
|
541
542
|
ossl_raise(eBNError, NULL); \
|
542
543
|
} \
|
@@ -639,7 +640,7 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit)
|
|
639
640
|
VALUE obj; \
|
640
641
|
b = NUM2INT(bits); \
|
641
642
|
GetBN(self, bn); \
|
642
|
-
obj = NewBN(
|
643
|
+
obj = NewBN(rb_obj_class(self)); \
|
643
644
|
if (!(result = BN_new())) { \
|
644
645
|
ossl_raise(eBNError, NULL); \
|
645
646
|
} \
|
data/ext/openssl/ossl_cipher.c
CHANGED
@@ -36,7 +36,7 @@
|
|
36
36
|
*/
|
37
37
|
VALUE cCipher;
|
38
38
|
VALUE eCipherError;
|
39
|
-
static ID id_auth_tag_len;
|
39
|
+
static ID id_auth_tag_len, id_key_set;
|
40
40
|
|
41
41
|
static VALUE ossl_cipher_alloc(VALUE klass);
|
42
42
|
static void ossl_cipher_free(void *ptr);
|
@@ -118,7 +118,6 @@ ossl_cipher_initialize(VALUE self, VALUE str)
|
|
118
118
|
EVP_CIPHER_CTX *ctx;
|
119
119
|
const EVP_CIPHER *cipher;
|
120
120
|
char *name;
|
121
|
-
unsigned char dummy_key[EVP_MAX_KEY_LENGTH] = { 0 };
|
122
121
|
|
123
122
|
name = StringValueCStr(str);
|
124
123
|
GetCipherInit(self, ctx);
|
@@ -129,16 +128,7 @@ ossl_cipher_initialize(VALUE self, VALUE str)
|
|
129
128
|
if (!(cipher = EVP_get_cipherbyname(name))) {
|
130
129
|
ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str);
|
131
130
|
}
|
132
|
-
|
133
|
-
* EVP_CipherInit_ex() allows to specify NULL to key and IV, however some
|
134
|
-
* ciphers don't handle well (OpenSSL's bug). [Bug #2768]
|
135
|
-
*
|
136
|
-
* The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows
|
137
|
-
* uninitialized key, but other EVPs (such as AES) does not allow it.
|
138
|
-
* Calling EVP_CipherUpdate() without initializing key causes SEGV so we
|
139
|
-
* set the data filled with "\0" as the key by default.
|
140
|
-
*/
|
141
|
-
if (EVP_CipherInit_ex(ctx, cipher, NULL, dummy_key, NULL, -1) != 1)
|
131
|
+
if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
|
142
132
|
ossl_raise(eCipherError, NULL);
|
143
133
|
|
144
134
|
return self;
|
@@ -251,6 +241,9 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
|
|
251
241
|
ossl_raise(eCipherError, NULL);
|
252
242
|
}
|
253
243
|
|
244
|
+
if (p_key)
|
245
|
+
rb_ivar_set(self, id_key_set, Qtrue);
|
246
|
+
|
254
247
|
return self;
|
255
248
|
}
|
256
249
|
|
@@ -304,7 +297,7 @@ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
|
|
304
297
|
*
|
305
298
|
* === Parameters
|
306
299
|
* * +salt+ must be an 8 byte string if provided.
|
307
|
-
* * +iterations+ is
|
300
|
+
* * +iterations+ is an integer with a default of 2048.
|
308
301
|
* * +digest+ is a Digest object that defaults to 'MD5'
|
309
302
|
*
|
310
303
|
* A minimum of 1000 iterations is recommended.
|
@@ -337,6 +330,8 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
|
|
337
330
|
OPENSSL_cleanse(key, sizeof key);
|
338
331
|
OPENSSL_cleanse(iv, sizeof iv);
|
339
332
|
|
333
|
+
rb_ivar_set(self, id_key_set, Qtrue);
|
334
|
+
|
340
335
|
return Qnil;
|
341
336
|
}
|
342
337
|
|
@@ -387,6 +382,9 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
|
|
387
382
|
|
388
383
|
rb_scan_args(argc, argv, "11", &data, &str);
|
389
384
|
|
385
|
+
if (!RTEST(rb_attr_get(self, id_key_set)))
|
386
|
+
ossl_raise(eCipherError, "key not set");
|
387
|
+
|
390
388
|
StringValue(data);
|
391
389
|
in = (unsigned char *)RSTRING_PTR(data);
|
392
390
|
if ((in_len = RSTRING_LEN(data)) == 0)
|
@@ -488,6 +486,8 @@ ossl_cipher_set_key(VALUE self, VALUE key)
|
|
488
486
|
if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
|
489
487
|
ossl_raise(eCipherError, NULL);
|
490
488
|
|
489
|
+
rb_ivar_set(self, id_key_set, Qtrue);
|
490
|
+
|
491
491
|
return key;
|
492
492
|
}
|
493
493
|
|
@@ -502,9 +502,6 @@ ossl_cipher_set_key(VALUE self, VALUE key)
|
|
502
502
|
* Cipher#random_iv to create a secure random IV.
|
503
503
|
*
|
504
504
|
* Only call this method after calling Cipher#encrypt or Cipher#decrypt.
|
505
|
-
*
|
506
|
-
* If not explicitly set, the OpenSSL default of an all-zeroes ("\\0") IV is
|
507
|
-
* used.
|
508
505
|
*/
|
509
506
|
static VALUE
|
510
507
|
ossl_cipher_set_iv(VALUE self, VALUE iv)
|
@@ -530,6 +527,27 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
|
|
530
527
|
return iv;
|
531
528
|
}
|
532
529
|
|
530
|
+
/*
|
531
|
+
* call-seq:
|
532
|
+
* cipher.authenticated? -> true | false
|
533
|
+
*
|
534
|
+
* Indicated whether this Cipher instance uses an Authenticated Encryption
|
535
|
+
* mode.
|
536
|
+
*/
|
537
|
+
static VALUE
|
538
|
+
ossl_cipher_is_authenticated(VALUE self)
|
539
|
+
{
|
540
|
+
EVP_CIPHER_CTX *ctx;
|
541
|
+
|
542
|
+
GetCipher(self, ctx);
|
543
|
+
|
544
|
+
#if defined(HAVE_AUTHENTICATED_ENCRYPTION)
|
545
|
+
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
|
546
|
+
#else
|
547
|
+
return Qfalse;
|
548
|
+
#endif
|
549
|
+
}
|
550
|
+
|
533
551
|
#ifdef HAVE_AUTHENTICATED_ENCRYPTION
|
534
552
|
/*
|
535
553
|
* call-seq:
|
@@ -675,23 +693,6 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen)
|
|
675
693
|
return vlen;
|
676
694
|
}
|
677
695
|
|
678
|
-
/*
|
679
|
-
* call-seq:
|
680
|
-
* cipher.authenticated? -> boolean
|
681
|
-
*
|
682
|
-
* Indicated whether this Cipher instance uses an Authenticated Encryption
|
683
|
-
* mode.
|
684
|
-
*/
|
685
|
-
static VALUE
|
686
|
-
ossl_cipher_is_authenticated(VALUE self)
|
687
|
-
{
|
688
|
-
EVP_CIPHER_CTX *ctx;
|
689
|
-
|
690
|
-
GetCipher(self, ctx);
|
691
|
-
|
692
|
-
return (EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER) ? Qtrue : Qfalse;
|
693
|
-
}
|
694
|
-
|
695
696
|
/*
|
696
697
|
* call-seq:
|
697
698
|
* cipher.iv_len = integer -> integer
|
@@ -726,7 +727,6 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length)
|
|
726
727
|
#define ossl_cipher_get_auth_tag rb_f_notimplement
|
727
728
|
#define ossl_cipher_set_auth_tag rb_f_notimplement
|
728
729
|
#define ossl_cipher_set_auth_tag_len rb_f_notimplement
|
729
|
-
#define ossl_cipher_is_authenticated rb_f_notimplement
|
730
730
|
#define ossl_cipher_set_iv_length rb_f_notimplement
|
731
731
|
#endif
|
732
732
|
|
@@ -939,12 +939,10 @@ Init_ossl_cipher(void)
|
|
939
939
|
* you absolutely need it</b>
|
940
940
|
*
|
941
941
|
* Because of this, you will end up with a mode that explicitly requires
|
942
|
-
* an IV in any case.
|
943
|
-
*
|
944
|
-
*
|
945
|
-
*
|
946
|
-
* it may be transmitted in public once generated, it should still stay
|
947
|
-
* unpredictable to prevent certain kinds of attacks. Therefore, ideally
|
942
|
+
* an IV in any case. Although the IV can be seen as public information,
|
943
|
+
* i.e. it may be transmitted in public once generated, it should still
|
944
|
+
* stay unpredictable to prevent certain kinds of attacks. Therefore,
|
945
|
+
* ideally
|
948
946
|
*
|
949
947
|
* <b>Always create a secure random IV for every encryption of your
|
950
948
|
* Cipher</b>
|
@@ -1082,4 +1080,5 @@ Init_ossl_cipher(void)
|
|
1082
1080
|
rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
|
1083
1081
|
|
1084
1082
|
id_auth_tag_len = rb_intern_const("auth_tag_len");
|
1083
|
+
id_key_set = rb_intern_const("key_set");
|
1085
1084
|
}
|
data/ext/openssl/ossl_digest.c
CHANGED
@@ -80,10 +80,13 @@ ossl_digest_new(const EVP_MD *md)
|
|
80
80
|
EVP_MD_CTX *ctx;
|
81
81
|
|
82
82
|
ret = ossl_digest_alloc(cDigest);
|
83
|
-
|
84
|
-
if (
|
85
|
-
ossl_raise(eDigestError, "
|
86
|
-
|
83
|
+
ctx = EVP_MD_CTX_new();
|
84
|
+
if (!ctx)
|
85
|
+
ossl_raise(eDigestError, "EVP_MD_CTX_new");
|
86
|
+
RTYPEDDATA_DATA(ret) = ctx;
|
87
|
+
|
88
|
+
if (!EVP_DigestInit_ex(ctx, md, NULL))
|
89
|
+
ossl_raise(eDigestError, "Digest initialization failed");
|
87
90
|
|
88
91
|
return ret;
|
89
92
|
}
|
@@ -94,13 +97,7 @@ ossl_digest_new(const EVP_MD *md)
|
|
94
97
|
static VALUE
|
95
98
|
ossl_digest_alloc(VALUE klass)
|
96
99
|
{
|
97
|
-
|
98
|
-
EVP_MD_CTX *ctx = EVP_MD_CTX_create();
|
99
|
-
if (ctx == NULL)
|
100
|
-
ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed");
|
101
|
-
RTYPEDDATA_DATA(obj) = ctx;
|
102
|
-
|
103
|
-
return obj;
|
100
|
+
return TypedData_Wrap_Struct(klass, &ossl_digest_type, 0);
|
104
101
|
}
|
105
102
|
|
106
103
|
VALUE ossl_digest_update(VALUE, VALUE);
|
@@ -133,11 +130,16 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self)
|
|
133
130
|
md = GetDigestPtr(type);
|
134
131
|
if (!NIL_P(data)) StringValue(data);
|
135
132
|
|
136
|
-
|
137
|
-
if (
|
138
|
-
|
133
|
+
TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx);
|
134
|
+
if (!ctx) {
|
135
|
+
RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new();
|
136
|
+
if (!ctx)
|
137
|
+
ossl_raise(eDigestError, "EVP_MD_CTX_new");
|
139
138
|
}
|
140
139
|
|
140
|
+
if (!EVP_DigestInit_ex(ctx, md, NULL))
|
141
|
+
ossl_raise(eDigestError, "Digest initialization failed");
|
142
|
+
|
141
143
|
if (!NIL_P(data)) return ossl_digest_update(self, data);
|
142
144
|
return self;
|
143
145
|
}
|
@@ -150,7 +152,12 @@ ossl_digest_copy(VALUE self, VALUE other)
|
|
150
152
|
rb_check_frozen(self);
|
151
153
|
if (self == other) return self;
|
152
154
|
|
153
|
-
|
155
|
+
TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1);
|
156
|
+
if (!ctx1) {
|
157
|
+
RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new();
|
158
|
+
if (!ctx1)
|
159
|
+
ossl_raise(eDigestError, "EVP_MD_CTX_new");
|
160
|
+
}
|
154
161
|
SafeGetDigest(other, ctx2);
|
155
162
|
|
156
163
|
if (!EVP_MD_CTX_copy(ctx1, ctx2)) {
|
data/ext/openssl/ossl_engine.c
CHANGED
@@ -227,21 +227,6 @@ ossl_engine_s_by_id(VALUE klass, VALUE id)
|
|
227
227
|
return obj;
|
228
228
|
}
|
229
229
|
|
230
|
-
static VALUE
|
231
|
-
ossl_engine_s_alloc(VALUE klass)
|
232
|
-
{
|
233
|
-
ENGINE *e;
|
234
|
-
VALUE obj;
|
235
|
-
|
236
|
-
obj = NewEngine(klass);
|
237
|
-
if (!(e = ENGINE_new())) {
|
238
|
-
ossl_raise(eEngineError, NULL);
|
239
|
-
}
|
240
|
-
SetEngine(obj, e);
|
241
|
-
|
242
|
-
return obj;
|
243
|
-
}
|
244
|
-
|
245
230
|
/* Document-method: OpenSSL::Engine#id
|
246
231
|
*
|
247
232
|
* Get the id for this engine
|
@@ -537,13 +522,11 @@ Init_ossl_engine(void)
|
|
537
522
|
cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject);
|
538
523
|
eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError);
|
539
524
|
|
540
|
-
|
525
|
+
rb_undef_alloc_func(cEngine);
|
541
526
|
rb_define_singleton_method(cEngine, "load", ossl_engine_s_load, -1);
|
542
527
|
rb_define_singleton_method(cEngine, "cleanup", ossl_engine_s_cleanup, 0);
|
543
528
|
rb_define_singleton_method(cEngine, "engines", ossl_engine_s_engines, 0);
|
544
529
|
rb_define_singleton_method(cEngine, "by_id", ossl_engine_s_by_id, 1);
|
545
|
-
rb_undef_method(CLASS_OF(cEngine), "new");
|
546
|
-
rb_undef_method(cEngine, "initialize_copy");
|
547
530
|
|
548
531
|
rb_define_method(cEngine, "id", ossl_engine_get_id, 0);
|
549
532
|
rb_define_method(cEngine, "name", ossl_engine_get_name, 0);
|
data/ext/openssl/ossl_ns_spki.c
CHANGED
@@ -159,8 +159,6 @@ ossl_spki_print(VALUE self)
|
|
159
159
|
{
|
160
160
|
NETSCAPE_SPKI *spki;
|
161
161
|
BIO *out;
|
162
|
-
BUF_MEM *buf;
|
163
|
-
VALUE str;
|
164
162
|
|
165
163
|
GetSPKI(self, spki);
|
166
164
|
if (!(out = BIO_new(BIO_s_mem()))) {
|
@@ -170,11 +168,8 @@ ossl_spki_print(VALUE self)
|
|
170
168
|
BIO_free(out);
|
171
169
|
ossl_raise(eSPKIError, NULL);
|
172
170
|
}
|
173
|
-
BIO_get_mem_ptr(out, &buf);
|
174
|
-
str = rb_str_new(buf->data, buf->length);
|
175
|
-
BIO_free(out);
|
176
171
|
|
177
|
-
return
|
172
|
+
return ossl_membio2str(out);
|
178
173
|
}
|
179
174
|
|
180
175
|
/*
|
data/ext/openssl/ossl_pkcs7.c
CHANGED
@@ -795,7 +795,7 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
|
|
795
795
|
BIO_free(in);
|
796
796
|
sk_X509_pop_free(x509s, X509_free);
|
797
797
|
if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify");
|
798
|
-
msg = ERR_reason_error_string(
|
798
|
+
msg = ERR_reason_error_string(ERR_peek_error());
|
799
799
|
ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil);
|
800
800
|
ossl_clear_error();
|
801
801
|
data = ossl_membio2str(out);
|
data/ext/openssl/ossl_pkey.c
CHANGED
@@ -70,12 +70,12 @@ const rb_data_type_t ossl_evp_pkey_type = {
|
|
70
70
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
71
71
|
};
|
72
72
|
|
73
|
-
VALUE
|
74
|
-
|
73
|
+
static VALUE
|
74
|
+
pkey_new0(EVP_PKEY *pkey)
|
75
75
|
{
|
76
|
-
if (!pkey)
|
77
|
-
ossl_raise(ePKeyError, "
|
78
|
-
|
76
|
+
if (!pkey)
|
77
|
+
ossl_raise(ePKeyError, "cannot make new key from NULL");
|
78
|
+
|
79
79
|
switch (EVP_PKEY_base_id(pkey)) {
|
80
80
|
#if !defined(OPENSSL_NO_RSA)
|
81
81
|
case EVP_PKEY_RSA:
|
@@ -96,29 +96,21 @@ ossl_pkey_new(EVP_PKEY *pkey)
|
|
96
96
|
default:
|
97
97
|
ossl_raise(ePKeyError, "unsupported key type");
|
98
98
|
}
|
99
|
-
|
100
|
-
UNREACHABLE;
|
101
99
|
}
|
102
100
|
|
103
101
|
VALUE
|
104
|
-
|
102
|
+
ossl_pkey_new(EVP_PKEY *pkey)
|
105
103
|
{
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
rb_check_safe_obj(filename);
|
110
|
-
if (!(fp = fopen(StringValueCStr(filename), "r"))) {
|
111
|
-
ossl_raise(ePKeyError, "%s", strerror(errno));
|
112
|
-
}
|
113
|
-
rb_fd_fix_cloexec(fileno(fp));
|
104
|
+
VALUE obj;
|
105
|
+
int status;
|
114
106
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
107
|
+
obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status);
|
108
|
+
if (status) {
|
109
|
+
EVP_PKEY_free(pkey);
|
110
|
+
rb_jump_tag(status);
|
119
111
|
}
|
120
112
|
|
121
|
-
return
|
113
|
+
return obj;
|
122
114
|
}
|
123
115
|
|
124
116
|
/*
|
@@ -166,6 +158,45 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
|
|
166
158
|
return ossl_pkey_new(pkey);
|
167
159
|
}
|
168
160
|
|
161
|
+
static void
|
162
|
+
pkey_check_public_key(EVP_PKEY *pkey)
|
163
|
+
{
|
164
|
+
void *ptr;
|
165
|
+
const BIGNUM *n, *e, *pubkey;
|
166
|
+
|
167
|
+
if (EVP_PKEY_missing_parameters(pkey))
|
168
|
+
ossl_raise(ePKeyError, "parameters missing");
|
169
|
+
|
170
|
+
ptr = EVP_PKEY_get0(pkey);
|
171
|
+
switch (EVP_PKEY_base_id(pkey)) {
|
172
|
+
case EVP_PKEY_RSA:
|
173
|
+
RSA_get0_key(ptr, &n, &e, NULL);
|
174
|
+
if (n && e)
|
175
|
+
return;
|
176
|
+
break;
|
177
|
+
case EVP_PKEY_DSA:
|
178
|
+
DSA_get0_key(ptr, &pubkey, NULL);
|
179
|
+
if (pubkey)
|
180
|
+
return;
|
181
|
+
break;
|
182
|
+
case EVP_PKEY_DH:
|
183
|
+
DH_get0_key(ptr, &pubkey, NULL);
|
184
|
+
if (pubkey)
|
185
|
+
return;
|
186
|
+
break;
|
187
|
+
#if !defined(OPENSSL_NO_EC)
|
188
|
+
case EVP_PKEY_EC:
|
189
|
+
if (EC_KEY_get0_public_key(ptr))
|
190
|
+
return;
|
191
|
+
break;
|
192
|
+
#endif
|
193
|
+
default:
|
194
|
+
/* unsupported type; assuming ok */
|
195
|
+
return;
|
196
|
+
}
|
197
|
+
ossl_raise(ePKeyError, "public key missing");
|
198
|
+
}
|
199
|
+
|
169
200
|
EVP_PKEY *
|
170
201
|
GetPKeyPtr(VALUE obj)
|
171
202
|
{
|
@@ -264,18 +295,23 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
|
|
264
295
|
pkey = GetPrivPKeyPtr(self);
|
265
296
|
md = GetDigestPtr(digest);
|
266
297
|
StringValue(data);
|
267
|
-
str = rb_str_new(0, EVP_PKEY_size(pkey)
|
298
|
+
str = rb_str_new(0, EVP_PKEY_size(pkey));
|
268
299
|
|
269
300
|
ctx = EVP_MD_CTX_new();
|
270
301
|
if (!ctx)
|
271
302
|
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
|
272
|
-
|
273
|
-
|
303
|
+
if (!EVP_SignInit_ex(ctx, md, NULL)) {
|
304
|
+
EVP_MD_CTX_free(ctx);
|
305
|
+
ossl_raise(ePKeyError, "EVP_SignInit_ex");
|
306
|
+
}
|
307
|
+
if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
|
308
|
+
EVP_MD_CTX_free(ctx);
|
309
|
+
ossl_raise(ePKeyError, "EVP_SignUpdate");
|
310
|
+
}
|
274
311
|
result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey);
|
275
312
|
EVP_MD_CTX_free(ctx);
|
276
313
|
if (!result)
|
277
|
-
ossl_raise(ePKeyError,
|
278
|
-
assert((long)buf_len <= RSTRING_LEN(str));
|
314
|
+
ossl_raise(ePKeyError, "EVP_SignFinal");
|
279
315
|
rb_str_set_len(str, buf_len);
|
280
316
|
|
281
317
|
return str;
|
@@ -308,19 +344,27 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
|
|
308
344
|
EVP_PKEY *pkey;
|
309
345
|
const EVP_MD *md;
|
310
346
|
EVP_MD_CTX *ctx;
|
311
|
-
int result;
|
347
|
+
int siglen, result;
|
312
348
|
|
313
349
|
GetPKey(self, pkey);
|
350
|
+
pkey_check_public_key(pkey);
|
314
351
|
md = GetDigestPtr(digest);
|
315
352
|
StringValue(sig);
|
353
|
+
siglen = RSTRING_LENINT(sig);
|
316
354
|
StringValue(data);
|
317
355
|
|
318
356
|
ctx = EVP_MD_CTX_new();
|
319
357
|
if (!ctx)
|
320
358
|
ossl_raise(ePKeyError, "EVP_MD_CTX_new");
|
321
|
-
|
322
|
-
|
323
|
-
|
359
|
+
if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
|
360
|
+
EVP_MD_CTX_free(ctx);
|
361
|
+
ossl_raise(ePKeyError, "EVP_VerifyInit_ex");
|
362
|
+
}
|
363
|
+
if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) {
|
364
|
+
EVP_MD_CTX_free(ctx);
|
365
|
+
ossl_raise(ePKeyError, "EVP_VerifyUpdate");
|
366
|
+
}
|
367
|
+
result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey);
|
324
368
|
EVP_MD_CTX_free(ctx);
|
325
369
|
switch (result) {
|
326
370
|
case 0:
|
@@ -329,9 +373,8 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
|
|
329
373
|
case 1:
|
330
374
|
return Qtrue;
|
331
375
|
default:
|
332
|
-
ossl_raise(ePKeyError,
|
376
|
+
ossl_raise(ePKeyError, "EVP_VerifyFinal");
|
333
377
|
}
|
334
|
-
return Qnil; /* dummy */
|
335
378
|
}
|
336
379
|
|
337
380
|
/*
|