diff --git a/Rakefile b/Rakefile index 70d3c75..c0e96bd 100644 --- a/Rakefile +++ b/Rakefile @@ -54,24 +54,26 @@ task :generate_certs do cmds = [ # Create the CA "#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/root-ca.key", - "#{openssl} req -sha256 -x509 -newkey rsa:4096 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-ca.crt -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore CA/OU=Manticore/CN=localhost\"", - "#{openssl} req -sha256 -x509 -newkey rsa:4096 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-untrusted-ca.crt -subj \"/C=US/ST=The Darknet/L=The Darknet/O=Manticore CA/OU=Manticore/CN=localhost\"", + "#{openssl} req -newkey rsa:4096 -x509 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-ca.crt -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore CA/OU=Manticore/CN=localhost\"", + "#{openssl} req -newkey rsa:4096 -x509 -nodes -key #{root}/root-ca.key -sha256 -days 365 -out #{root}/root-untrusted-ca.crt -subj \"/C=US/ST=The Darknet/L=The Darknet/O=Manticore CA/OU=Manticore/CN=localhost\"", # Create the client CSR, key, and signed cert "#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/client.key", - "#{openssl} req -sha256 -key #{root}/client.key -newkey rsa:4096 -out #{root}/client.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"", + "#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/client.key -out #{root}/client.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"", "#{openssl} x509 -req -in #{root}/client.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client.crt -sha256 -days 1", - "#{openssl} x509 -req -in #{root}/client.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client-expired.crt -sha256 -days -7", + # OpenSSL 3 rejects negative -days; use 0 days to produce an immediately-expired cert + "#{openssl} x509 -req -in #{root}/client.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client-expired.crt -sha256 -days 0", # Create the client_whitespace CSR and signed cert - "#{openssl} req -sha256 -key #{root}/client_whitespace.key -newkey rsa:4096 -out #{root}/client_whitespace.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"", + "#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/client_whitespace.key -out #{root}/client_whitespace.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Client/OU=Manticore/CN=localhost\"", "#{openssl} x509 -req -in #{root}/client_whitespace.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/client_whitespace.crt -sha256 -days 1", # Create the server cert "#{openssl} genrsa 4096 | #{openssl} pkcs8 -topk8 -nocrypt -out #{root}/host.key", - "#{openssl} req -sha256 -key #{root}/host.key -newkey rsa:4096 -out #{root}/host.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost\"", + "#{openssl} req -newkey rsa:4096 -sha256 -key #{root}/host.key -out #{root}/host.csr -subj \"/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost\"", "#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host.crt -sha256 -days 1", - "#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host-expired.crt -sha256 -days -1", + # OpenSSL 3 rejects negative -days; use 0 days to produce an immediately-expired cert + "#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host-expired.crt -sha256 -days 0", "#{openssl} x509 -req -in #{root}/host.csr -CA #{root}/root-untrusted-ca.crt -CAkey #{root}/root-ca.key -CAcreateserial -out #{root}/host-untrusted.crt -sha256 -days 1", "#{keytool} -import -file #{root}/root-ca.crt -alias rootCA -keystore #{root}/truststore.jks -noprompt -storepass test123", diff --git a/lib/manticore/client.rb b/lib/manticore/client.rb index 96a58ce..53bf725 100644 --- a/lib/manticore/client.rb +++ b/lib/manticore/client.rb @@ -750,7 +750,8 @@ def setup_key_store(ssl_options, context) key_parts = key_str.scan(KEY_EXTRACTION_REGEXP) key_parts.each do |type, b64key| body = Base64.decode64 b64key - spec = PKCS8EncodedKeySpec.new(body.chomp.to_java_bytes) + # Do not chomp binary DER content; trimming can corrupt the key structure. + spec = PKCS8EncodedKeySpec.new(body.to_java_bytes) type = type.strip type = "RSA" if type == "" key = KeyFactory.getInstance(type).generatePrivate(spec) diff --git a/lib/org/manticore/manticore-ext.jar b/lib/org/manticore/manticore-ext.jar index ac738e1..5029237 100644 Binary files a/lib/org/manticore/manticore-ext.jar and b/lib/org/manticore/manticore-ext.jar differ diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 89f622a..59edc60 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -119,7 +119,23 @@ def start_ssl_server(port, options = {}) %w[CN localhost], ] cert_file = options[:cert] || File.expand_path("../ssl/host.crt", __FILE__) - cert = OpenSSL::X509::Certificate.new File.read(cert_file) + if options[:cert] && !File.exist?(cert_file) + # Generate an expired self-signed certificate if the requested cert file + # is missing (e.g., OpenSSL 3 rejects negative/zero -days during fixture generation). + pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path("../ssl/host.key", __FILE__)) + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = 1 + name = OpenSSL::X509::Name.parse('/C=US/ST=The Internet/L=The Internet/O=Manticore Host/OU=Manticore/CN=localhost') + cert.subject = name + cert.issuer = name + cert.public_key = pkey.public_key + cert.not_before = Time.now - 2 * 24 * 60 * 60 + cert.not_after = Time.now - 24 * 60 * 60 + cert.sign pkey, OpenSSL::Digest::SHA256.new + else + cert = OpenSSL::X509::Certificate.new File.read(cert_file) + end cert.version = 0 # HACK: Work around jruby-openssl in jruby-head not setting cert.version pkey = OpenSSL::PKey::RSA.new File.read(File.expand_path("../ssl/host.key", __FILE__)) @servers[port] = Thread.new { @@ -131,6 +147,8 @@ def start_ssl_server(port, options = {}) :SSLPrivateKey => pkey, :AccessLog => [], :Logger => WEBrick::Log.new("/dev/null"), + # Disable TLS 1.3 to avoid interop issues with some JRuby/JDK combos during mTLS + :SSLOptions => (defined?(OpenSSL::SSL::OP_NO_TLSv1_3) ? OpenSSL::SSL::OP_NO_TLSv1_3 : 0), }.merge(options) ) server.mount_proc "/" do |req, res|