[前][次][番号順一覧][スレッド一覧]

ruby-changes:43348

From: rhe <ko1@a...>
Date: Wed, 15 Jun 2016 19:52:42 +0900 (JST)
Subject: [ruby-changes:43348] rhe:r55422 (trunk): openssl: allow specifying hash algorithm in OCSP::*#sign

rhe	2016-06-15 19:52:37 +0900 (Wed, 15 Jun 2016)

  New Revision: 55422

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55422

  Log:
    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@g...>.
      [ruby-core:70915] [Feature #11552] [GH ruby/openssl#28]
    
    * test/openssl/test_ocsp.rb: Test sign-verify works.

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl_ocsp.c
    trunk/test/openssl/test_ocsp.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55421)
+++ ChangeLog	(revision 55422)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Jun 15 19:52:23 2016  Kazuki Yamaguchi  <k@r...>
+
+	* 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@g...>.
+	  [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@r...>
 
 	* numeric.c: [DOC] fix rdoc directive, and an example of negative
Index: test/openssl/test_ocsp.rb
===================================================================
--- test/openssl/test_ocsp.rb	(revision 55421)
+++ test/openssl/test_ocsp.rb	(revision 55422)
@@ -86,14 +86,34 @@ class OpenSSL::TestOCSP < OpenSSL::TestC https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ocsp.rb#L86
     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::TestC https://github.com/ruby/ruby/blob/trunk/test/openssl/test_ocsp.rb#L129
     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)
Index: ext/openssl/ossl_ocsp.c
===================================================================
--- ext/openssl/ossl_ocsp.c	(revision 55421)
+++ ext/openssl/ossl_ocsp.c	(revision 55422)
@@ -312,39 +312,48 @@ ossl_ocspreq_get_certid(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ocsp.c#L312
 
 /*
  * 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
- *
- * Signs this OCSP request using +signer_cert+ and +signer_key+.
- * +certificates+ is an optional Array of certificates that may be included in
- * the request.
+ *   request.sign(cert, key, certs = nil, flags = 0, digest = nil) -> self
+ *
+ * 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) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ocsp.c#L808
 
 /*
  * 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;
 }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]