mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
openssl: allow specifying hash algorithm in OCSP::*#sign
* ext/openssl/ossl_ocsp.c (ossl_ocspreq_sign, ossl_ocspbres_sign): Allow specifying hash algorithm used in signing. They are hard coded to use SHA-1. Based on a patch provided by Tim Shirley <tidoublemy@gmail.com>. [ruby-core:70915] [Feature #11552] [GH ruby/openssl#28] * test/openssl/test_ocsp.rb: Test sign-verify works. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55422 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ce19b495d1
commit
2851f19f49
3 changed files with 99 additions and 41 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Wed Jun 15 19:52:23 2016 Kazuki Yamaguchi <k@rhe.jp>
|
||||
|
||||
* ext/openssl/ossl_ocsp.c (ossl_ocspreq_sign, ossl_ocspbres_sign): Allow
|
||||
specifying hash algorithm used in signing. They are hard coded to use
|
||||
SHA-1.
|
||||
Based on a patch provided by Tim Shirley <tidoublemy@gmail.com>.
|
||||
[ruby-core:70915] [Feature #11552] [GH ruby/openssl#28]
|
||||
|
||||
* test/openssl/test_ocsp.rb: Test sign-verify works.
|
||||
|
||||
Wed Jun 15 01:46:16 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* numeric.c: [DOC] fix rdoc directive, and an example of negative
|
||||
|
|
|
@ -312,39 +312,48 @@ ossl_ocspreq_get_certid(VALUE self)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* request.sign(signer_cert, signer_key) -> self
|
||||
* request.sign(signer_cert, signer_key, certificates) -> self
|
||||
* request.sign(signer_cert, signer_key, certificates, flags) -> self
|
||||
* request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
|
||||
*
|
||||
* Signs this OCSP request using +signer_cert+ and +signer_key+.
|
||||
* +certificates+ is an optional Array of certificates that may be included in
|
||||
* the request.
|
||||
* Signs this OCSP request using +cert+, +key+ and optional +digest+. If
|
||||
* +digest+ is not specified, SHA-1 is used. +certs+ is an optional Array of
|
||||
* additional certificates that will be included in the request. If +certs+ is
|
||||
* not specified, flag OpenSSL::OCSP::NOCERTS is set. Pass an empty array to
|
||||
* include only the signer certificate.
|
||||
*
|
||||
* +flags+ can include:
|
||||
* OpenSSL::OCSP::NOCERTS:: don't include certificates
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE signer_cert, signer_key, certs, flags;
|
||||
VALUE signer_cert, signer_key, certs, flags, digest;
|
||||
OCSP_REQUEST *req;
|
||||
X509 *signer;
|
||||
EVP_PKEY *key;
|
||||
STACK_OF(X509) *x509s;
|
||||
unsigned long flg;
|
||||
STACK_OF(X509) *x509s = NULL;
|
||||
unsigned long flg = 0;
|
||||
const EVP_MD *md;
|
||||
int ret;
|
||||
|
||||
rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
|
||||
rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
|
||||
GetOCSPReq(self, req);
|
||||
signer = GetX509CertPtr(signer_cert);
|
||||
key = GetPrivPKeyPtr(signer_key);
|
||||
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
||||
if(NIL_P(certs)){
|
||||
x509s = sk_X509_new_null();
|
||||
if (!NIL_P(flags))
|
||||
flg = NUM2INT(flags);
|
||||
if (NIL_P(digest))
|
||||
md = EVP_sha1();
|
||||
else
|
||||
md = GetDigestPtr(digest);
|
||||
if (NIL_P(certs))
|
||||
flags |= OCSP_NOCERTS;
|
||||
}
|
||||
else x509s = ossl_x509_ary2sk(certs);
|
||||
GetOCSPReq(self, req);
|
||||
ret = OCSP_request_sign(req, signer, key, EVP_sha1(), x509s, flg);
|
||||
else
|
||||
x509s = ossl_x509_ary2sk(certs);
|
||||
|
||||
ret = OCSP_request_sign(req, signer, key, md, x509s, flg);
|
||||
sk_X509_pop_free(x509s, X509_free);
|
||||
if(!ret) ossl_raise(eOCSPError, NULL);
|
||||
if (!ret) ossl_raise(eOCSPError, NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -799,40 +808,47 @@ ossl_ocspbres_get_status(VALUE self)
|
|||
|
||||
/*
|
||||
* call-seq:
|
||||
* basic_response.sign(signer_cert, signer_key) -> self
|
||||
* basic_response.sign(signer_cert, signer_key, certificates) -> self
|
||||
* basic_response.sign(signer_cert, signer_key, certificates, flags) -> self
|
||||
* basic_response.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
|
||||
*
|
||||
* Signs this response using the +signer_cert+ and +signer_key+. Additional
|
||||
* +certificates+ may be added to the signature along with a set of +flags+.
|
||||
* Signs this OCSP response using the +cert+, +key+ and optional +digest+. This
|
||||
* behaves in the similar way as OpenSSL::OCSP::Request#sign.
|
||||
*
|
||||
* +flags+ can include:
|
||||
* OpenSSL::OCSP::NOCERTS:: don't include certificates
|
||||
* OpenSSL::OCSP::NOTIME:: don't set producedAt
|
||||
* OpenSSL::OCSP::RESPID_KEY:: use signer's public key hash as responderID
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE signer_cert, signer_key, certs, flags;
|
||||
VALUE signer_cert, signer_key, certs, flags, digest;
|
||||
OCSP_BASICRESP *bs;
|
||||
X509 *signer;
|
||||
EVP_PKEY *key;
|
||||
STACK_OF(X509) *x509s;
|
||||
unsigned long flg;
|
||||
STACK_OF(X509) *x509s = NULL;
|
||||
unsigned long flg = 0;
|
||||
const EVP_MD *md;
|
||||
int ret;
|
||||
|
||||
rb_scan_args(argc, argv, "22", &signer_cert, &signer_key, &certs, &flags);
|
||||
rb_scan_args(argc, argv, "23", &signer_cert, &signer_key, &certs, &flags, &digest);
|
||||
GetOCSPBasicRes(self, bs);
|
||||
signer = GetX509CertPtr(signer_cert);
|
||||
key = GetPrivPKeyPtr(signer_key);
|
||||
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
|
||||
if(NIL_P(certs)){
|
||||
x509s = sk_X509_new_null();
|
||||
if (!NIL_P(flags))
|
||||
flg = NUM2INT(flags);
|
||||
if (NIL_P(digest))
|
||||
md = EVP_sha1();
|
||||
else
|
||||
md = GetDigestPtr(digest);
|
||||
if (NIL_P(certs))
|
||||
flg |= OCSP_NOCERTS;
|
||||
}
|
||||
else{
|
||||
else
|
||||
x509s = ossl_x509_ary2sk(certs);
|
||||
}
|
||||
GetOCSPBasicRes(self, bs);
|
||||
ret = OCSP_basic_sign(bs, signer, key, EVP_sha1(), x509s, flg);
|
||||
|
||||
ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg);
|
||||
sk_X509_pop_free(x509s, X509_free);
|
||||
if(!ret) ossl_raise(eOCSPError, NULL);
|
||||
if (!ret) ossl_raise(eOCSPError, NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -86,14 +86,34 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
|
|||
assert_equal asn1.to_der, OpenSSL::OCSP::Request.new(asn1.to_der).to_der
|
||||
end
|
||||
|
||||
def test_new_ocsp_request
|
||||
def test_request_sign_verify
|
||||
request = OpenSSL::OCSP::Request.new
|
||||
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
|
||||
request.add_certid(cid)
|
||||
request.sign(@cert, @key, [@cert])
|
||||
assert_kind_of OpenSSL::OCSP::Request, request
|
||||
# in current implementation not same instance of certificate id, but should contain same data
|
||||
assert_equal cid.serial, request.certid.first.serial
|
||||
request.sign(@cert, @key, nil, 0, "SHA1")
|
||||
assert_equal cid.to_der, request.certid.first.to_der
|
||||
store1 = OpenSSL::X509::Store.new; store1.add_cert(@ca_cert)
|
||||
assert_equal true, request.verify([@cert], store1)
|
||||
assert_equal true, request.verify([], store1)
|
||||
store2 = OpenSSL::X509::Store.new; store1.add_cert(@cert2)
|
||||
assert_equal false, request.verify([], store2)
|
||||
assert_equal true, request.verify([], store2, OpenSSL::OCSP::NOVERIFY)
|
||||
end
|
||||
|
||||
def test_request_nonce
|
||||
req0 = OpenSSL::OCSP::Request.new
|
||||
req1 = OpenSSL::OCSP::Request.new
|
||||
req1.add_nonce("NONCE")
|
||||
req2 = OpenSSL::OCSP::Request.new
|
||||
req2.add_nonce("NONCF")
|
||||
bres = OpenSSL::OCSP::BasicResponse.new
|
||||
assert_equal 2, req0.check_nonce(bres)
|
||||
bres.copy_nonce(req1)
|
||||
assert_equal 1, req1.check_nonce(bres)
|
||||
bres.add_nonce("NONCE")
|
||||
assert_equal 1, req1.check_nonce(bres)
|
||||
assert_equal 0, req2.check_nonce(bres)
|
||||
assert_equal 3, req0.check_nonce(bres)
|
||||
end
|
||||
|
||||
def test_basic_response_der
|
||||
|
@ -109,6 +129,18 @@ class OpenSSL::TestOCSP < OpenSSL::TestCase
|
|||
assert_equal der, OpenSSL::OCSP::BasicResponse.new(der).to_der
|
||||
end
|
||||
|
||||
def test_basic_response_sign_verify
|
||||
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new)
|
||||
bres = OpenSSL::OCSP::BasicResponse.new
|
||||
bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, 500, [])
|
||||
bres.sign(@cert2, @key2, [], 0, "SHA256") # how can I check the algorithm?
|
||||
store1 = OpenSSL::X509::Store.new; store1.add_cert(@ca_cert)
|
||||
assert_equal true, bres.verify([], store1)
|
||||
store2 = OpenSSL::X509::Store.new; store2.add_cert(@cert)
|
||||
assert_equal false, bres.verify([], store2)
|
||||
assert_equal true, bres.verify([], store2, OpenSSL::OCSP::NOVERIFY)
|
||||
end
|
||||
|
||||
def test_response_der
|
||||
bres = OpenSSL::OCSP::BasicResponse.new
|
||||
cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new)
|
||||
|
|
Loading…
Add table
Reference in a new issue