Giter Site home page Giter Site logo

OpenSSL 3 FIPS mode - creating encrypted RSA key pair fails with PEM_write_bio_PrivateKey_traditional: initialization error (OpenSSL::PKey::PKeyError) about openssl HOT 7 CLOSED

tarnowsc avatar tarnowsc commented on June 12, 2024
OpenSSL 3 FIPS mode - creating encrypted RSA key pair fails with PEM_write_bio_PrivateKey_traditional: initialization error (OpenSSL::PKey::PKeyError)

from openssl.

Comments (7)

rhenium avatar rhenium commented on June 12, 2024 1

#645 updates the RDoc for exporting PKeys.

from openssl.

tarnowsc avatar tarnowsc commented on June 12, 2024 1

yes, thanks for your support, the output of those two commands is not exactly identical, but it should do the trick:

irb(main):007:0> key_secure = key.export cipher, pass_phrase
=> "-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,B52746B87D40786BA0D8DC738CEF2072\n\ni/oWxCNgdtv7MutETCgnVSq6ZZSuYB8cnnJUa31Vx5DqGqegxLNcDxlEWka4ZOiO\nTnDYWE5RZJgSzJCdKCi+ZxneTklXxCfXIe4N1uiOgvNUXIRAgThBoUD...
irb(main):008:0> 
irb(main):009:0> key_secure = key.private_to_pem cipher, pass_phrase
=> "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIFuomdujf3bACAggA\nMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDQ92vVYiciFltnl5o33sxvBIIE\n0EX2XuxV7CuTSPN56kSSJ5XRkoOtsyNSIKY0/dzgqRwl+uKJn2aN52QIvjbh74Tw\...

from openssl.

junaruga avatar junaruga commented on June 12, 2024

I was reproduce this issue on the current master branch < 97fb410> with OpenSSL 3.0.9 FIPS built from the source.

The reproducing steps:

Install the OpenSSL seeing the Documents - How to debug Ruby OpenSSL binding.

Check the enabled FIPS and fips and base providers by this testing program.

$ LD_LIBRARY_PATH=${HOME}/.local/openssl-3.0.9-fips-debug/lib/ \
  OPENSSL_CONF=/home/jaruga/.local/openssl-3.0.9-fips-debug/ssl/openssl_fips.cnf \
  ./fips_mode
Loaded providers:
  fips
  base
FIPS mode enabled: 1
$ ruby -v
ruby 3.3.0dev (2023-05-30T12:39:26Z master 30b960ba34) [x86_64-linux]

bundle install --standalone

Compile

$ MAKEFLAGS="V=1" \
  RUBY_OPENSSL_EXTCFLAGS="-O0 -g3 -ggdb3 -gdwarf-5" \
  bundle exec rake compile -- \
  --enable-debug \
  --with-openssl-dir=$HOME/.local/openssl-3.0.9-fips-debug

Check the compiled Ruby binding is linked to the OpenSSL 3.0.9, and FIPS is enabled.

$ ldd lib/openssl.so 
	linux-vdso.so.1 (0x00007ffc551b0000)
	libruby.so.3.3 => /home/jaruga/.local/ruby-30b960ba34-debug/lib/libruby.so.3.3 (0x00007f59b7800000)
	libssl.so.3 => /home/jaruga/.local/openssl-3.0.9-fips-debug/lib/libssl.so.3 (0x00007f59b7eae000)
	libcrypto.so.3 => /home/jaruga/.local/openssl-3.0.9-fips-debug/lib/libcrypto.so.3 (0x00007f59b7200000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f59b7db5000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f59b7022000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f59b77e6000)
	libgmp.so.10 => /lib64/libgmp.so.10 (0x00007f59b7741000)
	libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f59b7708000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f59b6ffe000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f59b7ff7000)

$ bundle exec rake debug
/home/jaruga/.local/ruby-30b960ba34-debug/bin/ruby -I./lib -ropenssl -ve'puts OpenSSL::OPENSSL_VERSION, OpenSSL::OPENSSL_LIBRARY_VERSION'
ruby 3.3.0dev (2023-05-30T12:39:26Z master 30b960ba34) [x86_64-linux]
OpenSSL 3.0.9 30 May 2023
OpenSSL 3.0.9 30 May 2023

$ OPENSSL_CONF=${HOME}/.local/openssl-3.0.9-fips-debug/ssl/openssl_fips.cnf \
  bundle exec ruby -I ./lib -e 'require "openssl"; p OpenSSL.fips_mode'
true

Here is your script.

$ cat test.rb 
require 'openssl'

key = OpenSSL::PKey::RSA.new 2048
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
pass_phrase = 'my secure pass phrase goes here'

key_secure = key.export cipher, pass_phrase

Your reproducing script fails on FIPS as reported.

$ OPENSSL_CONF=${HOME}/.local/openssl-3.0.9-fips-debug/ssl/openssl_fips.cnf \
  bundle exec ruby -I ./lib test.rb
test.rb:7:in `export': PEM_write_bio_PrivateKey_traditional: initialization error (OpenSSL::PKey::PKeyError)
  from test.rb:7:in `<main>'

Your script succeeds as reported.

$ bundle exec ruby -I ./lib test.rb

$ echo $?
0

from openssl.

rhenium avatar rhenium commented on June 12, 2024

I think this might be unfixable. OpenSSL's traditional PEM encryption format uses MD5 to derive encryption keys from the password, but MD5 is prohibited under the FIPS mode, hence it fails.

We should document this. There is also room for improvement in the exception message. Running the code with OpenSSL.debug = true shows more information:

t643.rb:9: warning: error on stack: error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported (Global default library context, Algorithm (MD5 : 100), Properties ())
t643.rb:9: warning: error on stack: error:03000086:digital envelope routines:evp_md_init_internal:initialization error (Global default library context, Algorithm (MD5 : 100), Properties ())

from openssl.

junaruga avatar junaruga commented on June 12, 2024

@rhenium Thanks for the info. In that case, I think we can improve the logic to print the error message to tell users the reason with a better error message, and I think that can be a solution to close this issue ticket.

As a note OpenSSL 3.0 FIPS supports FIPS 140-2, and OpenSSL 3.1 FIPS supports FIPS 140-3. I learned it recently. :)

We should document this. There is also room for improvement in the exception message. Running the code with OpenSSL.debug = true shows more information:

Those are nice tips. For another improvement, perhaps, we might be able to create an issue template for this repository, adding the info as a reporting way.

from openssl.

junaruga avatar junaruga commented on June 12, 2024

I plan to list up all the supported encryptions in Ruby OpenSSL binding, then to compare the specification with OpenSSL 3.0 FIPS (FIPS 140-2) and OpenSSL 3.1 FIPS (FIPS 140-3) manually to decide how to implement.

from openssl.

junaruga avatar junaruga commented on June 12, 2024

@tarnowsc I suppose that the following code with OpenSSL::PKey::RSA#private_to_pem is a right way to achieve what you want to do.

key_secure = key.private_to_pem cipher, pass_phrase

instead of the following code.

key_secure = key.export cipher, pass_phrase

The #645 is to explain the details.

from openssl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.