Quick Version of Question
Gmail, TD (Canadian Bank), Royal Bank (Canadian Bank) all use ssl. When you inspect their certificates they all have
Common Name (CN) mail.google.com
Or more generally:
Common Name (CN) <url>
Is this needed to prevent man in the middle attacks?
Summary
JBoss allows clients and servers to authenticate using certificates and ssl. One thing that seems strange is that you are not required to give your hostname on the certificate.
I think that this means if Server B is in your truststore, Sever B can pretend to be any server that they want.
(And likewise: if Client B is in your truststore...)
Am I missing something here?
Authentication Steps
(Summary of Wikipeida Page)
Client Server
=================================================================================================
1) Client sends Client Hello
ENCRIPTION: None
- highest TLS protocol supported
- random number
- list of cipher suites
- compression methods
2) Sever Hello
ENCRIPTION: None
- highest TLS protocol supported
- random number
- choosen cipher suite
- choosen compression method
3) Certificate Message
ENCRIPTION: None
-
4) ServerHelloDone
ENCRIPTION: None
5) Certificate Message
ENCRIPTION: None
6) ClientKeyExchange Message
ENCRIPTION: server's public key => only server can read
=> if sever can read this he must own the certificate
- may contain a PreMasterSecerate, public key or nothing (depends on cipher)
7) CertificateVerify Message
ENCRIPTION: clients private key
- purpose is to prove to the server that client owns the cert
8) BOTH CLIENT AND SERVER:
- use random numbers and PreMasterSecret to compute a common secerate
9) Finished message
- contains a has and MAC over previous handshakes
(to ensure that those unincripted messages did not get broken)
10) Finished message
- samething
Sever Knows
The client has the public key for the sent certificate (step 7)
The client's certificate is valid because either:
it has been signed by a CA (verisign)
it has been self-signed BUT it is in the server's truststore
It is not a replay attack because presumably the random number (step 1 or 2) is sent with each message
Client Knows
The server has the public key for the sent certificate (step 6 with step 8)
The server's certificate is valid
because either:
it has been signed by a CA (verisign)
it has been self-signed BUT it is in the client's truststore
It is not a replay attack because presumably the random number (step 1 or 2)
is sent with each message
Potential Problem
Suppose the client's truststore has certs in it:
Server A
Server B (malicous)
Server A has hostname www.A.com
Server B has hostname www.B.com
Suppose: The client tries to connect to Server A but Server B launches a man in the middle attack.
Since server B:
has a public key for the certificate that will be sent to the client
has a "valid certificate" (a cert in the truststore)
And since:
certificates do not have a hostname feild in them
It seems like Server B can pretend to be Server A easily.
Is there something that I am missing?
Can you point to some text that says JBoss doesn't need a hostname in the cert, or is it simply your observation? I assume by 'hostname' you mean the Common Name (CN) or Distinguished Name (DN)??
Normally an application should check an X.509 cert for:
Valid date range
Usage (eg; server auth)
Chains to a trusted root
CN == DNS name of target host (it might be another name, not just DNS)
Not revoked (using a CRL or OCSP)
Technically, an app can choose to ignore any of these and simply indicate that all is well with the cert.... but that's bad :)
I think you're missing something, but I'm not sure if I understand your reasoning.
However, when server B tries to launch a man in the middle attack, you say that it has a public key. This is true, but to setup a ssl connection, you should also have a private key belonging to that public key. Moreover, the certificate used is coupled to the dns name (in case of https). So a client tries to connect to A, he types in www.a.com. Since we assume that B does not know the private key of A, he will have another keypair. He could never receive a valid (i.e. trusted) certificate from a major CA that is coupled to a domain he does not own.
So B could never get a certificate with common name www.A.com, for this reason, B could not perform a man in the middle attack.
Related
I have generated my private Root CA and then Intermediate CA which is being used for signing certificates rather than directly RootCA. Now I want to setup OCSP server hence have certain queries.
Since I am using Intermediate CA, shall I use Int CA to generate CSR
and generate CRT? Or Root should be used for generating OCSP crt?
I am planning to cater around 400-500 servers servers certificate hence
wondering if one ocsp server shodul suffice my need to check for
revocation?
Can anyone tell me if directly nginx can be used for
setting ocsp server or need to us openssl ocsp api only?
you normally would use an dedicated Int CA for generating the CSR. The Root is like an holly grail and should be keep in an save location preferable offline.
Once OCSP Server is can handle it as long as you do not need HA. But not the server count is important but how many clients you expect since not all of them can handle OCSP-Stappling. You certently need openssl api since nginx will not handle the crypto stuff out of the box.
Any time I attempt to send mail from my mail client (In this case, thunderbird), it comes up with an arbitrary error for why it couldn't send the email (The error doesn't matter, as it simply is telling me that the connection got dropped). When I run tail -f /var/log/maillog I see:
smtp disconnected reason=ca-failure
I can't seem to find anywhere online talking about this and how to fix it.
I've attempted to use several different matching keys and certificates, locally sourced (openssl) and from letsencrypt. OpenSMTP accepts all of these no problem. I have also went as far as to specify the root CA certificate for letsencrypt with their certificates.
Did you define the mail hostname for the OpenSMTPD server?
This file is supposed to be found in /etc/mail/mailname, and it should match the pkiname thats in the smtpd.conf file "pki 'hostname' cert /etc/letsencrypt/live/www.domain.com/cert.pem"
I spent an hour or two fighting with this.
This is defined in the manual:
pki pkiname cert certfile
Associate certificate file certfile with host pkiname, and use that file to prove the identity of the mail server to clients. pkiname
is the server's name, derived from the default hostname or set using
either /etc/mail/mailname or using the hostname directive. If a
fallback certificate or SNI is wanted, the ‘*’ wildcard may be used as
pkiname.
A certificate chain may be created by appending one or many certificates, including a Certificate Authority certificate, to certfile. The creation of certificates is documented in starttls(8).
We had an interesting problem come up. We solved it be re-installing the cert that does not successfully encrypt a message. I'm wondering if anybody knows how the same cert can display a different chain.
On one server, the encryption was working and successfully communicating with our business partner. On this server, our cert was chained to: “VeriSign Class 3 Secure Server CA – G3” then “VeriSign”.
On the other server, the encryption failed. The cert was chained to “VeriSign Class 3 Secure Server CA – G3” but then goes to “VeriSign Class 3 Public Primary Certification Authority – G5” and then “VeriSign Class 3 Public Primary CA”.
I don't understand how they can be different.
2 possibilities come to mind:
1) Check to see if you're sending the same intermediate cert on both. Some cert vendors offer different intermediates that chain back to different roots, for compatibility reasons.
2) Check to see that both systems have the same CA keys installed (on RHEL/CentOS, this would be the "ca-certificates" package).
In a TLS handshake configured with a client authentication, there is a step where the server receives the client's certificate and choose to trust it or not (for instance, in Java it is done via a TrustManager).
I would like to know if the eventual "trust failure" message from the server is sent before or after the server made sure that the client really own that public key (for example, by receiving first some messages from the handshake encoded with the client's private key).
The purpose of my question is to see if it is possible for a third party to check if the server trust a client, by pretending to be this client and by using his public key.
Note: The risk is real when TLS is used in a context with specific security requirements. For instance, let's suppose a P2P application which uses TLS between peers, and which use the TrustManager as a way to authenticate peers from his contact list. This contact list is supposed to be private. An ISP can list the IPs with who a node communicates, then get his public certificate by starting a TLS handshake with it, then he can try to connect each another nodes on the IP list. In the end, the ISP can get a big part of the contact list which was supposed to be private.
OpenSSL verifies the client certificate, too, immediately upon receiving it in the Client Certificate message.
But it is as Eugene says, if the server sends meaningful alerts, then it does not matter if you send bad_certificate right away or only after having verified the signature in the Certificate Verify message. This would only prevent someone from finding out whether a certificate is trusted or not if they additionally send a malformed signature (e.g. by using the wrong key). But if a server were implemented that way, all you had to do is sign your Certificate Verify message with a private key you just generated. Then the signature will be valid and the server will then dutifully validate the certificate you sent, revealing the same information as before.
To mitigate this situation you would really have to use a customized server that does not send the corresponding alert at all, but rather something less revealing.
This depends on implementation. Our implementation sends the error immediately, as for other implementations - I guess most do the same.
However it doesn't matter: the server sends specific error code (BadCertificate) if the certificate is not valid, so no matter when this code is sent, the attacker would know that the certificate has not been accepted. Protecting the server from this attack would require the server send a different error code and this would confuse legitimate clients.
The risk (or unpleasant consequences) of detecting that the certificate is accepted by the server or not is questionable. If this matters to you, you can change the error code and build your custom version of OpenSSL or other SSL server module you use.
I am trying to configure an IIS website to require SSL client certificates. The website is set up in both IIS 6 and 7, though I am more interested in making it work for 7. I set the require client certificates property in IIS and it works fine when accessing the site through a web browser, but a Java-based client is having trouble accessing it.
I believe the problem is that IIS does not request a client certificate during the initial SSL handshake. Instead it negotiates a normal SSL connection, checks to see if the resource requires client certificates, and if it does it then initiates a new SSL handshake that requests a client certificate. IIS does this so support sites that only require the client certificates for certain resources. Even when the requirement is specified for the entire website, IIS still initiates two SSL handshakes. I want to force IIS to request the client certificate on the first SSL handshake, which will hopefully get things working for the client. (The client is developed by an external partner and I have virtually no knowledge of how it is set up and no access to its source code)
Has anyone dealt with this problem in IIS before?
Here's how I did this, on IIS 7.5:
Run the following in an admin command prompt: netsh http show sslcert
Save the output in a text file. Will look something like this:
IP:port : 0.0.0.0:443
Certificate Hash : [a hash value]
Application ID : {[a GUID]}
Certificate Store Name : MY
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Create a batch file using that info:
netsh http show sslcert
netsh http delete sslcert ipport=0.0.0.0:443
netsh http add sslcert ipport=0.0.0.0:443 certhash=[your cert hash from above] appid={[your GUID from above]} certstorename=MY verifyclientcertrevocation=enable VerifyRevocationWithCachedClientCertOnly=disable UsageCheck=Enable clientcertnegotiation=enable
netsh http show sslcert
(Yes, you have to delete and re-add; you can't just alter clientcertnegotiation in-place. That's why it's important to save the hash and GUID, so it knows what to re-add.)
Run that batch file, check for any errors, done.
Keep in mind that this setting is applied per-certificate, not per-server. So if you use multiple certs, or change/update your cert, you will have to do this again.
It took me a while to find this metabase setting. We were having this same problem with our client using the new certicom libraries. Since the discovery of the MITM attack arround SSL Renegotiation, the answer in alot of circles has been to hangup on renegotitation requests.
running the following cmd from \inetpub\adminscripts will force IIS to always request a client certificate.
For IIS 6:
cscript adsutil.vbs set \w3svc\siteID\SSLAlwaysNegoClientCert True
(So for the default website, cscript adsutil.vbs set \w3svc\1\SSLAlwaysNegoClientCert True)
Keep in mind that some clients Internet Explorer prompt for client certificates when it recieves that packet wether the client certificate is needed or not.
For IIS 7:
Save the following text to a file called "Enable_SSL_Renegotiate_Workaround.js"
var vdirObj=GetObject("IIS://localhost/W3svc/1");
// replace 1 on this line with the number of the web site you wish to configure
WScript.Echo("Value of SSLAlwaysNegoClientCert Before: " + vdirObj.SSLAlwaysNegoClientCert);
vdirObj.Put("SSLAlwaysNegoClientCert", true);
vdirObj.SetInfo();
WScript.Echo("Value of SSLAlwaysNegoClientCert After: " + vdirObj.SSLAlwaysNegoClientCert);
Run the following command from an elevated / administrator command prompt:
cscript.exe enable_ssl_renegotiate_workaround.js
(Jacked from the KB article for 977377)