2016-10-09 12 views
0

Rubyバインディングに影響を与えるOpenSSLの部分についての誤った決定のため、OCSP要求が署名されているかどうかを確認する唯一の方法は、警告をOpenSSL::OCSP::Request#verifyから解析することです。私は$stderrを傍受して警告を読んでいますが、複数のユニットテストでこのプロセスを繰り返すと、各傍受で新しいバッファが使用されても、最初のエラーメッセージが毎回キャプチャされます。

例として、私はこのスクリプト作成:関数呼び出しの順序を反転することによりtest.rb

#!/usr/bin/env ruby 

require 'openssl' 
require 'stringio' 

def main 
    if ARGV[0] 
    puts "signed: \n#{signed}" 
    puts "unsigned: \n#{unsigned}" 
    else 
    puts "unsigned: \n#{unsigned}" 
    puts "signed: \n#{signed}" 
    end 
end 

def unsigned 
    cert = OpenSSL::X509::Certificate.new 
    certid = OpenSSL::OCSP::CertificateId.new cert, cert 
    request = OpenSSL::OCSP::Request.new.add_certid certid 
    store = OpenSSL::X509::Store.new 

    capture_stderr { request.verify([], store) } 
end 

def signed 
    key = OpenSSL::PKey::RSA.generate(2048) 
    cert = OpenSSL::X509::Certificate.new 
    cert.public_key = key.public_key 
    cert.sign(key, OpenSSL::Digest::SHA1.new) 
    certid = OpenSSL::OCSP::CertificateId.new OpenSSL::X509::Certificate.new, cert 

    store = OpenSSL::X509::Store.new 
    store.add_cert cert 

    request = OpenSSL::OCSP::Request.new.add_certid certid 
    request.sign(cert, key) 

    capture_stderr { request.verify([], store) } 
end 

def capture_stderr 
    $stderr = StringIO.new 
    result = yield 
    [result, $stderr.string] 
ensure 
    $stderr = STDERR 
end 

# try `./test.rb` and `./test.rb 1` 
main 

を、私は異なる結果が得られます。

$ ./test.rb 
unsigned: 
[false, "./test.rb:22: warning: error:27074080:OCSP routines:OCSP_request_verify:request not signed\n"] 
signed: 
[false, "./test.rb:38: warning: error:27074080:OCSP routines:OCSP_request_verify:request not signed\n"] 

$ ./test.rb 1 
signed: 
[false, "./test.rb:38: warning: error:27074065:OCSP routines:OCSP_request_verify:certificate verify error\n"] 
unsigned: 
[false, "./test.rb:22: warning: error:27074065:OCSP routines:OCSP_request_verify:certificate verify error\n"] 

私はこの奇妙な振る舞いについての説明は、おそらくルビーSTDLIBコードベースのC言語の一部に入ることを想像してみてください。

+0

* "OCSPリクエストが署名されているかどうかを確認する唯一の方法は、OpenSSL :: OCSP :: Request#verify"からの警告を解析することです。* - 私の無知を許してください。 OCSPは '/apps/ocsp.c'にあります。ライブラリから任意のコードを持ち上げたり再利用したりすることができます。短期間の来ることは、あなたが必要とするものを提供することができないというRubyのようです。 OpenSSLはバインディングを提供しません。これらはPython、Ruby、PHPなどで提供されています。あなたが必要とするものを得るために、Rubyに対するバグ報告を提出するべきでしょう。 – jww

+0

うーん...前に見たことがなかった。しかし、 'OCSP_request_verify'の使用法はありません。応答のみが検証されます。アプリケーションの部分でも利用できない場合は、OpenSSLの作成者は、リクエストがどこから来ているかを確認することは意味がないと考えているというかなり強いメッセージだと思います。たぶん、私がこれをやっている理由(そしてOCSP RFCがSigRequiredステータスを定義する理由)を再考する必要があるかもしれません。 – Ben

+0

警告メッセージまたはエラーメッセージがOpenSSLからのものである場合、コードを解除することができます。 OpenSSLは 'OCSP_verify'、' OCSP_BASICRESP_verify'、 'OCSP_REQUEST_verify'のような機能を提供します。多分、Rubyはそれを公開する必要があります。私の言葉をそれに服用しないでください... 'cd 'それから 'grep -IR 'OCSP _ *。* verify' *'を実行してください。 – jww

答えて

0

これはRubyのOpenSSLライブラリのバグであることが判明しました。 Gemバージョン2.0.0-beta2で修正されました:https://github.com/ruby/openssl/commit/9af69abcec15b114d9a0ec3811983fc1d7b5a1dc

OpenSSLメッセージがstderrに繰り返しリークすることはありません。ただし、信頼できない署名と署名の不一致を区別することは現在不可能です。ありがたいことに、私は前に間違っていたし、検証は実際に署名の欠落で失敗する。

関連する問題