diff options
author | Michal Rokos <m.rokos@sh.cvut.cz> | 2002-06-10 08:39:05 +0000 |
---|---|---|
committer | Michal Rokos <m.rokos@sh.cvut.cz> | 2002-06-10 08:39:05 +0000 |
commit | 416323fd522a3118b293589d128faa7de7323600 (patch) | |
tree | 7b290438cdd9820106a4635357680d7918edfd5d | |
parent | 9e6c2e2c64d62f313d35fad7aaa2a9b562b55484 (diff) | |
download | ruby-openssl-history-416323fd522a3118b293589d128faa7de7323600.tar.gz |
PKey#sign and #verify moved to C-space (pkey.c)
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | lib/openssl.rb | 1 | ||||
-rw-r--r-- | lib/openssl/pkey.rb | 76 | ||||
-rw-r--r-- | ossl_pkey.c | 61 | ||||
-rw-r--r-- | ossl_pkey_dsa.c | 6 | ||||
-rw-r--r-- | ossl_pkey_rsa.c | 65 |
6 files changed, 110 insertions, 105 deletions
@@ -3,6 +3,12 @@ ChangeLog for ### CHANGE LOG ### +Mon, 10 Jun 2002 10:35:56 +0200 -- Michal Rokos <m.rokos@sh.cvut.cz> + * pkey.c: implemented #sign and #verify for PKey + * pkey.rb: deleted (funcs implemented in C-space (pkey.c)) + * pkey_dsa.c: #sign_digest and #verify_digest renamed to #syssign #sysverify + * pkey_rsa.c: implemented RSA_sign, RSA_verify, but commented out until a good way of specifiing digest type will be found + Sun, 9 Jun 2002 22:17:13 +0200 -- Michal Rokos <m.rokos@sh.cvut.cz> * x509store.c: really port to Ruby 1.8 interface :-) * x509store.c: #protect method dropped (useless) diff --git a/lib/openssl.rb b/lib/openssl.rb index 18bc1c4..24a9eed 100644 --- a/lib/openssl.rb +++ b/lib/openssl.rb @@ -19,7 +19,6 @@ require 'openssl.so' require 'openssl/bn' require 'openssl/cipher' require 'openssl/digest' -require 'openssl/pkey' require 'openssl/ssl' require 'openssl/x509' diff --git a/lib/openssl/pkey.rb b/lib/openssl/pkey.rb deleted file mode 100644 index 7067130..0000000 --- a/lib/openssl/pkey.rb +++ /dev/null @@ -1,76 +0,0 @@ -=begin -= $RCSfile$ -- Ruby-space definitions that completes C-space funcs for PKey and subclasses - -= Info - 'OpenSSL for Ruby 2' project - Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> - All rights reserved. - -= Licence - This program is licenced under the same licence as Ruby. - (See the file 'LICENCE'.) - -= Version - $Id$ -=end - -## -# Should we care what if somebody require this file directly? -#require 'openssl' - -module OpenSSL -module PKey - -if defined? DSA - class DSA - def sign(digest, data) - unless private? - raise OpenSSL::PKey::DSAError, "Cannot sign with public key!" - end - unless digest.kind_of? OpenSSL::Digest::Digest - raise TypeError, "digest alg needed! (got #{digest.class})" - end - sign_digest digest.update(data.to_s).digest - end # sign - - def verify(digest, signature, data) - unless digest.kind_of? OpenSSL::Digest::Digest - raise TypeError, "digest alg needed! (got #{digest.class})" - end - unless signature.class == String - raise TypeError, "Signature as String expected (got #{sign.class})" - end - verify_digest(digest.update(data.to_s).digest, signature) - end # verify - end # DSA -end #defined? DSA - -if defined? RSA - class RSA - def sign(digest, data) - unless self.private? - raise OpenSSL::PKey::RSAError, "Cannot sign with public key!" - end - unless digest.kind_of? OpenSSL::Digest::Digest - raise TypeError, "digest alg needed! (got #{digest.class})" - end - private_encrypt digest.update(data.to_s).digest - end # sign - - def verify(digest, signature, data) - unless digest.kind_of? OpenSSL::Digest::Digest - raise TypeError, "digest alg needed! (got #{digest.class})" - end - unless signature.class == String - raise TypeError, "Signature as String expected (got #{sign.class})" - end - md_s = self.public_decrypt signature - md_d = digest.update(data.to_s).digest - md_s == md_d - end # verify - end # RSA -end # defined? RSA - -end # PKey -end # OpenSSL - diff --git a/ossl_pkey.c b/ossl_pkey.c index e6733e5..5737b53 100644 --- a/ossl_pkey.c +++ b/ossl_pkey.c @@ -163,6 +163,65 @@ ossl_pkey_to_der(VALUE self) return str; } +static VALUE +ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) +{ + EVP_PKEY *pkey; + EVP_MD_CTX ctx; + const EVP_MD *md; + char *buf; + int buf_len; + VALUE str; + + GetPKey(self, pkey); + + md = ossl_digest_get_EVP_MD(digest); + StringValue(data); + + EVP_SignInit(&ctx, md); + EVP_SignUpdate(&ctx, RSTRING(data)->ptr, RSTRING(data)->len); + + if (!(buf = OPENSSL_malloc(EVP_PKEY_size(pkey) + 16))) { + OSSL_Raise(ePKeyError, ""); + } + if (!EVP_SignFinal(&ctx, buf, &buf_len, pkey)) { + OPENSSL_free(buf); + OSSL_Raise(ePKeyError, ""); + } + str = rb_str_new(buf, buf_len); + OPENSSL_free(buf); + + return str; +} + +static VALUE +ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) +{ + EVP_PKEY *pkey; + EVP_MD_CTX ctx; + const EVP_MD *md; + int result; + + GetPKey(self, pkey); + + md = ossl_digest_get_EVP_MD(digest); + StringValue(sig); + StringValue(data); + + EVP_VerifyInit(&ctx, md); + EVP_VerifyUpdate(&ctx, RSTRING(data)->ptr, RSTRING(data)->len); + + result = EVP_VerifyFinal(&ctx, RSTRING(sig)->ptr, RSTRING(sig)->len, pkey); + + if (result < 0) { + OSSL_Raise(ePKeyError, ""); + } + if (result == 1) { + return Qtrue; + } + return Qfalse; +} + /* * INIT */ @@ -179,6 +238,8 @@ Init_ossl_pkey() rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); rb_define_method(cPKey, "to_der", ossl_pkey_to_der, 0); + rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); + rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); id_private_q = rb_intern("private?"); diff --git a/ossl_pkey_dsa.c b/ossl_pkey_dsa.c index 3a565a0..7a69cdc 100644 --- a/ossl_pkey_dsa.c +++ b/ossl_pkey_dsa.c @@ -305,7 +305,7 @@ ossl_dsa_sign(VALUE self, VALUE data) if (!(buf = OPENSSL_malloc(DSA_size(pkey->pkey.dsa) + 16))) { OSSL_Raise(eDSAError, ""); } - if (!DSA_sign(0, RSTRING(data)->ptr, RSTRING(data)->len, buf, &buf_len, pkey->pkey.dsa)) { /*type = 0*/ + if (!DSA_sign(0, RSTRING(data)->ptr, RSTRING(data)->len, buf, &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */ OPENSSL_free(buf); OSSL_Raise(eDSAError, ""); } @@ -355,8 +355,8 @@ Init_ossl_dsa() rb_define_method(cDSA, "export", ossl_dsa_export, -1); rb_define_alias(cDSA, "to_pem", "export"); rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); - rb_define_method(cDSA, "sign_digest", ossl_dsa_sign, 1); - rb_define_method(cDSA, "verify_digest", ossl_dsa_verify, 2); + rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); + rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); } #else /* defined NO_DSA */ diff --git a/ossl_pkey_rsa.c b/ossl_pkey_rsa.c index d77ce69..8e35c32 100644 --- a/ossl_pkey_rsa.c +++ b/ossl_pkey_rsa.c @@ -413,43 +413,57 @@ ossl_rsa_to_public_key(VALUE self) } /* - * Better to implement is in Ruby space? + * TODO, FIXME + * Find some good way how to specify type + * Is NID_md5_sha1 OK for all? (Don't think so.) * static VALUE -ossl_rsa_sign(VALUE self, VALUE digest, VALUE text) +ossl_rsa_sign(VALUE self, VALUE data) { - ossl_rsa *rsap = NULL; - EVP_MD_CTX ctx; - const EVP_MD *md = NULL; - char *sign = NULL; - int sign_len = 0; + EVP_PKEY *pkey; + char *buf; + int buf_len; VALUE str; - GetRSA(self, rsap); - OSSL_Check_type(digest, cDigest); - text = rb_String(text); + GetPKeyRSA(self, pkey); + + StringValue(data); - if (!(sign = OPENSSL_malloc(RSA_size(rsap->rsa)+16))) { + if (!RSA_PRIVATE(pkey->pkey.rsa)) { + rb_raise(eRSAError, "Private RSA key needed!"); + } + if (!(buf = OPENSSL_malloc(RSA_size(pkey->pkey.rsa) + 16))) { OSSL_Raise(eRSAError, ""); } - - md = ossl_digest_get_EVP_MD(digest); - EVP_SignInit(&ctx, md); - EVP_SignUpdate(&ctx, RSTRING(text)->ptr, RSTRING(text)->len); - if (!EVP_SignFinal(&ctx, sign, &sign_len, pkeyp->key)) { - OPENSSL_free(sign); + if (!RSA_sign(0, RSTRING(data)->ptr, RSTRING(data)->len, buf, &buf_len, pkey->pkey.rsa)) { + OPENSSL_free(buf); OSSL_Raise(eRSAError, ""); } - - str = rb_str_new(sign, sign_len); - OPENSSL_free(sign); + str = rb_str_new(buf, buf_len); + OPENSSL_free(buf); return str; } - + static VALUE -ossl_rsa_verify(VALUE self, VALUE digest, VALUE text) +ossl_rsa_verify(VALUE self, VALUE digest, VALUE sig) { + EVP_PKEY *pkey; + int ret; + + GetPKeyDSA(self, pkey); + + StringValue(digest); + StringValue(sig); + + ret = RSA_verify(0, RSTRING(digest)->ptr, RSTRING(digest)->len, RSTRING(sig)->ptr, RSTRING(sig)->len, pkey->pkey.rsa); + + if (ret < 0) { + OSSL_Raise(eRSAError, ""); + } else if (ret == 1) { + return Qtrue; + } + return Qfalse; } */ @@ -478,10 +492,11 @@ Init_ossl_rsa() rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, 1); /*rb_define_method(cRSA, "n", ossl_rsa_get_n, 0);*/ /* - * Implemented in Ruby space... + * TODO, FIXME + * Find way how to support digest types * - rb_define_method(cRSA, "sign", ossl_rsa_sign, 2); - rb_define_method(cRSA, "verify", ossl_rsa_verify, 3); + rb_define_method(cRSA, "syssign", ossl_rsa_sign, 2); + rb_define_method(cRSA, "sysverify", ossl_rsa_verify, 3); */ } |