From: Justin Peal Date: 2012-03-08T14:34:25+09:00 Subject: [ruby-core:43130] [ruby-trunk - Bug #6122] OpenSSL::PKCS7 verify Issue #6122 has been updated by Justin Peal. # not_after can not later than 2038-01-19 11:14:07 require 'OpenSSL' class Rsa attr_reader :key, :cert @@sha = OpenSSL::Digest::SHA1.new @@aes = OpenSSL::Cipher.new("aes-128-ofb") def initialize serial, issuer=nil @key = OpenSSL::PKey::RSA.new(1024) @cert = OpenSSL::X509::Certificate.new @cert.version = 2 # RFC 5280 - v3 @cert.serial = serial @cert.subject = OpenSSL::X509::Name.parse "CN=#{serial}" @cert.issuer = issuer==nil ? @cert.subject : issuer @cert.public_key = @key.public_key @cert.not_before = Time.now @cert.not_after = Time.mktime(2038, 1, 19, 11, 14, 7) # second = 8 ==> Fail! @cert.sign(@key, @@sha) if issuer==nil end def sign key @cert.sign(key, @@sha) end def sign_encrypt(plain, obj_cert) signed = OpenSSL::PKCS7::sign(@cert, @key, plain) encrypted = OpenSSL::PKCS7::encrypt([obj_cert], signed.to_s, @@aes) end def decrypt_verify(received, obj_cert, ca_cert) encrypted = OpenSSL::PKCS7.new(received) decrypted = encrypted.decrypt(@key, @cert) signed = OpenSSL::PKCS7.new(decrypted) cert_store = OpenSSL::X509::Store.new.add_cert(ca_cert) plain = signed.data if signed.verify([obj_cert], cert_store, nil, OpenSSL::PKCS7::NOINTERN | OpenSSL::PKCS7::NOCHAIN) end end ca = Rsa.new(1) alice = Rsa.new(11, ca.cert.issuer) alice.sign ca.key right = Rsa.new(12, ca.cert.issuer) right.sign ca.key fa = Rsa.new(3) wrong = Rsa.new(33, fa.cert.issuer) wrong.sign fa.key plain = "Something's wrong." signed_encrypted = right.sign_encrypt(plain, alice.cert) recovered = alice.decrypt_verify(signed_encrypted, right.cert, ca.cert) puts recovered==plain ? "It's okay!" : recovered; recovered = alice.decrypt_verify(signed_encrypted, wrong.cert, ca.cert) # wrong should be right puts recovered!=plain ? "It's okay!" : recovered; ---------------------------------------- Bug #6122: OpenSSL::PKCS7 verify https://bugs.ruby-lang.org/issues/6122 Author: Justin Peal Status: Open Priority: High Assignee: Category: Target version: ruby -v: ruby 1.9.3p125 (2012-02-16) [i386-mingw32] # not_after can not later than 2038-01-19 11:14:07 # verify can pass wrong certificate require 'OpenSSL' class Rsa attr_reader :key, :cert @@sha = OpenSSL::Digest::SHA1.new @@aes = OpenSSL::Cipher.new("aes-128-ofb") def initialize serial, issuer=nil @key = OpenSSL::PKey::RSA.new(1024) @cert = OpenSSL::X509::Certificate.new @cert.version = 2 # RFC 5280 - v3 @cert.serial = serial @cert.subject = OpenSSL::X509::Name.parse "CN=#{serial}" @cert.issuer = issuer==nil ? @cert.subject : issuer @cert.public_key = @key.public_key @cert.not_before = Time.now @cert.not_after = Time.mktime(2038, 1, 19, 11, 14, 7) # second = 8 ==> Fail! @cert.sign(@key, @@sha) if issuer==nil end def sign key @cert.sign(key, @@sha) end def sign_encrypt(plain, obj_cert) signed = OpenSSL::PKCS7::sign(@cert, @key, plain) encrypted = OpenSSL::PKCS7::encrypt([obj_cert], signed.to_s, @@aes) end def decrypt_verify(received, obj_cert, ca_cert) encrypted = OpenSSL::PKCS7.new(received) decrypted = encrypted.decrypt(@key, @cert) signed = OpenSSL::PKCS7.new(decrypted) cert_store = OpenSSL::X509::Store.new.add_cert(ca_cert) plain = signed.data if signed.verify([obj_cert], cert_store) end end ca = Rsa.new(1) alice = Rsa.new(11, ca.cert.issuer) alice.sign ca.key right = Rsa.new(12, ca.cert.issuer) right.sign ca.key fa = Rsa.new(3) wrong = Rsa.new(33, fa.cert.issuer) # wrong.sign fa.key # Don't sign indeed! plain = "Something's wrong." signed_encrypted = right.sign_encrypt(plain, alice.cert) recovered = alice.decrypt_verify(signed_encrypted, wrong.cert, ca.cert) # wrong should be right puts recovered==plain ? recovered : "It's okay!" -- http://bugs.ruby-lang.org/