Skip to content

Commit 2a433b0

Browse files
committed
pkey/dsa: refactor DSA#sys{sign,verify} with PKey#{sign,verify}_raw
With the newly added OpenSSL::PKey::PKey#{sign,verify}_raw, OpenSSL::PKey::DSA's low level signing operation methods can be implemented in Ruby. The definitions are now in lib/openssl/pkey.rb.
1 parent afffbc0 commit 2a433b0

File tree

2 files changed

+54
-88
lines changed

2 files changed

+54
-88
lines changed

ext/openssl/ossl_pkey_dsa.c

-88
Original file line numberDiff line numberDiff line change
@@ -422,92 +422,6 @@ ossl_dsa_to_public_key(VALUE self)
422422
return obj;
423423
}
424424

425-
/*
426-
* call-seq:
427-
* dsa.syssign(string) -> aString
428-
*
429-
* Computes and returns the DSA signature of _string_, where _string_ is
430-
* expected to be an already-computed message digest of the original input
431-
* data. The signature is issued using the private key of this DSA instance.
432-
*
433-
* === Parameters
434-
* * _string_ is a message digest of the original input data to be signed.
435-
*
436-
* === Example
437-
* dsa = OpenSSL::PKey::DSA.new(2048)
438-
* doc = "Sign me"
439-
* digest = OpenSSL::Digest.digest('SHA1', doc)
440-
* sig = dsa.syssign(digest)
441-
*
442-
*
443-
*/
444-
static VALUE
445-
ossl_dsa_sign(VALUE self, VALUE data)
446-
{
447-
DSA *dsa;
448-
const BIGNUM *dsa_q;
449-
unsigned int buf_len;
450-
VALUE str;
451-
452-
GetDSA(self, dsa);
453-
DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
454-
if (!dsa_q)
455-
ossl_raise(eDSAError, "incomplete DSA");
456-
if (!DSA_PRIVATE(self, dsa))
457-
ossl_raise(eDSAError, "Private DSA key needed!");
458-
StringValue(data);
459-
str = rb_str_new(0, DSA_size(dsa));
460-
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
461-
(unsigned char *)RSTRING_PTR(str),
462-
&buf_len, dsa)) { /* type is ignored (0) */
463-
ossl_raise(eDSAError, NULL);
464-
}
465-
rb_str_set_len(str, buf_len);
466-
467-
return str;
468-
}
469-
470-
/*
471-
* call-seq:
472-
* dsa.sysverify(digest, sig) -> true | false
473-
*
474-
* Verifies whether the signature is valid given the message digest input. It
475-
* does so by validating _sig_ using the public key of this DSA instance.
476-
*
477-
* === Parameters
478-
* * _digest_ is a message digest of the original input data to be signed
479-
* * _sig_ is a DSA signature value
480-
*
481-
* === Example
482-
* dsa = OpenSSL::PKey::DSA.new(2048)
483-
* doc = "Sign me"
484-
* digest = OpenSSL::Digest.digest('SHA1', doc)
485-
* sig = dsa.syssign(digest)
486-
* puts dsa.sysverify(digest, sig) # => true
487-
*
488-
*/
489-
static VALUE
490-
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
491-
{
492-
DSA *dsa;
493-
int ret;
494-
495-
GetDSA(self, dsa);
496-
StringValue(digest);
497-
StringValue(sig);
498-
/* type is ignored (0) */
499-
ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
500-
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa);
501-
if (ret < 0) {
502-
ossl_raise(eDSAError, NULL);
503-
}
504-
else if (ret == 1) {
505-
return Qtrue;
506-
}
507-
508-
return Qfalse;
509-
}
510-
511425
/*
512426
* Document-method: OpenSSL::PKey::DSA#set_pqg
513427
* call-seq:
@@ -565,8 +479,6 @@ Init_ossl_dsa(void)
565479
rb_define_alias(cDSA, "to_s", "export");
566480
rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0);
567481
rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0);
568-
rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1);
569-
rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2);
570482

571483
DEF_OSSL_PKEY_BN(cDSA, dsa, p);
572484
DEF_OSSL_PKEY_BN(cDSA, dsa, q);

lib/openssl/pkey.rb

+54
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,60 @@ def compute_key(pub_bn)
3131

3232
class DSA
3333
include OpenSSL::Marshal
34+
35+
# :call-seq:
36+
# dsa.syssign(string) -> string
37+
#
38+
# Computes and returns the \DSA signature of +string+, where +string+ is
39+
# expected to be an already-computed message digest of the original input
40+
# data. The signature is issued using the private key of this DSA instance.
41+
#
42+
# <b>Deprecated in version 2.3</b>.
43+
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
44+
#
45+
# +string+::
46+
# A message digest of the original input data to be signed.
47+
#
48+
# Example:
49+
# dsa = OpenSSL::PKey::DSA.new(2048)
50+
# doc = "Sign me"
51+
# digest = OpenSSL::Digest.digest('SHA1', doc)
52+
#
53+
# # With legacy #syssign and #sysverify:
54+
# sig = dsa.syssign(digest)
55+
# p dsa.sysverify(digest, sig) #=> true
56+
#
57+
# # With #sign_raw and #verify_raw:
58+
# sig = dsa.sign_raw(nil, digest)
59+
# p dsa.verify_raw(nil, sig, digest) #=> true
60+
def syssign(string)
61+
q or raise OpenSSL::PKey::DSAError, "incomplete DSA"
62+
private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!"
63+
begin
64+
sign_raw(nil, string)
65+
rescue OpenSSL::PKey::PKeyError
66+
raise OpenSSL::PKey::DSAError, $!.message
67+
end
68+
end
69+
70+
# :call-seq:
71+
# dsa.sysverify(digest, sig) -> true | false
72+
#
73+
# Verifies whether the signature is valid given the message digest input.
74+
# It does so by validating +sig+ using the public key of this DSA instance.
75+
#
76+
# <b>Deprecated in version 2.3</b>.
77+
# Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead.
78+
#
79+
# +digest+::
80+
# A message digest of the original input data to be signed.
81+
# +sig+::
82+
# A \DSA signature value.
83+
def sysverify(digest, sig)
84+
verify_raw(nil, sig, digest)
85+
rescue OpenSSL::PKey::PKeyError
86+
raise OpenSSL::PKey::DSAError, $!.message
87+
end
3488
end
3589

3690
if defined?(EC)

0 commit comments

Comments
 (0)