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.

@@ -8,9 +8,6 @@
8
8
  * (See the file 'LICENCE'.)
9
9
  */
10
10
  #include "ossl.h"
11
- #ifdef HAVE_UNISTD_H
12
- #include <unistd.h>
13
- #endif
14
11
 
15
12
  BIO *
16
13
  ossl_obj2bio(VALUE obj)
@@ -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(CLASS_OF(self)); \
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(CLASS_OF(self)); \
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(CLASS_OF(self)); \
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
- obj1 = NewBN(CLASS_OF(self));
512
- obj2 = NewBN(CLASS_OF(self));
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(CLASS_OF(self)); \
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(CLASS_OF(self)); \
643
+ obj = NewBN(rb_obj_class(self)); \
643
644
  if (!(result = BN_new())) { \
644
645
  ossl_raise(eBNError, NULL); \
645
646
  } \
@@ -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 a integer with a default of 2048.
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. Note that for backwards compatibility reasons,
943
- * setting an IV is not explicitly mandated by the Cipher API. If not
944
- * set, OpenSSL itself defaults to an all-zeroes IV ("\\0", not the
945
- * character). Although the IV can be seen as public information, i.e.
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
  }
@@ -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
- GetDigest(ret, ctx);
84
- if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
85
- ossl_raise(eDigestError, "Digest initialization failed.");
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
- VALUE obj = TypedData_Wrap_Struct(klass, &ossl_digest_type, 0);
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
- GetDigest(self, ctx);
137
- if (EVP_DigestInit_ex(ctx, md, NULL) != 1) {
138
- ossl_raise(eDigestError, "Digest initialization failed.");
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
- GetDigest(self, ctx1);
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)) {
@@ -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
- rb_define_alloc_func(cEngine, ossl_engine_s_alloc);
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);
@@ -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 str;
172
+ return ossl_membio2str(out);
178
173
  }
179
174
 
180
175
  /*
@@ -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(ERR_get_error());
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);
@@ -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
- ossl_pkey_new(EVP_PKEY *pkey)
73
+ static VALUE
74
+ pkey_new0(EVP_PKEY *pkey)
75
75
  {
76
- if (!pkey) {
77
- ossl_raise(ePKeyError, "Cannot make new key from NULL.");
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
- ossl_pkey_new_from_file(VALUE filename)
102
+ ossl_pkey_new(EVP_PKEY *pkey)
105
103
  {
106
- FILE *fp;
107
- EVP_PKEY *pkey;
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
- pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
116
- fclose(fp);
117
- if (!pkey) {
118
- ossl_raise(ePKeyError, NULL);
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 ossl_pkey_new(pkey);
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)+16);
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
- EVP_SignInit(ctx, md);
273
- EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
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, NULL);
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
- EVP_VerifyInit(ctx, md);
322
- EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data));
323
- result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
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, NULL);
376
+ ossl_raise(ePKeyError, "EVP_VerifyFinal");
333
377
  }
334
- return Qnil; /* dummy */
335
378
  }
336
379
 
337
380
  /*