aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-01-22 18:49:22 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-03-04 12:39:08 +0900
commita6708846f40f8ea7cb7bb04b9bcec6ec459b9d3b (patch)
tree92fa300c41c3de48c7c802e325606e3eef507f3c
parentc6b0cbe82ea3ac9c1f54005bea7c4dd9fcc78327 (diff)
downloadruby-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.c26
-rw-r--r--ext/openssl/ossl_x509crl.c29
-rw-r--r--ext/openssl/ossl_x509req.c29
-rw-r--r--test/test_x509cert.rb12
-rw-r--r--test/test_x509crl.rb10
-rw-r--r--test/test_x509req.rb10
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)