- OpenSSL is an open-source cryptographic library and SSL toolkit. The applications contained in the library help create a secure communication environment for computer networks. OpenSSL contains an implementation of SSL and TLS protocols, meaning that most servers and HTTPS websites use its resources.
- Select a site in the tree view and click Bindings. In the Actions pane. This brings up the bindings editor that lets you create, edit, and delete bindings for your Web site. To add your new SSL binding to the site. The default settings for a new binding are set to HTTP on port 80.
Due to the large number of protocol features and implementation quirks, it’s sometimes difficult to determine the exact configuration and features of secure servers. Although many tools exist for this purpose, it’s often difficult to know exactly how they work, and that sometimes makes it difficult to fully trust their results. Even though I spent years testing secure servers and have access to good tools, when I really want to understand what is going on, I resort to using OpenSSL and Wireshark. I am not saying that you should use OpenSSL for everyday testing; on the contrary, you should find an automated tool that you trust. For online testing, I recommend Hardenize;25 for offline work, consider
testssl.sh.26 But when you really need to be certain of something, the only way is to get your hands dirty with OpenSSL.
Using OpenSSL for testing purposes has become more difficult recently because, paradoxically, OpenSSL itself got better. In the aftermath of Heartbleed, the OpenSSL developers undertook a great overhaul, one aspect of which was removal of obsolete cryptography. That is great news for everyone, of course, but does make our lives more difficult. To test for a wide variety of conditions, we may need to use two versions: one recent and one old. The recent one is useful to test modern features (e.g., TLS 1.3), but the old one is what you need to test obsolete functionality.
SSL Website Certificate Checker - For checking your SSL certificate installation. If you want to check if installation is correct. SSL Website Content Checker - For when you have insecure content errors. Insecure images or iframes can cause these errors. OpenSSL Toolkit; FTP Client for help with manual HTTP verification. Some third parties provide OpenSSL compatible engines. As for the binaries above the following disclaimer applies: Important Disclaimer: The listing of these third party products does not imply any endorsement by the OpenSSL project, and these organizations are not affiliated in any way with OpenSSL other than by the reference to their independent web sites here.
At the time of writing, the new version will most definitely be from the 1.1.1 branch. As for the old, after some research, I settled on OpenSSL 1.0.2g, configured so that the removal of some obsolete features is reverted:
Throughout this chapter, I will refer to these two versions of OpenSSL as new and old. That’s how you’ll know which version to use for the testing. Refer to the previous chapter for more information on how to configure and install OpenSSL.
OpenSSL comes with a client tool that you can use to connect to a secure server. The tool is similar to
nc in the sense that it handles the encryption aspect but allows you to fully control the layer that comes next.
To connect to a server, you need to supply a hostname and a port. For example:
Notice that you had to supply the hostname twice. The
-connect switch is used to establish the TCP connection, but
-servername is used to specify the hostname sent at the TLS level. Starting with OpenSSL 1.1.1, the
s_client tool automatically configures the latter. You’ll still need to use the
-servername switch if (1) you’re using an earlier version of OpenSSL, (2) you’re connecting to an IP address, or (3) the TLS host needs to be different. Use the
-noservername switch to avoid sending hostname information in the TLS handshake.
Once you type the command, you’re going to see a lot of diagnostic output (more about that in a moment) followed by an opportunity to type whatever you want. Because we’re talking to an HTTP server, the most sensible thing to do is to submit an HTTP request. In the following example, I use a
HEAD request because it instructs the server not to send the response body:
If, when connecting to a remote server in this way, the TLS handshake completes but you’re getting disconnected after the first HTTP request line, check that you’ve specified the
-crlf switch on the command line. This switch ensures that the newlines you type are translated to a carriage return plus line feed combo to ensure string HTTP compliance.
Now we know that the TLS communication layer is working: we got through to the HTTP server, submitted a request, and received a response back. Let’s go back to the diagnostic output. The first couple of lines will show the information about the server certificate:
The next section in the output lists all the certificates presented by the server in the order in which they were delivered:
For each certificate, the first line shows the subject and the second line shows the issuer information.
This part is very useful when you need to see exactly what certificates are sent; browser certificate viewers typically display reconstructed certificate chains that can be almost completely different from the presented ones. To determine if the chain is nominally correct, you might wish to verify that the subjects and issuers match. You start with the leaf (web server) certificate at the top, and then you go down the list, matching the issuer of the current certificate to the subject of the next. The last issuer you see can point to some root certificate that is not in the chain, or—if the self-signed root is included—it can point to itself.
The next item in the output is the server certificate; it’s a lot of text, but I’m going to remove most of it for brevity:
By default, the
s_client tool shows just the leaf certificate. If you wish to obtain the entire chain, use the
If you want to have a better look at the certificate, you’ll first need to copy it from the output and store it in a separate file. I’ll discuss how to do that in the next section.
The following is a lot of information about the TLS connection, most of which is self-explanatory:
The most important information here is the protocol version (TLS 1.2) and cipher suite used (
ECDHE-RSA-AES128-GCM-SHA256). Do note that protocol information appears in two locations, which is potentially confusing when different versions are shown. The first location describes the minimum protocol requirement with the negotiated cipher suite, while the second location points to the actual protocol version currently being negotiated. You will see a difference in protocol versions with some older cipher suites—for example:
The selected suite could be used with SSL 3.0, but it’s used with TLS 1.2 on this connection:
You can also determine that the server has issued to you a session ID and a TLS session ticket (a way of resuming sessions without having the server maintain state) and that secure renegotiation is supported.
If you’re connecting to a TLS 1.3 server, the output may be different. Sometimes you will observe less information initially, with additional information arriving later in bursts. This behavior depends on the implementation and reflects the changes in TLS 1.3, which transmits session tickets as separate protocol messages that are sent only after the handshake is complete. Additionally, multiple session tickets are usually sent on the same connection.
Just because you are able to connect to a TLS server, that doesn’t mean that the service is configured correctly, even if the server supports all the right protocols and cipher suites. It is equally important that the configured certificate matches the correct DNS names.
By default, the
s_client tool reports but otherwise ignores certificate issues. Further, before you begin to trust its judgment you need to be confident that it can recognize a valid certificate when it sees one. This is especially true when you’re using a custom-compiled binary.
In the example from the previous section, the verification status code (shown on the penultimate line) was
0, which means that the verification has been successful. If you’re connecting to a server that has a valid public certificate but you see status
20 instead, that probably means that trusted roots haven’t been correctly configured:
At this point, if you don’t wish to fix your OpenSSL installation, you can instead use the
-CApath switch to point to the location where the roots are kept. For example:
If you instead have a single file with the roots in it, use the
Even if you get a successful status code at this point, that doesn’t mean that the certificate is correctly configured. That’s because the
s_client tool doesn’t check that the certificate is correct for the given hostname; you have to tell it to do that manually and tell it which hostname to use:
If there is a mismatch, you might see status code 62:
Otherwise, you’ll see the familiar status code
0. In the rare instance that you need to verify a certificate that has been issued for an IP address instead of a hostname, you’ll need to use the
-verify_ip switch for the verification.
When used with HTTP, TLS wraps the entire plain-text communication channel to form HTTPS. Some other protocols start off as plaintext, but then they upgrade to encryption. If you want to test such a protocol, you’ll have to tell OpenSSL which protocol it is so that it can upgrade on your behalf. Provide the protocol information using the -
starttls switch. For example:
At the time of writing, the supported protocols in recent OpenSSL releases are
ldap. There is less choice with OpenSSL 1.0.2g:
Some protocols require the client to provide their names. For example, for SMTP, OpenSSL will use
mail.example.com by default, but you can specify the correct value with the
-name switch. If you’re testing XMPP, you may need to specify the correct server name; you can do this with the
When you connect to a remote secure server using
s_client, it will dump the server’s PEM-encoded certificate to standard output. If you need the certificate for any reason, you can copy it from the scroll-back buffer. If you know in advance you only want to retrieve the certificate, you can use this command line as a shortcut:
The purpose of the
echo command at the beginning is to separate your shell from
s_client. If you don’t do that,
s_client will wait for your input until the server times out (which may potentially take a very long time).
s_client will print only the leaf certificate; if you want to print the entire chain, give it the
-showcerts switch. With that switch enabled, the previous command line will place all the certificates in the same file.
Another useful trick is to pipe the output of
s_client directly to the
x509 tool. The following command shows detailed server information, along with its SHA256 fingerprint:
Sometimes you will need to take the certificate fingerprint and use it with other tools. Unfortunately, OpenSSL outputs certificates in a format that shows individual bytes and separates them using colons. This handy command line normalizes certificate fingerprints by removing the colons and converting the hexadecimal characters to lowercase:
Connecting to remote TLS servers and reviewing their certificates is a pretty common operation, but you shouldn’t spend your time remembering and typing these long commands. Instead, invest into writing a couple of shell functions that will package this functionality into easy-to-use commands.
s_client will try to use the best protocol to talk to the remote server and report the negotiated version in output. As mentioned earlier, you will find the protocol version in the output twice, and you want the line that explicitly talks about the protocol:27
If you need to test support for specific protocol versions, you have two options. You can explicitly choose one protocol to test by supplying one of the
tls1_3 switches. Naturally, each switch requires support for a specific protocol version in the testing tool. If you want to exclude a particular protocol from the testing, there is a family of switches that disable protocols (e.g.,
-no_tls_1_2 for TLS 1.2). Sometimes that may be the better approach. Starting with OpenSSL 1.1.0, there are two new options,
-max_protocol, which control the minimum and maximum protocol version, respectively.
For example, here’s the output you might get when testing a server that doesn’t support a certain protocol version:
Understanding if a server supports SSL 2.0 may sometimes require more work, due to the fact that this old and very insecure version of the SSL protocol uses a different handshake from that used from SSL 3.0 onwards. Although servers that support only SSL 2.0 should now be very rare, to check this eventuality, you’ll need to submit a separate check using the
Another protocol difference is that SSL 2.0 servers are sometimes seen without any configured cipher suites. In that case, although SSL 2.0 is supported, technically speaking, any handshake attempts will still fail. You should treat this situation as misconfiguration.
It’s not very likely that you will be spending a lot of time testing cipher suite configuration using OpenSSL on the command line. This is because you can effectively test for only one suite at a time; testing for more than 300 cipher suites that are supported by TLS 1.2 and earlier protocol revisions would take a considerable amount of time. This is a perfect opportunity to use those handy tools that automate the process.
Still, there will be times when you will need to probe servers to determine if they support a particular suite or a cryptographic primitive, or if the preference is correctly configured.
The introduction of TLS 1.3 made testing in this area slightly more complicated, but it’s still manageable. Because of the differences between this protocol version and all other revisions, it’s usually best to split your tests into two groups. When testing TLS 1.3, always use the
-ciphersuites switch in combination with
-tls1_3. The usual approach is to specify only one suite to determine if it’s supported:
The output will naturally be different if you pick a suite that is not supported:
When you’re testing the configuration of TLS 1.2 and earlier protocol versions, use the
-cipher switch in combination with
-no_tls1_3 (assuming you’re using a version of OpenSSL that supports TLS 1.3):
As you can see in the previous example, when testing TLS 1.2 and earlier you don’t have to specify only one cipher suite, but in that case you will need to observe what has been negotiated. If you want to probe further, you can always tweak the command line to remove the previously negotiated suite:
Even though you won’t be testing for a great many suites manually, there is a quick way to determine if a particular server supports any of the many bad cryptographic primitives. To do this, use your old OpenSSL version and list all the bad cipher suite keywords, like this:
Another good test is to see if a server supports the RSA key exchange that doesn’t support forward secrecy:
Ideally, you’d get a handshake failure here, but it’s not terrible if you don’t, provided the server uses the RSA key exchange only as a matter of last resort. You can check this by offering suites with forward secrecy as your least preferred option:
As a general rule, TLS servers should always be configured to enforce their cipher suite preferences, ensuring that they negotiate their preferred cipher suite with every client. This feature is essential with TLS 1.2 and earlier protocol revisions, which support many cipher suites, most of them undesirable. It’s a different story with TLS 1.3: it only has a handful of suites available at this time and all of them are secure, so enforcing server preference doesn’t matter that much.28
Because cipher suite preference doesn’t matter much with TLS 1.3, some stacks don’t even support it with this protocol, even if they do with earlier protocol versions. Thus, for the best results, you will want to test separately for TLS 1.3 and everything else—or separately for every supported protocol. This is another case in which automation is the better choice.
To test for server suite preference, you first need to have some idea of what suites are supported. For example, you could have the complete list of supported suites. Alternatively, you can probe the server with different suite types—for example, those that use ECDHE versus DHE or RSA key exchange.
With two suites in hand, you need to initiate two connections, first offering one of the suites as your first choice, then the other:
If you see the same suite negotiated on both connections, that means that the server is configured to actively select negotiated suites. Otherwise, it isn’t. The server in the previous example is one of those TLS 1.3 servers that doesn’t enforce preference. That very same server does have a preference with TLS 1.2; we can see that it always selects a better suite, even when we push it to the end of our list:
When it comes to server suite preference testing, the ChaCha20 suites are best avoided. This is because some servers support another type of preference, where they treat AES-GCM and ChaCha20 suites as equal in terms of security and respect client preference as a special case. The idea is that the client will prefer the faster cipher suite, which is typically ChaCha20 for mobile devices and AES-GCM for desktops.
That said, with servers that support this type of preference, you may want to test if it’s working correctly. To do that, you’ll need to use three supported cipher suites and three tests. The purpose of the first two tests is to establish that the server selects its favorite suite when ChaCha20 is not involved:
If you see that the server responds with the same suite in both cases, you can submit another test with a supported ChaCha20 suite first. If you see the server selecting it, you know it’s configured to support the client-preferred suite:
Named groups are predefined cryptographic parameters that are used for key exchange. In TLS 1.3, named groups include both elliptic curve (EC) and finite field (DH) parameters. TLS 1.2 and earlier generally use only predefined elliptic curves; the server provides DH parameters on every connection.29 In a handshake, the client and server have to agree on a common named group over which the key exchange will take place, and it’s important that the selected group satisfies desired security requirements.
In practice, there is seldom a need to test servers for named groups. Although there’s a fair number of named groups in various RFCs, OpenSSL is probably the only major client to have extensive support. Historically, you could only use NIST’s P-256 and P-384 EC groups because these were the only widely supported curves. Relatively recently, X25519 and X448 groups were added as an alternative. Because all these curves are strong, there is little need to spend time thinking about them.
You may find yourself testing named group configuration usually to understand what your web server is doing. For example, you may care about X25519 and want to ensure it’s available and preferred. To test for this, use the
s_client tool and the
-curves switch. For example, here’s how to determine if a single named group is supported:
On success, you will see the named group in the output, because that’s the group that was selected for the handshake. On failure, you may see no output, which means that the handshake failed. Alternatively, the server, unable to negotiate an ECDHE suite, may fall back to a DHE suite, indicated by the following output:
If you need to test for named group preference, you need to offer two or more named groups, with your preferred one last. If you see it negotiated, that will mean that the server actively chooses the group it considers most appropriate. Use colons to separate the groups and be aware that the names are case-sensitive.
You can get the complete list of elliptic curves supported by OpenSSL using the
ecparam tool and the
-list_curves switch. To that list, add X25519 and X448. Support for finite field groups is currently not available but should arrive with OpenSSL 3.0.
DNS-based Authentication of Named Entities (DANE) is set of standards that enables you to endorse the TLS certificates you use via DNS configuration. For this to work, DANE requires DNS itself to be secure, which means that DNSSEC is necessary. Therefore, DANE is essentially a mechanism for pinning; only the certificates you approve will be accepted as valid by DANE-enabled clients. DANE itself is not controversial, but DNSSEC, on which it relies, is a very divisive topic, with the world split between those who love it and those who hate it. As a result, DANE is currently not universally supported. It’s more commonly used to secure SMTP servers; there is no support at the browser level.
Supporting DANE adds some complexity to your TLS deployments because of the way DNS configuration is propagated and cached. Before you use a new certificate you need to ensure that your new DNS configuration (endorsing that certificate) is fully propagated. Thus, you would typically first publish your DNS changes, wait for a period time sufficient for the caches to clear, and only then deploy the certificates.30
The testing itself is straightforward; you use the
s_client tool while feeding it DANE data. This is handy because it enables you to test a connection even before making DNS changes. First, let’s see what DANE configuration looks like.
DANE stores configuration in TLSA resource records, using two prefix labels to indicate the protocol and port:
This output contains two endorsements, one per certificate. Having two endorsements is not unusual. For example, perhaps you might have a service that uses two certificates (e.g., one with an RSA key and another with an ECDSA key), or you have a backup certificate, or you’re simply in a transitional period when you’re switching certificates. The three numbers at the beginning indicate that the endorsement targets the certificate directly (3) via its public key (1) and a SHA256 hash (1). The rest of the data is the hash itself.
To test, you connect to the SMTP service while providing the DANE data using the
If the verification is successful, you will see something like this in the output:
If you’d like to test for validation failure, just break the supplied hash. The result will be similar to the following output:
For the best results, when testing DANE in this way, always provide all known TLSA records (one per
-dane_tlsa_rrdata switch). If you do, services that use multiple certificates simultaneously will check out no matter what certificate is negotiated. For TLS 1.2 and earlier, it’s possible to force a particular certificate via a choice of client-supported cipher suites (the
-cipher switch). TLS 1.3 suites are different, and for this protocol version you would need to use the
-sigalgs switch with a value such as
When coupled with the
-reconnect switch, the
s_client command can be used to test session reuse. In this mode,
s_client will connect to the target server six times. It will create a new session on the first connection, then try to reuse the same session in the subsequent five connections:
Due to a bug in OpenSSL, at the time of writing session resumption testing doesn’t work in combination with TLS 1.3. Until the bug is resolved,31 the best you can do is test the earlier protocol versions. Use the
The previous command will produce a sea of output, most of which you won’t care about. The key parts are the information about new and reused sessions. There should be only one new session at the beginning, indicated by the following line:
This is followed by five session reuses, indicated by lines like this:
Most of the time, you don’t want to look at all that output and want an answer quickly. You can get it using the following command line:
Here’s what the command does:
-reconnectswitch activates the session reuse mode.
2> /dev/nullpart hides
stderroutput, which you don’t care about.
Finally, the piped
grepcommand filters out the rest of the fluff and lets through only the lines that you care about.
If you don’t want to include session tickets in the test—for example, because not all clients support this feature yet—you can disable this method of resumption using the
-no_ticket switch. This option doesn’t apply to TLS 1.3.
If you need better control over resumption, the
s_client tool provides options to persist the connection state to a file. On your first connection, use the
-sess_out switch to record the state:
To view the recorded state, use the
Finally, to connect again using the same session state, use the
Keeping the state across connections in this way gives you more control and enables you to completely change connection parameters from one connection to another. For example, you could connect to one server on your first attempt, then another server on your second. This may be of use when you need to test if session resumption is correctly implemented on a web server cluster. Manual control of your connections allows you to spread them over time, perhaps testing for session timeouts and ticket key rotation.
If an OCSP responder is malfunctioning, sometimes it’s difficult to understand exactly why. Checking certificate revocation status from the command line is possible, but it’s not quite straightforward. You need to perform the following steps:
Obtain the certificate that you wish to check for revocation.
Obtain the issuing certificate.
Determine the URL of the OCSP responder.
Submit an OCSP request and observe the response.
For the first two steps, connect to the server with the
-showcerts switch specified:
The first certificate in the output will be the one belonging to the server. If the certificate chain is properly configured, the second certificate will be that of the issuer. To confirm, check that the issuer of the first certificate matches the subject of the second:
If the second certificate isn’t the right one, check the rest of the chain; some servers don’t serve the chain in the correct order. If you can’t find the issuer certificate in the chain, you’ll have to find it somewhere else. One way to do that is to look for the Authority Information Access extension in the leaf certificate:
If the CA Issuers information is present, it should contain the URL of the issuer certificate. If the issuer certificate information isn’t available, you can try to open the site in a browser, let it reconstruct the chain, and download the issuing certificate from its certificate viewer. If all that fails, you can look for the certificate in your trust store or visit the CA’s web site.
If you already have the certificates and just need to know the address of the OCSP responder, use the
-ocsp_uri switch with the
x509 command as a shortcut:
Now you can submit the OCSP request:
You want to look for two things in the response. First, check that the response itself is valid (
Response verify OK in the previous example), and second, check what the response said. When you see
good as the status, that means that the certificate hasn’t been revoked. The status will be
revoked for revoked certificates.
The warning message about the missing nonce is telling you that OpenSSL wanted to use a nonce as a protection against replay attacks, but the server in question did not reply with one. This generally happens because CAs want to improve the performance of their OCSP responders. When they disable the nonce protection (the standard allows it), OCSP responses can be produced (usually in batch), cached, and reused for a period of time.
You may encounter OCSP responders that do not respond successfully to the previous command line. The following suggestions may help in such situations.
Some servers cannot handle nonce requests and respond with errors. OpenSSL will request a nonce by default. To disable nonces, use the
-no_nonce command-line switch.
Although most OCSP servers respond to HTTP requests that don’t specify the correct hostname in the
Host header, some don’t. If you encounter an error message that includes an HTTP error code (e.g., 404), try adding the hostname to your OCSP request. You can do this with the help of the
With the previous two points in mind, the final command to use is the following:
OCSP stapling is an optional feature that allows a server certificate to be accompanied by an OCSP response that proves its validity. Because the OCSP response is delivered over an already existing connection, the client does not have to fetch it separately.
OCSP stapling is used only if requested by a client, which submits the
status_request extension in the handshake request. A server that supports OCSP stapling will respond by including an OCSP response as part of the handshake.
When using the
s_client tool, OCSP stapling is requested with the
The OCSP-related information will be displayed at the very beginning of the connection output. For example, with a server that does not support stapling you will see this line near the top of the output:
With a server that does support stapling, you will see the entire OCSP response in the output:
The certificate status
good means that the certificate has not been revoked.
Checking certificate verification with a Certificate Revocation List (CRL) is even more involved than doing the same via OCSP. The process is as follows:
Obtain the certificate you wish to check for revocation.
Obtain the issuing certificate.
Download and verify the CRL.
Look for the certificate serial number in the CRL.
The first steps overlap with OCSP checking; to complete them follow the instructions in the section called “Checking OCSP Revocation”.
The location of the CRL is encoded in the server certificate; look for the “X509v3 CRL Distribution Points” section in the text output. For example:
Then fetch the CRL from the CA:
Verify that the CRL is valid (i.e., signed by the issuer certificate):
Now, determine the serial number of the certificate you wish to check:
At this point, you can convert the CRL into a human-readable format and inspect it manually:
The CRL starts with some metadata, which is followed by a list of revoked certificates, and it ends with a signature (which we verified in the previous step). If the serial number of the server certificate is on the list, that means it had been revoked.
If you don’t want to look for the serial number visually (some CRLs can be quite long), grep for it, but be careful that your formatting matches that used by the
crl tool. For example:
In TLS, renegotiation is a failed feature that was responsible for several protocol weaknesses, some of which are quite easy to exploit. TLS 1.3 no longer supports renegotiation, but there are still older servers out there that support it with earlier protocol revisions.
s_client tool has a couple of features that can assist you with manual testing of renegotiation. First of all, when you connect, the tool will report if the remote server supports secure renegotiation. This is because a server that supports secure renegotiation indicates its support for it via a special TLS extension that is exchanged during the handshake phase. When support is available, the output may look like this:
If secure renegotiation is not supported, the output will be slightly different:
Because TLS 1.3 doesn’t support renegotiation, the
s_client tool will always give a negative answer if this protocol version is negotiated. To ensure reliable results, use the
-no_tls1_3 switch to force negotiation of an earlier protocol version.
Even if the server indicates support for secure renegotiation, you may wish to test whether it also allows clients to initiate renegotiation. Client-initiated renegotiation is a protocol feature that doesn’t serve any purpose in practice (because the server can always initiate renegotiation when it is needed) and makes the server more susceptible to denial of service attacks.
To initiate renegotiation, after the TLS handshake is complete, type an
R character on a line by itself. For example, assuming we’re talking to an HTTP server, you can type the first line of a request, initiate renegotiation, and then finish the request. Here’s what that looks like when talking to a web server that supports client-initiated renegotiation:
When renegotiation is taking place, the server will send its certificates to the client again. You can see the verification of the certificate chain in the output. The next line after that continues with the
Host request header. Seeing the web server’s response is the proof that renegotiation is supported. Because of the various ways the renegotiation issue was addressed in various versions of SSL/TLS libraries, servers that do not support renegotiation may break the connection or may keep it open but refuse to continue to talk over it (which usually results in a timeout).
A server that does not support renegotiation will flatly refuse the second handshake on the connection:
At the time of writing, the default behavior for OpenSSL is to connect to servers that don’t support secure renegotiation; it will also accept both secure and insecure renegotiation, opting for whatever the server is able to do. If renegotiation is successful with a server that doesn’t support secure renegotiation, you will know that the server supports insecure client-initiated renegotiation.
The most reliable way to test for insecure renegotiation is to use the method described in this section, but with a version of OpenSSL that was released before the discovery of insecure renegotiation (e.g., 0.9.8k). I mention this because there is a small number of servers that support both secure and insecure renegotiation. This vulnerability is difficult to detect with modern versions of OpenSSL, which always prefer the secure option.
You can test for Heartbleed manually with OpenSSL or by using one of the tools designed for this purpose. There are now many utilities available, because Heartbleed is very easy to exploit. But, as usual with such tools, there is a question of their accuracy. There is evidence that some tools fail to detect vulnerable servers.32 Given the seriousness of Heartbleed, it’s best to either test manually or by using a tool that gives you full visibility of the process. I am going to describe an approach you can use with only a modified version of OpenSSL.
Some parts of the test don’t require modifications to OpenSSL, assuming you have a version that supports the Heartbeat protocol (starting with 1.0.1, but before 1.1.0). For example, to determine if the remote server supports the Heartbeat protocol, use the
-tlsextdebug switch to display server extensions when connecting:
A server that does not return the heartbeat extension is not vulnerable to Heartbleed. To test if a server responds to heartbeat requests, use the
-msg switch to request that protocol messages are shown, connect to the server, wait until the handshake completes, then type
B and press return:
This output shows a complete heartbeat request and response. The second and third bytes in both heartbeat messages specify payload length. We submitted a payload of 18 bytes (12 hexadecimal) and the server responded with a payload of the same size. In both cases there were also additional 16 bytes of padding. The first two bytes in the payload make the sequence number, which OpenSSL uses to match responses to requests. The remaining payload bytes and the padding are just random data.
To detect a vulnerable server, you’ll have to prepare a special version of OpenSSL that sends an incorrect payload length. Vulnerable servers take the declared payload length and respond with that many bytes irrespective of the length of the actual payload provided.
At this point, you have to decide if you want to build an invasive test (which exploits the server by retrieving some data from the process) or a noninvasive test. This will depend on your circumstances. If you have permission for your testing activities, use the invasive test. With it, you’ll be able to see exactly what is returned, and there won’t be room for errors. For example, some versions of GnuTLS support Heartbeat and will respond to requests with incorrect payload length, but they will not actually return server data. A noninvasive test can’t reliably diagnose that situation.
The following patch against OpenSSL 1.0.1h creates a noninvasive version of the test:
To build a noninvasive test, increase payload length by up to 16 bytes, or the length of the padding. When a vulnerable server responds to such a request, it will return the padding but nothing else. To build an invasive test, increase the payload length by, say, 32 bytes. A vulnerable server will respond with a payload of 50 bytes (18 bytes sent by OpenSSL by default, plus your 32 bytes) and send 16 bytes of padding. By increasing the declared length of the payload in this way, a vulnerable server will return up to 64 KB of data. A server not vulnerable to Heartbleed will not respond.
To produce your own Heartbleed testing tool, unpack a fresh copy of OpenSSL source code, edit
ssl/t1_lib.c to make the change as in the patch, compile as usual, but don’t install. The resulting
openssl binary will be placed in the
apps/ subdirectory. Because it is statically compiled, you can rename it to something like
openssl-heartbleed and move it to its permanent location.
Here’s an example of the output you’d get with a vulnerable server that returns 16 bytes of server data (in bold):
What Is Openssl
If you want to see more data retrieved in a single response, increase the payload length, recompile, and test again. Alternatively, to retrieve another batch of the same size, use the
B command again.
Starting from OpenSSL 1.0.2, when you connect to a server, the
s_client command prints the strength of the ephemeral Diffie-Hellman key if one is used. Thus, to determine the strength of server’s DH parameters, all you need to do is connect to it while offering only suites that use the DH key exchange. For example:
Servers that support export suites might actually offer even weaker DH parameters. To check for that possibility, connect using your old OpenSSL33 while offering only export DHE suites:
This command should fail with well-configured servers. Otherwise, you’ll probably see the server offering to negotiate insecure 512-bit DH parameters.
 Hardenize (retrieved 31 August 2020)
 Do note that when connecting to a TLS v1.3 server, the protocol information may not appear immediately on the connection. Instead, it will be printed when the session ticket is received, which may take a couple of seconds with some servers.
 Out of five cipher suites that TLS v1.3 supports, OpenSSL enables only three by default. The remaining two are CCM suites, which are intended for use with embedded systems, in which every little bit of performance and battery life matters. These suites are not worth using for other use cases—especially the CCM_8 suite, which reduces the strength of authentication.
 RFC 7919, which came out in 2016, redefined the
elliptic_curves TLS extension to support finite field groups and changed the extension name to
supported_groups. Although this extension applies to TLS 1.2, support for it is not widespread.
 New Adventures in DNSSEC and DANE (Jan Schaumann, retrieved 2 October 2020)
 s_client -reconnect Option Is Broken with TLSv1.3 (OpenSSL; retrieved 31 August 2020)
Openssl Website Examples
 Bugs in Heartbleed detection scripts (Shannon Simpson and Adrian Hayter, 14 April 2014)
Openssl Generate Website Certificate
 Support for EXPORT cipher suites was removed in OpenSSL 1.1.0.