I have generated a certificate for apache with
openssl ca -config openssl.conf -extensions usr_cert -in reqs/httpd.req -out httpd.pem -startdate 170226000000Z -enddate 180226000000Z -noemailDN
This certificate is accepted by openssl, chrome, git etc. but not by firefox which rejects it with:
xxx uses an invalid security certificate.
The certificate will not be valid until 26.02.2017 01:00.
The current time is 26.02.2017 11:49. Error code: SEC_ERROR_INVALID_TIME
This seems to have something to do with the encoding of the notBefore and notAfter fields (https://bugzilla.mozilla.org/show_bug.cgi?id=1152515) but I've been unable to find any hints to on how to fix this but this really helpful
Re-generate the certificate with valid encodings for time fields
(https://developer.mozilla.org/en-US/docs/Mozilla/Security/x509_Certificates)
Any advice / hints appreciated!
Related
I try to use curl on Windows to post a timestamp request. Authentication is needed, so I use p12 file. I get error message, but password of p12 file is correct.
Command:
curl --insecure --cert-type P12 --cert my.p12:mypassword -X POST -d #mytest.req <myTSURL>
Error message:
curl: (58) could not parse PKCS12 file, check password, OpenSSL error
error:0308010C:digital envelope routines::unsupported
curl -V
curl 7.83.1 (x86_64-pc-win32) libcurl/7.83.1 OpenSSL/3.0.2 (Schannel) zlib/1.2.12 brotli/1.0.9 libidn2/2.3.2 libssh2/1.10.0 nghttp2/1.47.0 ngtcp2/0.5.0 nghttp3/0.4.1 libgsasl/1.10.0
Release-Date: 2022-05-11
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli gsasl HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI TLS-SRP UnixSocket
Meta: this isn't really programming or development, and would probably be better on superuser or maybe security.SX, but this is issue is likely to become more common as OpenSSL 3.0 spreads and I wanted to get the answer out.
OpenSSL 3.0.x by default doesn't support old/insecure algorithms, but until recently most software that creates PKCS12 (including OpenSSL 1.x.x) used such an algorithm for the certbag(s), namely a PKCS12-defined PBE using 40-bit RC2, usually abbreviated RC2-40 -- and some still does at least sometimes, like the Windows 10 cert-export dialog by default. To check this do
openssl pkcs12 -in my.p12 -info -nokeys -nocerts
# in 3.0.x add -provider legacy or just -legacy
# to avoid prompt use -password or -passin, see man pages
and I expect the output will include
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
See if your curl has an option to specify the OpenSSL 3.0.x provider and if so specify 'legacy'. Otherwise, convert your pkcs12 like (editted)
# 3.0.x
openssl pkcs12 -in old -nodes -provider legacy >temp && <temp openssl pkcs12 -export -out new
# or slightly simpler
openssl pkcs12 -in old -nodes -legacy >temp && <temp openssl pkcs12 -export -out new
# 1.x.x
openssl pkcs12 -in old -nodes >temp && <temp openssl pkcs12 -export -descert -out new
# and in either case securely delete temp; on systems with a memory tmpfs,
# typically /tmp, putting the file there can help assure this
# IFF 'old' was created by software that put the keybag before the certbag,
# which you can infer from the order displayed by pkcs12 -info,
# you can skip the temp file and pipe directly from one openssl to the other
Conversion loses any 'friendlyname' set in the existing file. For curl, and probably most other programs, this doesn't matter, but if you want to use this same file with something where friendlyname does matter, add -name $name on the -export part.
I was getting the same error using OpenVPN. I was able to fix it by adding or uncommenting the following lines in the /etc/ssl/openssl.cnf configuration file:
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1
This is based on the information at OpenSSL WIKI
In macOS I want to connect to the server using openssl.
With the command
openssl s_client -connect ipaddress:port -cert path.crt -key path.key.pem
Shows CONNECTED but throws
Verify return code:19 ( self signed certificate in certificate chain)
I guess the error is because of missing CA.
To refer to the path of the chain certificate in my case its (chain.cert.pem) which is created by combining Root certificate(ca.cert.pem.crt) and Intermediate certificate(ca.cert.pem.crt).
I tested adding the chain certificate as
openssl s_client -connect ipaddress:port -CAfile \path\chain.cert.pem -cert path.crt -key path.key.pem
Here I get error as invalid arguments.Looks like I am not adding the CAfile correctly
How do we refer to the chain certificate in macOS
Assuming that the error thrown is because of the missing CA how to add or refer to the chain certificate
Please provide your suggestions so that I can try out connecting with the server.
Got an alert on server that the certificate is going to expire. I click the "renew" button and it says Unknown Error. So I dig deeper and run the following on the command line
sudo /Applications/Server.app/Contents/ServerRoot/usr/sbin/certadmin --recreate-CA-signed-certificate "macserver.local Code Signing Certificate" "IntermediateCA_MACSERVER.LOCAL_1" dd3d0ec3
to which i got the following error:
/Applications/Server.app/Contents/ServerRoot/usr/sbin/certadmin --recreate-CA-signed-certificate: Unable to renew identity 'macserver.local Code Signing Certificate': unable to renew certificate: could not find original certificate 'macserver.local Code Signing Certificate' with serial number 'dd3d0ec3' issued by 'IntermediateCA_MACSERVER.LOCAL_1' (-25300)
So I run the following to search the certificate and it does find it:
sudo security find-certificate -c "macserver.local Code Signing Certificate"
keychain: "/Library/Keychains/System.keychain"
class: 0x80001000
attributes:
"alis"<blob>="macserver.local Code Signing Certificate"
"cenc"<uint32>=0x00000003
"ctyp"<uint32>=0x00000001
"hpky"<blob>=0xA14502C168EB2D717615AA60535926B760804C8F "\241E\002\301h\353-qv\025\252`SY&\267`\200L\217"
"issu"<blob>=0x308193312A302806035504030C21496E7465726D65646961746543415F46494C455345525645522E4C4F43414C5F3131123010060355040A0C09727472616374696F6E312D302B060355040B0C244D41434F5358204F70656E4469726563746F727920496E7465726D6564696174652043413122302006092A864886F70D010901161361646D696E40727472616374696F6E2E636F6D "0\201\2231*0(\006\003U\004\003\014!IntermediateCA_MACSERVER.LOCAL_11\0220\020\006\003U\004\012\014\011macserver1-0+\006\003U\004\013\014$MACOSX OpenDirectory Intermediate CA1"0 \006\011*\206H\206\367\015\001\011\001\026\023mymacserver#gmail.com"
"labl"<blob>="macserver.local Code Signing Certificate"
"skid"<blob>=<NULL>
"snbr"<blob>=0x00DD3D0EC3 "\000\335=\016\303"
"subj"<blob>=0x30553132303006035504030C2966696C657365727665722E6C6F63616C20436F6465205369676E696E6720436572746966696361746531123010060355040A0C09727472616374696F6E310B3009060355040613025553 "0U1200\006\003U\004\003\014)macserver.local Code Signing Certificate1\0220\020\006\003U\004\012\014\011macserver1\0130\011\006\003U\004\006\023\002US"
Anyone have any ideas on this?
I've solved this problem for my cert. Instead of using hexadecimal, i use decimal. So in your case the serial number should be 3711766211 in decimal.
Hope this will help you too.
Thanks
I'm trying to add all the pem and crt files in /etc/pki/tls/certs to an OpenSSL::X509::Store with this code:
require 'openssl'
store = OpenSSL::X509::Store.new
Dir.glob('/etc/pki/tls/certs/*.{pem,crt}') do |cert_path|
puts cert_path
cert = OpenSSL::X509::Certificate.new(IO.read(cert_path))
store.add_cert(cert)
end
And when it gets to /etc/pki/tls/certs/ca-bundle.trust.crt the OpenSSL::X509::Certificate.new raises this error:
cert_test.rb:6:in `initialize': nested asn1 error (OpenSSL::X509::CertificateError)
from cert_test.rb:6:in `new'
from cert_test.rb:6:in `block in <main>'
from cert_test.rb:4:in `glob'
from cert_test.rb:4:in `<main>'
Anyone know what that ca-bundle.trust.crt is or why ruby's openssl can't read it?
For what it's worth, I don't get any errors when I run:
openssl x509 -text -in /etc/pki/tls/certs/ca-bundle.trust.crt
It is a bundle of "Trusted Certificates".
The x509 man page talks about them some.
TRUST SETTINGS
Please note these options are currently experimental and may well change.
A trusted certificate is an ordinary certificate which has several additional pieces of information attached to it such as the permitted and prohibited uses of the certificate and an "alias".
Normally when a certificate is being verified at least one certificate must be "trusted". By default a trusted certificate must be stored locally and must be a root CA: any certificate chain ending in this CA is then usable for any purpose.
Trust settings currently are only used with a root CA. They allow a finer control over the purposes the root CA can be used for. For example a CA may be trusted for SSL client but not SSL server use.
See the description of the verify utility for more information on the meaning of trust settings.
Future versions of OpenSSL will recognize trust settings on any certificate: not just root CAs.
and
The PEM format uses the header and footer lines:
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
it will also handle files containing:
-----BEGIN X509 CERTIFICATE-----
-----END X509 CERTIFICATE-----
Trusted certificates have the lines
-----BEGIN TRUSTED CERTIFICATE-----
-----END TRUSTED CERTIFICATE-----
I am just trying to get my head around SSL.
I have set up a Jetty server on my localhost, and generated my own certificate using Keytool.
Now when I go to https://localhost:8443/ I get the can't trust this certificate error.
I use
keytool -export -alias pongus -keystore keystore -file certfile.cer
To create the certificate which I think is what the client needs to authenticate with the server. (This is where I could be very wrong!)
I have the following ruby code :
require 'net/https'
require 'openssl'
require 'open-uri'
puts 'yay' if File.exists?('certfile.cer')
uri = URI.parse("https://localhost:8443/")
http_session = Net::HTTP.new(uri.host, uri.port)
http_session.use_ssl = true
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER
http_session.ca_file = 'certfile.cer'
res = http_session.start do |http|
# do some requests here
http.get('/')
end
This does print 'yay', so the certfile.cer file does exist.
But I get the errors
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586 warning: can't set verify locations
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)
Any ideas what I am doing wrong?
EDIT
I want to get it so I guarantee that I am connecting to the right server, and the server can guarantee that it is me connecting to it, without any tampering in between. I am developing both the server and the client.
Your client needs access to its
private key.
You dont need the private key for server certificate verification. All you need is the certificate itself which contains the public key. Only the server has the private key. Well described here http://www.helpbytes.co.uk/https.php and here http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/
My recommendation is simple. Check your certificate is correct.
openssl x509 -text -in mycert.crt
Also if you have access to the server you can explicitely validate if the certificate and key (used in httpd configuration) are correct (matches): http://kb.wisc.edu/middleware/page.php?id=4064 Please note this is explicit check ran on server. Never give out the private key. This check can be done only by the administrator to verify if the httpd was not misconfigured.
(openssl x509 -noout -modulus -in server.pem | openssl md5 ;\
openssl rsa -noout -modulus -in server.key | openssl md5) | uniq
You can also debug the SSL certificate communication using standard openssl command. Issue this command then wait few seconds and then type QUIT and hit enter. You will see the certificate the server sends out.
openssl s_client -connect your.server.com:443
Also try to import the certificate to your browser and access the URL resource. Browser is able to validate it by clicking on https (Firefox and Chrome). Then you will see the certificate itself and validity information.
All the above was all about the server certificate. This is only one part of the problem. "I am connecting to the right server, and the server can guarantee that it is me connecting to it" Actully in your code above you only check for the server cert. Now. If you want a client certificate (the second part of your statement) than you need this in Ruby:
File.open( "client_certificate.pem", 'rb' ) { |f| cert = f.read }
File.open( "client_key.pem", 'rb' ) { |f| key = f.read }
http_session.cert = OpenSSL::X509::Certificate.new(cert)
http_session.key = OpenSSL::PKey::RSA.new(key, nil)
This is how client cert should be used in Ruby. If your private key is encrypted with a password just pass it instead nil in the second argument of RSA constructor.
I highly recommend to get server certificate working (your code) and then start with client certificate. Please note you keep your current code (ca_cert, validation constant) and add the above four lines to it.
Hope this helps.
Your client needs access to its private key. The private key is not in the certificate, the certificate only contains the public key. Sorry, I don't know ruby, but a common technique is to bundle the private key and certificate in a single PKCS#12, aka p12, file and supply this to the crypto library.
Change
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER
to
http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
Once you do that, the SSL will work properly. I have used this multiple times in my development environments, always works flawlessly.