How does the browser deal with missing intermediate certs - ssl

I've come across the site https://alpower.com, this site is only providing its own site certificate. Because of this I can't access the site properly with cURL as the cacerts used are only root certsificates.
The site is accessible in Firefox however. How exactly is Firefox able to verify the site's identity where as cURL isn't?

Browsers will cache intermediate certificates. So if the missing certificate was already provided by another site the browser will have it already and will use it. But, if you use a fresh browser profile you might get the same problems as you get with curl, because the intermediate certificate is not cached.
This is at least how it works with Firefox. Other browsers might look into the Authority Information Access section of the certificate and if they find the URL issuer certificate they will download the certificate to continue with the chain verification.

Most browsers are using the AIA information embedded in the certificate (see comment on browsers exceptions).
To expose the URL of the CA Issuer with openssl:
openssl x509 -in "YOUR_CERT.pem" -noout -text
There is a section Authority Information Access with CA Issuers - URI which would be the "parent" certificate (intermediate or root certificate).
This can be reproduced up to the root CA.
In a gist:
ssl_endpoint=<ENDPOINT:443>
# first, get the endpoint cert
echo | openssl s_client -showcerts -connect $ssl_endpoint 2>/dev/null | openssl x509 -outform PEM > endpoint.cert.pem
# then extract the intermediate cert URI
intermediate_cert_uri=$(openssl x509 -in endpoint.cert.pem -noout -text | (grep 'CA Issuers - URI:' | cut -d':' -f2-))
# and get the intermediate cert (convert it from DER to PEM)
curl -s "${intermediate_cert_uri}" | openssl x509 -outform PEM -inform DER > intermediate.cert.pem

Related

Generate CRT & KEY ssl files from Let's Encrypt from scratch

I'd like to generate a CRT/KEY couple SSL files with Let's Encrypt (with manual challenge).
I'm trying something like this :
certbot certonly --manual -d mydomain.com
But I only get these files in my /etc/letsencrypt/live/mydomain.com folder :
cert.pem
chain.pem
fullchain.pem
privkey.pem
Did I missed something?
I'm the author of Greenlock, a certbot-compatible Let's Encrypt v2 client, so I've had to learn the ins and outs of all these things as well.
Hopefully this helps:
KEY
privkey.pem is the "key" file
Sometimes it is improperly named as cert.key or example.com.key.
CRT
fullchain.pem is your "crt" file.
Sometimes it is improperly named as example.com.crt.
CRT/KEY Bundle
bundle.pem would be made like so: cat fullchain.pem privkey.pem > bundle.pem
HAProxy is the only server that I know of that uses bundle.pem.
cert.pem
cert.pem contains ONLY your certificate, which can only be used by itself if the browser already has the certificate which signed it, which may work in testing (which makes it seem like it may be the right file), but will actually fail for many of your users in production with a security error of untrusted certificate.
However, you don't generally use the cert.pem by itself. It's almost always coupled with chain.pem as fullchain.pem.
chain.pem
chain.pem is the intermediary signed authority, signed by the root authority - which is what all browsers are guaranteed to have in their pre-built cache.
Checking certs
You can inspect the cert only like so:
openssl x509 -in cert.pem -text -noout
There's a list of useful commands here:
https://www.sslshopper.com/article-most-common-openssl-commands.html

How to give CRL to openssl s_client?

I'm testing certificate revocation with a test server. I'm trying to use openssl s_client with crl_check parameter for testing the revocation. I have appended ca certs to a chain file I give in CAfile parameter.
With the command:
openssl s_client -connect <host>:<port> -crl_check -cert cert.pem \
-key key.pem -CAfile ca_chain.pem -state -verify_return_error debug
I get a response:
Verify return code: 3 (unable to get certificate CRL)
Which is natural because I don't give the CRL.
How should I give the CRL (where the server cert is revoked) to the openssl s_client to get certificate revocation checked in negotiation?
With 1.02 you should be able to do this. From the changelog:
*) New options -CRL and -CRLform for s_client and s_server for CRLs.
[Steve Henson]
In versions before that the behavior is undocumented: You have to include the CRL together with the certificate in the same file if you are using a single file with -CAfile. If you are using a directory with -CApath instead it gets even harder.

After signing .mobileconfig profile it shows as "Unverified" - "The ceritifcate was signed by an unknown authority"

I'm trying to sign a configuration profile (CardDav) with my SSL certificate issued by networksolutions.com
NetworkSolutions.com should be one of the providers that's in iOS/OSX trusted ceritifcates according to this
I've also seen other configuration profiles signed by NetworkSolutions that were "Verified" just fine.
This is the Ruby code I use to sign the profile
ssl_key_str = File.read(Rails.root.join("config/ssl/server.key"))
ssl_key = OpenSSL::PKey::RSA.new(ssl_key_str)
ssl_cert_str = File.read(Rails.root.join("config/ssl/server.crt"))
ssl_cert = OpenSSL::X509::Certificate.new(ssl_cert_str)
signed_profile = OpenSSL::PKCS7.sign(ssl_cert, ssl_key, profile, [], OpenSSL::PKCS7::BINARY)
Also tried to sign with openssl:
openssl smime -sign -in apple_sync_profile-unsigned.mobileconfig -out signed.mobileconfig -signer server.crt -inkey server.key -certfile server.crt -outform der -nodetach
Still getting "Unverified"
Digging deeper by trying to open the mobileconfig file on my Mac, it shows "this certificate was signed by an unknown authority"
I tried to compare with this other profile that I downloaded and shows up as Verified but could not come up with any meanigful difference.
Any recommendations?
Is there any tool I could use to sign profile other than openssl which might be able to provide more insight?
How to Sign and verify a .mobileconfig file in apple
Export certificate from the key chain
keychain access --> Certifcates(LeftPanel)--> right click the particular certificate and export the certificate.
convert .p12 file to PEM file (converting use this link www.sslshopper.com/ssl-converter.html)
Eg: InnovCertificates.p12 to InnovCertificates.pem
Download Apple Root Certificate and Apple Intermediate Certificate
(For my .mobileconfig file verification i am used Apple Inc. Root Certificate(Apple Root Certificate) and
Application Integration Certificate (Apple Intermediate Certificate) certificates.
you can also use these certificates or other certificates that have in the apple certificates www.apple.com/certificateauthority/)
The download file is combination of certificate and keys . (Read the certificate in Terminal commands are following link info.ssl.com/article.aspx?id=12149)
From this certificate file we need extract certificate.
extract certificate from Apple Root Certificate. Then extract certificate from Apple Intermediate Certificate
openssl x509 -inform DER -outform PEM -in AppleIncRootCertificate.cer -out root.crt.pem
openssl x509 -inform DER -outform PEM -in AppleAAICA.cer -out Intermediate.crt.pem
open the two extracted file in text editor,
copy and paste the Intermediate.crt.pem to beginning of the root.crt.pem and save .then your root.crt.pem file is combination of two certificate.
Sign and verify the .mobileconfig file
Once you have all the files listed above, you will run a command like the following:
openssl smime -sign -in Example.mobileconfig -out SignedVerifyExample.mobileconfig -signer InnovCertificates.pem -certfile root.crt.pem -outform der -nodetach
The result .mobileconfig file is signed and verified.
Use full links:
renren.io/questions/637349/ios-mobileconfig-walkarounds
developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/smime.1ssl.html#//apple_ref/doc/man/1/smime
www.apple.com/certificateauthority/
www.rootmanager.com/iphone-ota-configuration/iphone-ota-setup-with-signed-mobileconfig.html
info.ssl.com/article.aspx?id=12149
www.sslshopper.com/ssl-converter.html
wiki.cac.washington.edu/display/infra/Extracting+Certificate+and+Private+Key+Files+from+a+.pfx+File
stackoverflow.com/questions/9277426/ios-mobileconfig-walkarounds
stackoverflow.com/questions/991758/how-to-get-an-openssl-pem-file-from-key-and-crt-files
discussions.apple.com/thread/2363234
My certificate was signed by a sub-CA and did not contain the full certificate chain. In order for the signing to be complete, you must provide a full server.crt certificate which contains the full chain of certificates.
Download the sub-certificates from your certificate provider (e.g: Startssl) and add them to your server certificate simply by cat server.crt ca-bundle.crt > server.crt)

Two way authorization with PFX file

I have a problem with two-way authentication. I Use tomcat6 as a server and as a client I try IE, Firefox and my own java application.
The problem occurs using PFX certificates given to me by someone else. I have to use them as a client certificate, so i just add it to trusted certs on server and use it on browser in user certificates. The problem is that i get bad_certificate alert.
I have succeeded in doing two-way ssl by generating my own certificates for server and client and adding public keys as trusted in both keystores etc...
When i watch wireshark logs i see, that server sends good certificate request but client sends empty Certificate (11 bytes length packet) instead of 500+ bytes when i used my own generated cert.
What can be the problem? Why client does not send good cert? :(
Well, the first thing to check is to see if Tomcat is configured correctly to request a certificate from the client for the path in question. For Tomcat 6, this means you should have a Connector configured in conf/server.xml something like this:
<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="${user.home}/.keystore" keystorePass="password"
truststoreFile="conf/truststore" truststorePass="password"
clientAuth="true" sslProtocol="TLS" />
The truststoreFile & truststorePass are important - if you just add "clientAuth=true" without including these two parameters, you'll see all sorts of strange behavior (and no warning that you did anything wrong). The truststoreFile must point to a legitimate JKS file that lists the CA's that you trust to sign the client certificates. If Tomcat is configured correctly, the browser should pop up a dialog to the user along the lines of: "The website requires a client certificate" along with a list of all certificates that have been imported to the browser. If you don't see this, there's something wrong with your Tomcat setup.
It sounds like you've got that set up correctly, but it's worth double-checking. Also, if you have it set up correctly, you will see a "certificate request" handshake message if you trace the connection in wireshark that lists the trusted CAs by distinguished name. Again, if you don't see this, check your Tomcat setup and most importantly the truststore.
The next thing would be to check the PKCS12 file itself. You can do this with:
openssl pkcs12 -in [path-to-pkcs12-file] -nokeys | openssl x509 -noout -subject -issuer
Make sure that the issuer's distinguished name matches one of the trustedCaCert entries in your trust store. This is sort of a hassle to do with the Java keytool, but you can double check using:
keytool -exportcert -keystore conf/truststore -alias [alias of trusted cert] | openssl x509 -noout -subject -inform der
If all of this checks out, but it's still not working, it's worth using openssl's s_client to troubleshoot, since you usually get a lot more troubleshooting information from it. To do so, you'll have to separate the key from the cert in the PKCS12 file:
openssl pkcs12 -in [PKCS12 file] -out [whatever].key
openssl s_client -tls1 -connect localhost:443 -cert [whatever].key -key [whatever].key
(You can use the same file for the "-cert" and "-key" argument because openssl is smart enough look for the "BEGIN CERTIFICATE" and "BEGIN RSA PRIVATE KEY" delimiters in the source files). I was having a frustrating problem with client certs that I couldn't figure out once until I used s_client and got a reminder that my client certificate had expired (which wasn't logged or output anywhere else).
Also, you might want to strongly consider shifting your configuration to use Apache over Tomcat - Apache is a lot more flexible, and gives you a lot more feedback when it comes to SSL confifguration than Tomcat is.
Take a closer look at your client certificates, in particular the X509v3 extensions "Key Usage" and "Extended Key Usage". They may be marked as not trusted for client authentication.
Using the openssl command-line tool:
$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -purpose
Enter Import Password:
MAC verified OK
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : Yes
SSL server CA : No
This certificate is only signed for server authentication (normal HTTPS). For full details, use the -text option in openssl x509:
$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -text
[..snip..]
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
[..snip..]
If this is the case, you're going to have to ask to get a new signed certificate that is marked for client authentication use.

Client SSL authentication causing 403.7 error from IIS

I'm trying to connect to a web service (not under my control) configured to authenticate users via SSL client certs. I have a valid certificate in PKCS12 format containing the client certificate and associated private key. The certificate is issued by a CA accepted by the web service provider.
Installing the certificate and trying to access the restricted area in various browsers gives the following results:
IE6 - Works fine and I can retrieve the WSDL
IE7 - Prompts for the certificate but then fails with a 403.7 from the server
Firefox3 - Set to ask, but no prompt and fails with a 403.7
Safari 4 - Certificate is installed in the Keychain, but no prompt and a 403.7
Also, trying to access the web service programmatically (Java) fails with the same 403.7 error code.
Strange that this works in IE6 but in no other browser, what am I missing? Do I need to include the full CA certificate chain in the PKCS12 file?
Any help would be greatly appreciated.
This really works! If you're confused by the -inkey and -in options, they are the private key and certificate from the p12 file. You can convert the p12 file to pem format with:
openssl pkcs12 -in file.p12 -clcerts -out file.pem
and use the above command with "-in file.pem" only.
Also, you can import the root CA cert into your trusted certs store, here is the description how to do that: http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl, and then you don't have to manually copy the certificates. After installing the cert use the command above without the "-CAfile chain.pem".
Ok, got this working. The answer is yes, I did need to include all intermediary CA certs in the PKCS12 file. I concatenated all the intermediary CA certs plus the Root CA cert in the file "chain.pem" then executed the following command:
openssl pkcs12 -export -chain -CAfile chain.pem -in cert.pem -inkey key.pem -out cert.p12