Issue #4421 has been updated by wolfgangw (Wolfgang Woehl).


MartinBosslet (Martin Bosslet) wrote:
> [...] and you need the latter instead of the former, let me know, I could also provide a code sample for that case.

Martin, I'd appreciate an example for the latter, yes, thanks in advance. In my code I need to reach public key digests which correspond to info embedded in X.509v3 certs' CNs (generated elsewhere, not with some ruby/openssl) and 1.9.3(-p125) breaks this.

Also I'm wondering: With 1.8.7-p352 and 1.9.2-p290 I can reproduce values computed by openssl 0.9.8k. With 1.9.3-p125 I cannot. So did openssl's default encoding change?

Here's what I'm doing:

$ openssl x509 -pubkey -noout -in x509v3.pem | openssl base64 -d | dd bs=1 skip=24 2> /dev/null | openssl sha1 -binary | openssl base64
NPq2kOXj9wUCE/Q/L+YSWm8Es9k=

$ irb
>> RUBY_VERSION 
=> "1.9.2"  
>> cert = OpenSSL::X509::Certificate.new( open 'x509v3.pem' )

=> #<OpenSSL::X509::Certificate subject=/O=example.org/OU=csc.example.org/CN=leaf/dnQualifier=NPq2kOXj9wUCE/Q/L+YSWm8Es9k=, issuer=/O=example.org/OU=csc.example.org/CN=intermediate/dnQualifier=7OTO2EEWPx8palhiTx1VZ1adrjE=, serial=7, not_before=2012-03-19 19:57:11 UTC, not_after=2022-03-15 19:57:11 UTC>

>> puts cert.public_key.to_pem
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA7YZMQoS91QPXD1lMbyJQlK7jPidOMZ2hCsuq6UaJQsIyqDuu3RkJ
3Byl2xayvFmt7NSAwUEQvaCC0hoUPASB9GJJ9G/nAk4kPP1vbSmnyEjeWe+deb+m
6BB9/4GvRnacoHYw2MoOXScqrLVBJ2JoNvSXcPjqxZ266bb8b0mznuDubGACOH8L
luATgTdomeBmh80hl+Kpb4mfFKoyNGoIQPSybwoFDzTxgDo1YHD/rUgCF8Djim9W
c+/Rllz5q+Fhxsz9VgxlY0E2yV6vdUML+n4fqK9QmM9Z0e9X5TOz5Ntj6lZFCjmE
Hot18W+HNhncghiPkfEMDwyldP+/797ruwIDAQAB
-----END RSA PUBLIC KEY-----
=> nil

>> asn1 = Base64.decode64( cert.public_key.to_pem.split( "\n" )[ 1 .. -2 ].join )
=> "0\x82\x01\n\x02\x82\x01\x01\x00\xED\x86LB\x84\xBD\xD5\x03\xD7\x0FYLo"P\x94\xAE\xE3>'N1\x9D\xA1\n\xCB\xAA\xE9F\x89B\xC22\xA8;\xAE\xDD\x19\t\xDC\x1C\xA5\xDB\x16\xB2\xBCY\xAD\xEC\xD4\x80\xC1A\x10\xBD\xA0\x82\xD2\x1A\x14<\x04\x81\xF4bI\xF4o\xE7\x02N$<\xFDom)\xA7\xC8H\xDEY\xEF\x9Dy\xBF\xA6\xE8\x10}\xFF\x81\xAFFv\x9C\xA0v0\xD8\xCA\x0E]'*\xAC\xB5A'bh6\xF4\x97p\xF8\xEA\xC5\x9D\xBA\xE9\xB6\xFCoI\xB3\x9E\xE0\xEEl`\x028\x7F\v\x96\xE0\x13\x817h\x99\xE0f\x87\xCD!\x97\xE2\xA9o\x89\x9F\x14\xAA24j\b@\xF4\xB2o\n\x05\x0F4\xF1\x80:5`p\xFF\xADH\x02\x17\xC0\xE3\x8AoVs\xEF\xD1\x96\\\xF9\xAB\xE1a\xC6\xCC\xFDV\fecA6\xC9^\xAFuC\v\xFA~\x1F\xA8\xAFP\x98\xCFY\xD1\xEFW\xE53\xB3\xE4\xDBc\xEAVE\n9\x84\x1E\x8Bu\xF1o\x876\x19\xDC\x82\x18\x8F\x91\xF1\f\x0F\f\xA5t\xFF\xBF\xEF\xDE\xEB\xBB\x02\x03\x01\x00\x01"

>> dnq_calc = Base64.encode64( OpenSSL::Digest.new( 'sha1', asn1 ).digest ).chomp
=> "NPq2kOXj9wUCE/Q/L+YSWm8Es9k="
>> exit

$ rbenv global 1.9.3-p125
$ irb      
>> RUBY_VERSION
=> "1.9.3"
>> cert = OpenSSL::X509::Certificate.new( open 'x509v3.pem' )

=> #<OpenSSL::X509::Certificate subject=/O=example.org/OU=csc.example.org/CN=leaf/dnQualifier=NPq2kOXj9wUCE/Q/L+YSWm8Es9k=, issuer=/O=example.org/OU=csc.example.org/CN=intermediate/dnQualifier=7OTO2EEWPx8palhiTx1VZ1adrjE=, serial=7, not_before=2012-03-19 19:57:11 UTC, not_after=2022-03-15 19:57:11 UTC>

>> puts cert.public_key.to_pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7YZMQoS91QPXD1lMbyJQ
lK7jPidOMZ2hCsuq6UaJQsIyqDuu3RkJ3Byl2xayvFmt7NSAwUEQvaCC0hoUPASB
9GJJ9G/nAk4kPP1vbSmnyEjeWe+deb+m6BB9/4GvRnacoHYw2MoOXScqrLVBJ2Jo
NvSXcPjqxZ266bb8b0mznuDubGACOH8LluATgTdomeBmh80hl+Kpb4mfFKoyNGoI
QPSybwoFDzTxgDo1YHD/rUgCF8Djim9Wc+/Rllz5q+Fhxsz9VgxlY0E2yV6vdUML
+n4fqK9QmM9Z0e9X5TOz5Ntj6lZFCjmEHot18W+HNhncghiPkfEMDwyldP+/797r
uwIDAQAB
-----END PUBLIC KEY-----
=> nil

>> asn1 = Base64.decode64( cert.public_key.to_pem.split( "\n" )[ 1 .. -2 ].join )
=> "0\x82\x01\"0\r\x06\t*\x86H\x86\xF7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0F\x000\x82\x01\n\x02\x82\x01\x01\x00\xED\x86LB\x84\xBD\xD5\x03\xD7\x0FYLo\"P\x94\xAE\xE3>'N1\x9D\xA1\n\xCB\xAA\xE9F\x89B\xC22\xA8;\xAE\xDD\x19\t\xDC\x1C\xA5\xDB\x16\xB2\xBCY\xAD\xEC\xD4\x80\xC1A\x10\xBD\xA0\x82\xD2\x1A\x14<\x04\x81\xF4bI\xF4o\xE7\x02N$<\xFDom)\xA7\xC8H\xDEY\xEF\x9Dy\xBF\xA6\xE8\x10}\xFF\x81\xAFFv\x9C\xA0v0\xD8\xCA\x0E]'*\xAC\xB5A'bh6\xF4\x97p\xF8\xEA\xC5\x9D\xBA\xE9\xB6\xFCoI\xB3\x9E\xE0\xEEl`\x028\x7F\v\x96\xE0\x13\x817h\x99\xE0f\x87\xCD!\x97\xE2\xA9o\x89\x9F\x14\xAA24j\b@\xF4\xB2o\n\x05\x0F4\xF1\x80:5`p\xFF\xADH\x02\x17\xC0\xE3\x8AoVs\xEF\xD1\x96\\\xF9\xAB\xE1a\xC6\xCC\xFDV\fecA6\xC9^\xAFuC\v\xFA~\x1F\xA8\xAFP\x98\xCFY\xD1\xEFW\xE53\xB3\xE4\xDBc\xEAVE\n9\x84\x1E\x8Bu\xF1o\x876\x19\xDC\x82\x18\x8F\x91\xF1\f\x0F\f\xA5t\xFF\xBF\xEF\xDE\xEB\xBB\x02\x03\x01\x00\x01"

>> dnq_calc = Base64.encode64( OpenSSL::Digest.new( 'sha1', asn1 ).digest ).chomp
=> "7pxBugGtDPy/CAbe8IDHuj4LUY4="

----------------------------------------
Bug #4421: [ext/openssl] Fix RSA public key encoding
https://bugs.ruby-lang.org/issues/4421#change-24953

Author: MartinBosslet (Martin Bosslet)
Status: Closed
Priority: Normal
Assignee: MartinBosslet (Martin Bosslet)
Category: ext
Target version: 1.9.3
ruby -v: -


=begin
 When calling RSA#to_der and RSA#to_pem on RSA public keys, they currently
 get encoded using i2d_RSAPublicKey and PEM_write_bio_RSAPublicKey. This encoding
 was specified in PKCS#1 and is specific to RSA. It is also not the default 
 encoding used by OpenSSL itself, which rather uses the generic format generated
 by i2d_RSA_PUBKEY and PEM_write_bio_RSA_PUBKEY. This format is the same that is
 used in a certificate's SubjectPublicKeyInfo, the advantage being that the format
 is generic and can be used to represent public keys of all kinds, including RSA,
 DSA and Elliptic Curve.
 
 The attached patch will make use of the generic format for encoding RSA keys. The
 change should not cause compatibility problems, since RSA#initialize uses several
 fallback scenarios that cover public keys of both formats.
 
 The fallbacks are also re-prioritized according to these changes.
 
 Regards,
 Martin
=end



-- 
http://bugs.ruby-lang.org/