Skip to content

Commit 809646e

Browse files
authored
Merge pull request #382 from rhenium/ky/pkey-encrypt-decrypt
pkey: implement PKey#encrypt, #decrypt, #sign_raw, #verify_raw, and #verify_recover
2 parents 508ae95 + ce805ad commit 809646e

File tree

8 files changed

+684
-317
lines changed

8 files changed

+684
-317
lines changed

ext/openssl/ossl_pkey.c

+375-2
Large diffs are not rendered by default.

ext/openssl/ossl_pkey_dsa.c

-88
Original file line numberDiff line numberDiff line change
@@ -264,92 +264,6 @@ ossl_dsa_get_params(VALUE self)
264264
return hash;
265265
}
266266

267-
/*
268-
* call-seq:
269-
* dsa.syssign(string) -> aString
270-
*
271-
* Computes and returns the DSA signature of _string_, where _string_ is
272-
* expected to be an already-computed message digest of the original input
273-
* data. The signature is issued using the private key of this DSA instance.
274-
*
275-
* === Parameters
276-
* * _string_ is a message digest of the original input data to be signed.
277-
*
278-
* === Example
279-
* dsa = OpenSSL::PKey::DSA.new(2048)
280-
* doc = "Sign me"
281-
* digest = OpenSSL::Digest.digest('SHA1', doc)
282-
* sig = dsa.syssign(digest)
283-
*
284-
*
285-
*/
286-
static VALUE
287-
ossl_dsa_sign(VALUE self, VALUE data)
288-
{
289-
DSA *dsa;
290-
const BIGNUM *dsa_q;
291-
unsigned int buf_len;
292-
VALUE str;
293-
294-
GetDSA(self, dsa);
295-
DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
296-
if (!dsa_q)
297-
ossl_raise(eDSAError, "incomplete DSA");
298-
if (!DSA_PRIVATE(self, dsa))
299-
ossl_raise(eDSAError, "Private DSA key needed!");
300-
StringValue(data);
301-
str = rb_str_new(0, DSA_size(dsa));
302-
if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
303-
(unsigned char *)RSTRING_PTR(str),
304-
&buf_len, dsa)) { /* type is ignored (0) */
305-
ossl_raise(eDSAError, NULL);
306-
}
307-
rb_str_set_len(str, buf_len);
308-
309-
return str;
310-
}
311-
312-
/*
313-
* call-seq:
314-
* dsa.sysverify(digest, sig) -> true | false
315-
*
316-
* Verifies whether the signature is valid given the message digest input. It
317-
* does so by validating _sig_ using the public key of this DSA instance.
318-
*
319-
* === Parameters
320-
* * _digest_ is a message digest of the original input data to be signed
321-
* * _sig_ is a DSA signature value
322-
*
323-
* === Example
324-
* dsa = OpenSSL::PKey::DSA.new(2048)
325-
* doc = "Sign me"
326-
* digest = OpenSSL::Digest.digest('SHA1', doc)
327-
* sig = dsa.syssign(digest)
328-
* puts dsa.sysverify(digest, sig) # => true
329-
*
330-
*/
331-
static VALUE
332-
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
333-
{
334-
DSA *dsa;
335-
int ret;
336-
337-
GetDSA(self, dsa);
338-
StringValue(digest);
339-
StringValue(sig);
340-
/* type is ignored (0) */
341-
ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
342-
(unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa);
343-
if (ret < 0) {
344-
ossl_raise(eDSAError, NULL);
345-
}
346-
else if (ret == 1) {
347-
return Qtrue;
348-
}
349-
350-
return Qfalse;
351-
}
352-
353267
/*
354268
* Document-method: OpenSSL::PKey::DSA#set_pqg
355269
* call-seq:
@@ -404,8 +318,6 @@ Init_ossl_dsa(void)
404318
rb_define_alias(cDSA, "to_pem", "export");
405319
rb_define_alias(cDSA, "to_s", "export");
406320
rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0);
407-
rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1);
408-
rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2);
409321

410322
DEF_OSSL_PKEY_BN(cDSA, dsa, p);
411323
DEF_OSSL_PKEY_BN(cDSA, dsa, q);

ext/openssl/ossl_pkey_ec.c

-55
Original file line numberDiff line numberDiff line change
@@ -471,57 +471,6 @@ static VALUE ossl_ec_key_check_key(VALUE self)
471471
return Qtrue;
472472
}
473473

474-
/*
475-
* call-seq:
476-
* key.dsa_sign_asn1(data) => String
477-
*
478-
* See the OpenSSL documentation for ECDSA_sign()
479-
*/
480-
static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data)
481-
{
482-
EC_KEY *ec;
483-
unsigned int buf_len;
484-
VALUE str;
485-
486-
GetEC(self, ec);
487-
StringValue(data);
488-
489-
if (EC_KEY_get0_private_key(ec) == NULL)
490-
ossl_raise(eECError, "Private EC key needed!");
491-
492-
str = rb_str_new(0, ECDSA_size(ec));
493-
if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1)
494-
ossl_raise(eECError, "ECDSA_sign");
495-
rb_str_set_len(str, buf_len);
496-
497-
return str;
498-
}
499-
500-
/*
501-
* call-seq:
502-
* key.dsa_verify_asn1(data, sig) => true or false
503-
*
504-
* See the OpenSSL documentation for ECDSA_verify()
505-
*/
506-
static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig)
507-
{
508-
EC_KEY *ec;
509-
510-
GetEC(self, ec);
511-
StringValue(data);
512-
StringValue(sig);
513-
514-
switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) {
515-
case 1: return Qtrue;
516-
case 0: return Qfalse;
517-
default: break;
518-
}
519-
520-
ossl_raise(eECError, "ECDSA_verify");
521-
522-
UNREACHABLE;
523-
}
524-
525474
/*
526475
* OpenSSL::PKey::EC::Group
527476
*/
@@ -1583,10 +1532,6 @@ void Init_ossl_ec(void)
15831532
rb_define_alias(cEC, "generate_key", "generate_key!");
15841533
rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0);
15851534

1586-
rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1);
1587-
rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2);
1588-
/* do_sign/do_verify */
1589-
15901535
rb_define_method(cEC, "export", ossl_ec_key_export, -1);
15911536
rb_define_alias(cEC, "to_pem", "export");
15921537
rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0);

ext/openssl/ossl_pkey_rsa.c

-141
Original file line numberDiff line numberDiff line change
@@ -229,138 +229,6 @@ ossl_rsa_to_der(VALUE self)
229229
return ossl_pkey_export_spki(self, 1);
230230
}
231231

232-
/*
233-
* call-seq:
234-
* rsa.public_encrypt(string) => String
235-
* rsa.public_encrypt(string, padding) => String
236-
*
237-
* Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING.
238-
* The encrypted string output can be decrypted using #private_decrypt.
239-
*/
240-
static VALUE
241-
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
242-
{
243-
RSA *rsa;
244-
const BIGNUM *rsa_n;
245-
int buf_len, pad;
246-
VALUE str, buffer, padding;
247-
248-
GetRSA(self, rsa);
249-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
250-
if (!rsa_n)
251-
ossl_raise(eRSAError, "incomplete RSA");
252-
rb_scan_args(argc, argv, "11", &buffer, &padding);
253-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
254-
StringValue(buffer);
255-
str = rb_str_new(0, RSA_size(rsa));
256-
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
257-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
258-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
259-
rb_str_set_len(str, buf_len);
260-
261-
return str;
262-
}
263-
264-
/*
265-
* call-seq:
266-
* rsa.public_decrypt(string) => String
267-
* rsa.public_decrypt(string, padding) => String
268-
*
269-
* Decrypt _string_, which has been encrypted with the private key, with the
270-
* public key. _padding_ defaults to PKCS1_PADDING.
271-
*/
272-
static VALUE
273-
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
274-
{
275-
RSA *rsa;
276-
const BIGNUM *rsa_n;
277-
int buf_len, pad;
278-
VALUE str, buffer, padding;
279-
280-
GetRSA(self, rsa);
281-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
282-
if (!rsa_n)
283-
ossl_raise(eRSAError, "incomplete RSA");
284-
rb_scan_args(argc, argv, "11", &buffer, &padding);
285-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
286-
StringValue(buffer);
287-
str = rb_str_new(0, RSA_size(rsa));
288-
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
289-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
290-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
291-
rb_str_set_len(str, buf_len);
292-
293-
return str;
294-
}
295-
296-
/*
297-
* call-seq:
298-
* rsa.private_encrypt(string) => String
299-
* rsa.private_encrypt(string, padding) => String
300-
*
301-
* Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING.
302-
* The encrypted string output can be decrypted using #public_decrypt.
303-
*/
304-
static VALUE
305-
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
306-
{
307-
RSA *rsa;
308-
const BIGNUM *rsa_n;
309-
int buf_len, pad;
310-
VALUE str, buffer, padding;
311-
312-
GetRSA(self, rsa);
313-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
314-
if (!rsa_n)
315-
ossl_raise(eRSAError, "incomplete RSA");
316-
if (!RSA_PRIVATE(self, rsa))
317-
ossl_raise(eRSAError, "private key needed.");
318-
rb_scan_args(argc, argv, "11", &buffer, &padding);
319-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
320-
StringValue(buffer);
321-
str = rb_str_new(0, RSA_size(rsa));
322-
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
323-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
324-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
325-
rb_str_set_len(str, buf_len);
326-
327-
return str;
328-
}
329-
330-
/*
331-
* call-seq:
332-
* rsa.private_decrypt(string) => String
333-
* rsa.private_decrypt(string, padding) => String
334-
*
335-
* Decrypt _string_, which has been encrypted with the public key, with the
336-
* private key. _padding_ defaults to PKCS1_PADDING.
337-
*/
338-
static VALUE
339-
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
340-
{
341-
RSA *rsa;
342-
const BIGNUM *rsa_n;
343-
int buf_len, pad;
344-
VALUE str, buffer, padding;
345-
346-
GetRSA(self, rsa);
347-
RSA_get0_key(rsa, &rsa_n, NULL, NULL);
348-
if (!rsa_n)
349-
ossl_raise(eRSAError, "incomplete RSA");
350-
if (!RSA_PRIVATE(self, rsa))
351-
ossl_raise(eRSAError, "private key needed.");
352-
rb_scan_args(argc, argv, "11", &buffer, &padding);
353-
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
354-
StringValue(buffer);
355-
str = rb_str_new(0, RSA_size(rsa));
356-
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
357-
(unsigned char *)RSTRING_PTR(str), rsa, pad);
358-
if (buf_len < 0) ossl_raise(eRSAError, NULL);
359-
rb_str_set_len(str, buf_len);
360-
361-
return str;
362-
}
363-
364232
/*
365233
* call-seq:
366234
* rsa.sign_pss(digest, data, salt_length:, mgf1_hash:) -> String
@@ -657,10 +525,6 @@ Init_ossl_rsa(void)
657525
rb_define_alias(cRSA, "to_pem", "export");
658526
rb_define_alias(cRSA, "to_s", "export");
659527
rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0);
660-
rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1);
661-
rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1);
662-
rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1);
663-
rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1);
664528
rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1);
665529
rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1);
666530

@@ -678,11 +542,6 @@ Init_ossl_rsa(void)
678542

679543
rb_define_method(cRSA, "params", ossl_rsa_get_params, 0);
680544

681-
DefRSAConst(PKCS1_PADDING);
682-
DefRSAConst(SSLV23_PADDING);
683-
DefRSAConst(NO_PADDING);
684-
DefRSAConst(PKCS1_OAEP_PADDING);
685-
686545
/*
687546
* TODO: Test it
688547
rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0);

0 commit comments

Comments
 (0)