diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-01-22 18:49:22 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-03-04 12:39:08 +0900 |
commit | a6708846f40f8ea7cb7bb04b9bcec6ec459b9d3b (patch) | |
tree | 92fa300c41c3de48c7c802e325606e3eef507f3c | |
parent | c6b0cbe82ea3ac9c1f54005bea7c4dd9fcc78327 (diff) | |
download | ruby-openssl-topic/pkey-signer.tar.gz |
x509: sign with OpenSSL::PKey::Signer interfacetopic/pkey-signer
OpenSSL::X509::{Certificate,CRL,Request}#sign now accept an instance of
OpenSSL::PKey::Signer in addition to a pair of a private key and digest
algorithm name.
-rw-r--r-- | ext/openssl/ossl_x509cert.c | 26 | ||||
-rw-r--r-- | ext/openssl/ossl_x509crl.c | 29 | ||||
-rw-r--r-- | ext/openssl/ossl_x509req.c | 29 | ||||
-rw-r--r-- | test/test_x509cert.rb | 12 | ||||
-rw-r--r-- | test/test_x509crl.rb | 10 | ||||
-rw-r--r-- | test/test_x509req.rb | 10 |
6 files changed, 86 insertions, 30 deletions
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 00bce40c..bb48c8b7 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -564,20 +564,28 @@ ossl_x509_set_public_key(VALUE self, VALUE key) /* * call-seq: * cert.sign(key, digest) => self + * cert.sign(signer) => self + * + * Signs the certificate using private key _key_ and message digest algorithm + * _digest_. Alternatively, if an OpenSSL::PKey::Signer _signer_ is given, uses + * the parameters contained in _signer_. */ static VALUE -ossl_x509_sign(VALUE self, VALUE key, VALUE digest) +ossl_x509_sign(int argc, VALUE *argv, VALUE self) { X509 *x509; - EVP_PKEY *pkey; - const EVP_MD *md; + VALUE signer, digest; + EVP_MD_CTX *ctx; + + rb_scan_args(argc, argv, "11", &signer, &digest); + if (argc == 2) + signer = ossl_pkey_signer(signer, digest); - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); GetX509(self, x509); - if (!X509_sign(x509, pkey, md)) { - ossl_raise(eX509CertError, NULL); - } + ctx = GetPKeySignature(signer); + if (!X509_sign_ctx(x509, ctx)) + ossl_raise(eX509CertError, "X509_sign_ctx"); + RB_GC_GUARD(signer); return self; } @@ -852,7 +860,7 @@ Init_ossl_x509cert(void) rb_define_method(cX509Cert, "not_after=", ossl_x509_set_not_after, 1); rb_define_method(cX509Cert, "public_key", ossl_x509_get_public_key, 0); rb_define_method(cX509Cert, "public_key=", ossl_x509_set_public_key, 1); - rb_define_method(cX509Cert, "sign", ossl_x509_sign, 2); + rb_define_method(cX509Cert, "sign", ossl_x509_sign, -1); rb_define_method(cX509Cert, "verify", ossl_x509_verify, 1); rb_define_method(cX509Cert, "check_private_key", ossl_x509_check_private_key, 1); rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0); diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index f9819f58..71c4f16f 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -345,19 +345,30 @@ ossl_x509crl_add_revoked(VALUE self, VALUE revoked) return revoked; } +/* + * call-seq: + * crl.sign(key, digest) => self + * crl.sign(signer) => self + * + * Signs the CRL using private key _key_ and message digest algorithm _digest_. + * Alternatively, if an OpenSSL::PKey::Signer _signer_ is given, uses the + * parameters contained in _signer_. + */ static VALUE -ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest) +ossl_x509crl_sign(int argc, VALUE *argv, VALUE self) { X509_CRL *crl; - EVP_PKEY *pkey; - const EVP_MD *md; + VALUE signer, digest; + EVP_MD_CTX *ctx; + + if (rb_scan_args(argc, argv, "11", &signer, &digest) == 2) + signer = ossl_pkey_signer(signer, digest); GetX509CRL(self, crl); - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - if (!X509_CRL_sign(crl, pkey, md)) { - ossl_raise(eX509CRLError, NULL); - } + ctx = GetPKeySignature(signer); + if (!X509_CRL_sign_ctx(crl, ctx)) + ossl_raise(eX509CRLError, "X509_CRL_sign_ctx"); + RB_GC_GUARD(signer); return self; } @@ -534,7 +545,7 @@ Init_ossl_x509crl(void) rb_define_method(cX509CRL, "revoked", ossl_x509crl_get_revoked, 0); rb_define_method(cX509CRL, "revoked=", ossl_x509crl_set_revoked, 1); rb_define_method(cX509CRL, "add_revoked", ossl_x509crl_add_revoked, 1); - rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, 2); + rb_define_method(cX509CRL, "sign", ossl_x509crl_sign, -1); rb_define_method(cX509CRL, "verify", ossl_x509crl_verify, 1); rb_define_method(cX509CRL, "to_der", ossl_x509crl_to_der, 0); rb_define_method(cX509CRL, "to_pem", ossl_x509crl_to_pem, 0); diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index 220d2f40..29ca4951 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -338,19 +338,30 @@ ossl_x509req_set_public_key(VALUE self, VALUE key) return key; } +/* + * call-seq: + * req.sign(key, digest) => self + * req.sign(signer) => self + * + * Signs the certificate request using private key _key_ and message digest + * algorithm _digest_. Alternatively, if an OpenSSL::PKey::Signer _signer_ is + * given, uses the parameters contained in _signer_. + */ static VALUE -ossl_x509req_sign(VALUE self, VALUE key, VALUE digest) +ossl_x509req_sign(int argc, VALUE *argv, VALUE self) { X509_REQ *req; - EVP_PKEY *pkey; - const EVP_MD *md; + VALUE signer, digest; + EVP_MD_CTX *ctx; + + if (rb_scan_args(argc, argv, "11", &signer, &digest) == 2) + signer = ossl_pkey_signer(signer, digest); GetX509Req(self, req); - pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = GetDigestPtr(digest); - if (!X509_REQ_sign(req, pkey, md)) { - ossl_raise(eX509ReqError, NULL); - } + ctx = GetPKeySignature(signer); + if (!X509_REQ_sign_ctx(req, ctx)) + ossl_raise(eX509ReqError, "X509_REQ_sign_ctx"); + RB_GC_GUARD(signer); return self; } @@ -470,7 +481,7 @@ Init_ossl_x509req(void) rb_define_method(cX509Req, "signature_algorithm", ossl_x509req_get_signature_algorithm, 0); rb_define_method(cX509Req, "public_key", ossl_x509req_get_public_key, 0); rb_define_method(cX509Req, "public_key=", ossl_x509req_set_public_key, 1); - rb_define_method(cX509Req, "sign", ossl_x509req_sign, 2); + rb_define_method(cX509Req, "sign", ossl_x509req_sign, -1); rb_define_method(cX509Req, "verify", ossl_x509req_verify, 1); rb_define_method(cX509Req, "attributes", ossl_x509req_get_attributes, 0); rb_define_method(cX509Req, "attributes=", ossl_x509req_set_attributes, 1); diff --git a/test/test_x509cert.rb b/test/test_x509cert.rb index 7f8426f7..79e928de 100644 --- a/test/test_x509cert.rb +++ b/test/test_x509cert.rb @@ -137,8 +137,8 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase rescue OpenSSL::X509::CertificateError end if defined?(OpenSSL::Digest::DSS1) - def test_sign_and_verify_dsa_md5 - assert_raise(OpenSSL::X509::CertificateError){ + def test_sign_dsa_md5 + assert_raise(OpenSSL::PKey::PKeyError) { issue_cert(@ca, @dsa512, 1, [], nil, nil, digest: "md5") } end @@ -153,6 +153,14 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase assert_equal("dsaWithSHA1", cert.signature_algorithm) end + def test_sign_with_signer + cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) + cert.sign(@rsa1024.signer("sha256")) + assert_equal("sha256WithRSAEncryption", cert.signature_algorithm) + assert_equal(true, cert.verify(@rsa1024)) + assert_equal(false, cert.verify(@rsa2048)) + end + def test_check_private_key cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) assert_equal(true, cert.check_private_key(@rsa2048)) diff --git a/test/test_x509crl.rb b/test/test_x509crl.rb index fd7b562a..794c4665 100644 --- a/test/test_x509crl.rb +++ b/test/test_x509crl.rb @@ -195,6 +195,16 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase assert_equal(false, crl.verify(@dsa512)) end + def test_sign_with_signer + cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil) + crl = issue_crl([], 1, Time.now, Time.now+1600, [], + cert, @rsa2048, "sha1") + crl.sign(@rsa1024.signer("sha256")) + assert_equal("sha256WithRSAEncryption", crl.signature_algorithm) + assert_equal(true, crl.verify(@rsa1024)) + assert_equal(false, crl.verify(@rsa2048)) + end + private def crl_error_returns_false diff --git a/test/test_x509req.rb b/test/test_x509req.rb index 88156220..4000ba37 100644 --- a/test/test_x509req.rb +++ b/test/test_x509req.rb @@ -130,10 +130,18 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase end def test_sign_and_verify_dsa_md5 - assert_raise(OpenSSL::X509::RequestError){ + assert_raise(OpenSSL::PKey::PKeyError) { issue_csr(0, @dn, @dsa512, OpenSSL::Digest::MD5.new) } end + def test_sign_with_signer + req = issue_csr(0, @dn, @rsa2048, "sha1") + req.sign(@rsa1024.signer("sha256")) + assert_equal("sha256WithRSAEncryption", req.signature_algorithm) + assert_equal(true, req.verify(@rsa1024)) + assert_equal(false, req.verify(@rsa2048)) + end + def test_dup req = issue_csr(0, @dn, @rsa1024, OpenSSL::Digest::SHA1.new) assert_equal(req.to_der, req.dup.to_der) |