In which cases can an SSL server omit sending the certificate? - ssl

I'm trying to figure out the SSL handshake process. After reading up on TLS in Wikipedia I've seen that
The server sends its Certificate message (depending on the selected cipher suite, this may be omitted by the server)
I've also seen such behavior in real-life sniffs, but only in cases where the user eventually received an "Invalid certificate" warning.
I was wondering in which cases can a server omit the certificate? How can the client verify the server's identity in this case then? Or is it only reserved to cases where the server have no certificate and gives up on sending a fake one, knowing that the user will see a browser warning anyway?
Thanks!

Some cipher suites don't rely on certificates:
The anonymous cipher suites, defined in the main TLS RFC (the names containing DH_anon). Some of them can provide encryption, but without authentication, which is insecure. Section A.5 says the following about them:
The following cipher suites are used for completely anonymous
Diffie-Hellman communications in which neither party is
authenticated. Note that this mode is vulnerable to man-in-the-
middle attacks. Using this mode therefore is of limited use: These
cipher suites MUST NOT be used by TLS 1.2 implementations unless the
application layer has specifically requested to allow anonymous key
exchange. (Anonymous key exchange may sometimes be acceptable, for
example, to support opportunistic encryption when no set-up for
authentication is in place, or when TLS is used as part of more
complex security protocols that have other means to ensure
authentication.)
Kerberos cipher suites, in which case the identification is done via the Kerberos ticket, and the name is verified against the Kerberos principal name (host/MachineName#Realm).
Pre-Shared Keys cipher suites (see section on PSK Identity Encoding).

There is one valid case for anonymous ciphers: the opportunistic encryption of e-mail over SMTP with STARTTLS. As an MITM could easily prevent the use of TLS, there is no use in protecting agains MITM at the TLS level.
If the client knows that he will proceed anyway, even if the certificate was invalid, the can request an anonymous ciphersuite saving the server the generation of a signature and himself the verification the certificate and the signature.

Related

Delayed certificate in TLS 1.3

In ASP.NET Core there are 4 available certificate modes:
// Summary:
// A client certificate is not required and will not be requested from clients.
NoCertificate,
// Summary:
// A client certificate will be requested; however, authentication will not fail
// if a certificate is not provided by the client.
AllowCertificate,
// Summary:
// A client certificate will be requested, and the client must provide a valid certificate
// for authentication to succeed.
RequireCertificate,
// Summary:
// A client certificate is not required and will not be requested from clients at
// the start of the connection. It may be requested by the application later.
DelayCertificate
I want to use DelayCertificate mode because this shouldn't ask for certificate to user in e.g. web explorer, but still I can require certificate on some endpoints. But I have one consideration: It seems to me that I once read that delayed certificates aren't supported in TLS 1.3. I'm not sure about it, and I can't find the source where I read this. So what's it like with this mode? Will it work with TLS 1.3?
... I once read that delayed certificates aren't supported in TLS 1.3
In TLS 1.2 and lower renegotiation was used to ask for client certificates after the initial TLS handshake was already done. This mechanism does not exist in TLS 1.3 anymore, which means it also cannot be used for delayed client certificates anymore in TLS 1.3.
But, TLS 1.3 introduced a different mechanism for this purpose: Post-Handshake Client Authentication. Thus, delayed client certificates can still work with TLS 1.3, only differently. But it requires that the client supports it and not all might do.
Additionally TLS 1.3 post-handshake client authentication is explicitly forbidden in HTTP/2 - see RFC 8740. But similar to this delaying client certificates in response to access to a protected resource weren't allowed with TLS 1.2 in HTTP/2 either: RFC 7540 explicitly forbids renegotiation after the actual HTTP/2 protocol (inside the TLS) has been started.

openSSL 1.1.1 API Doubts

I want to set up and run SSL client and server with TLS 1.2 using openSSL 1.1.1 for my project.
I have a few doubts and/or requirements with openSSL:
what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?
I need to run an SSL clinet with following handshake extensions.
ec_point_formats with "uncompressed" as value
supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"
encrypt_then_mac with value 0
server_name
extended_master_secret without any value and length set to 0
I need to run an SSL server with following handshake extensions
encrypt_then_mac with value 0
extended_master_secret without any value and length set to 0
Apart from above header extension fields I want to disable everything else. How to accomplish that?
From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.
Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?
Is there any example or open source client-server implementation with PSK authentication?
what is the right way to select TLS 1.2 as version? Currently I am using TLS_client_method(). the other methods seem to be deprecated. Is there a specific API for choosing particular version?
TLS_client_method() is the correct method to use. To specify that no version below TLSv1.2 is used you should do this:
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
Where ctx is your SSL_CTX object.
If you also want to prevent anything higher than TLSv1.2 from being used then do this:
SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
See this page for information on these calls:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_min_proto_version.html
I need to run an SSL clinet with following handshake extensions.
ec_point_formats with "uncompressed" as value
supported_groups with list of "secp521r","secp384r1","secp256r1","secp224r1","secp192r1","secp160r1","ffdhe2048"
These extensions aren't used if you specify the PSK ciphersuite that you've selected so OpenSSL won't send them (assuming you've restricted the max TLS protocol version as described above, and have configured only that ciphersuite). Doing so would be pointless. Even if it did, OpenSSL 1.1.1 does not support "ffdhe2048". It does support all the others.
encrypt_then_mac with value 0
Not sure what you mean by "with value 0" since this extension is always empty and has no value. I assume you mean with length 0. This extension is sent by default so you don't need to do anything.
server_name
You should call:
SSL_set_tlsext_host_name(ssl, "hostname of the server");
Where ssl is your SSL object, and replacing "hostname of the server" with the server's real hostname.
See this page for information on this call:
https://www.openssl.org/docs/man1.1.1/man3/SSL_set_tlsext_host_name.html
extended_master_secret without any value and length set to 0
This extension is sent by default so you don't need to do anything.
I need to run an SSL server with following handshake extensions
encrypt_then_mac with value 0
extended_master_secret without any value and length set to 0
If the client sent them, then the server will echo them back by default. You don't need to do anything.
Apart from above header extension fields I want to disable everything else. How to accomplish that?
An OpenSSL client will additionally send the session_ticket extension. Its harmless, but if you really want to disable it you can do this:
SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET);
See this page for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_options.html
An OpenSSL server will additionally send the "renegotiate" extension. You must not disable this (in fact you cannot). Ignore it. Its harmless.
From client I want to provide only "TLS_PSK_WITH_AES_128_CBC_SHA256" cipher suite as option.
That is the official IANA name for the ciphersuite. OpenSSL knows it as "PSK-AES128-CBC-SHA256".
Configure it on both the client and the server like this:
SSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256");
See this page for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_cipher_list.html
In addition you will need to provide PSK callbacks to tell OpenSSL what the PSK is that you want to use.
On the client you need to call SSL_CTX_set_psk_client_callback(). On the server you must call SSL_CTX_set_psk_server_callback().
See these pages for further information:
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_client_callback.html
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_server_callback.html
TLSv1.3 ciphersuites will still automatically be sent unless you have additionally restricted the max TLS protocol version to TLSv1.2 as described above. Finally you will also see a ciphersuite called "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" being sent. This isn't actually a real ciphersuite at all. It is always sent and cannot be suppressed. It will never be negotiated and is harmless. Ignore it.
Is client certificate and key files (pem) necessary for successful connection establishment and communication when PSK cipher is used?
No.
Is there any example or open source client-server implementation with PSK authentication?
You can look at how s_client and s_server do it:
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_client.c
https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_server.c

handshake failure(40) and TLS_EMPTY_RENEGOTIATION_INFO_SCSV

A client installed on jBOSS is trying to access a secured website configured on DataPower xi50v6.0.0.2 appliance. The connection is getting failed at SSL handshake.
I have taken a packet capture at DataPower and observed that SSL Handshake is failing with the Description:Handshake failure(40).
However, at the Client Hello step, I have observed that, only one Cipher Suite is specified which is : TLS_EMPTY_RENEGOTIATION_INFO_SCSV.
The TLS protocol used ( as per packet capture) is TLS1.1. Can this Cipher Suite be a problem?
In the DataPower system logs I can see below error:
Request processing failed: Connection terminated before request headers read because of the connection error occurs
Update:
The client application is running on jBOSS7.I have asked our jBOSS administrator to check the configuration at jBOSS end. I somehow got the access to server where jBOSS instance is installed and checked domain.xml where the ssl is configured. Where exactly in domain.xml, ths configuration related to cipher suites can be found?
I have observed that, only one Cipher Suite is specified which is : TLS_EMPTY_RENEGOTIATION_INFO_SCSV
This is no real cipher. If no other ciphers are specified then the client does not offer any ciphers at all which means that no shared ciphers can be found and thus the handshake will fail. It looks like the client is buggy. Reason might be a failed attempt to fight POODLE attack by disabling all SSL3.0 ciphers, which in effect disables all ciphers for TLS1 1.0 and TLS 1.1.

is ssl certificate encoded?

My application capture every packet coming from the server. I can read those packet for HTTP. I want to read the subject field from ssl certificate. But I cant. Is it encoded? If it is, how can I decode & read it?
Assuming that SSL negotiates a protocol that needs certificates, the certificates are generally in ASN.1 based X.509v3 format when they're sent from the server to the client.
From the TLS 1.0 RFC (which is a start if you want to listen to/analyze the protocol);
7.4.2. Server certificate
When this message will be sent:
The server must send a certificate whenever the agreed-upon key
exchange method is not an anonymous one. This message will always
immediately follow the server hello message.
Meaning of this message:
The certificate type must be appropriate for the selected cipher
suite's key exchange algorithm, and is generally an X.509v3
certificate.

403.7 IIS 7.5 SSL client certificate authentication issue

I am testing a web service with an external partner using 2 way SSL under IIS 7.5. I am requiring SSL, requiring a client cert, and using one to one mapping to authenticate to a domain account. I have configured everything and it works fine on our network (I am able to provide a client cert, get authenticated and invoke the service from browser and test harness).
From outside of our network (in most cases, see below), I am getting a 403.7 error. I have gone through the machine level certificate store and made sure the certificates and CAs are trusted.
Here's the weird thing. I obtained a Type I cert to test from home (and got 403.7 like our intended partner is). So I setup Fiddler to debug SSL and send my certificate, and this works for some reason. I setup a test harness to pass the exact same certificate, and got 403.7. I test in my browser (IE 9), don't get a prompt for a client cert, and get 403.7.
Any help appreciated.
Bill
Last time I checked, IIS was using re-negotiation (by default) to get the client certificate: there is a first handshake where the server doesn't request a client certificate, followed by another handshake (encrypted this time) where the server requests the certificate (via a TLS CertificateRequest message). This will prevent you from seeing anything from Wireshark, unless you configure it to use the server's private key and decipher the traffic (note that this only works with some cipher suites).
One way to see the client-certificate negotiation is to configure IIS to use initial client certificate negotiation, using netsh and clientcertnegotiation=true (which is about initial negotiation). At least the CertificateRequest and the certificate will be sent in clear during the handshake, so you should be able to see this with Wireshark.
If the client isn't sending a certificate to the server as a response to the CertificateRequest, you'll still see an empty Certificate message from the client.
If you don't export the private key with the certificate to use with Fiddler or whichever other client, there is no chance that it will be able to use the certificate. It may at best try to send the certificate, but the handshake will fail (since the CertificateVerify message needs to be signed by the client's private key).
I guess you may encounter a problem whereby:
not presenting a certificate is accepted by the server (it's effectively optional),
presenting an invalid certificate makes it fail and causes this 403.7 status code (many servers and SSL/TLS stacks would implement this as a fatal error, but TLS specification doesn't say that unsupported_certificate, certificate_revoked, certificate_expired, certificate_unknown should be fatal, so this is at the server's discretion).
Are you using the same physical machine to test both the in-network and external-network connections? If not, are you sure that the external-network client has the private key accessible?
I have not configured Fiddler client authentication before. Does it read the client certificate and key from the standard certificate stores? Does it read directly from a PKCS12?
One other thing that may be helpful is inspecting the TLS handshake in WireShark. Specifically, check out the Server's "Certificate Request" message, as the data here clues the client (IE9) which client certificates it should display in the prompt. Compare this for the internal and external connections.