Skip to content

Commit 51621d6

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 8d775a5 commit 51621d6

File tree

2 files changed

+47
-88
lines changed

2 files changed

+47
-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

+47
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,53 @@ 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+
# === Parameters
43+
# * _string_ is a message digest of the original input data to be signed.
44+
#
45+
# === Example
46+
# dsa = OpenSSL::PKey::DSA.new(2048)
47+
# doc = "Sign me"
48+
# digest = OpenSSL::Digest.digest('SHA1', doc)
49+
# sig = dsa.syssign(digest)
50+
def syssign(string)
51+
q or raise OpenSSL::PKey::DSAError, "incomplete DSA"
52+
private? or raise OpenSSL::PKey::DSAError, "Private DSA key needed!"
53+
begin
54+
sign_raw(nil, string)
55+
rescue OpenSSL::PKey::PKeyError
56+
raise OpenSSL::PKey::DSAError, $!.message
57+
end
58+
end
59+
60+
# :call-seq:
61+
# dsa.sysverify(digest, sig) -> true | false
62+
#
63+
# Verifies whether the signature is valid given the message digest input.
64+
# It does so by validating _sig_ using the public key of this DSA instance.
65+
#
66+
# === Parameters
67+
# * _digest_ is a message digest of the original input data to be signed
68+
# * _sig_ is a DSA signature value
69+
#
70+
# === Example
71+
# dsa = OpenSSL::PKey::DSA.new(2048)
72+
# doc = "Sign me"
73+
# digest = OpenSSL::Digest.digest('SHA1', doc)
74+
# sig = dsa.syssign(digest)
75+
# puts dsa.sysverify(digest, sig) # => true
76+
def sysverify(digest, sig)
77+
verify_raw(nil, sig, digest)
78+
rescue OpenSSL::PKey::PKeyError
79+
raise OpenSSL::PKey::DSAError, $!.message
80+
end
3481
end
3582

3683
if defined?(EC)

0 commit comments

Comments
 (0)