TLS over REST ============= Service for inspecting the TLS configuration of publicly accessible HTTPS hosts. QUICK START ----------- Current API: https://v1.tls.rest/ Inspect a host: GET https://v1.tls.rest/{host} For example: https://v1.tls.rest/google.com or: curl https://v1.tls.rest/google.com The value after the slash is a hostname, not a URL. GOOD https://v1.tls.rest/google.com GOOD https://v1.tls.rest/api.github.com BAD https://v1.tls.rest/https://google.com BAD https://v1.tls.rest/google.com/search BAD https://v1.tls.rest/google.com:8443 All inspections are performed against port 443. WHAT DOES IT ACTUALLY DO? ------------------------- tls.rest makes a real TLS connection to the requested host. It doesn't simply fetch a certificate and stop there. The service collects information about the connection, negotiated TLS session, supported protocol versions, certificate chain, certificate properties and verification result. A typical response is split into a few major areas: +----------------+----------------------------------------------------+ | Section | Contains | +----------------+----------------------------------------------------+ | target | Host, port and resolved endpoint | | connection | Connection state, timing and remote address | | tls | Negotiated TLS session and protocol probes | | verification | Certificate trust / verification result | | certificates | Certificate chain and certificate metadata | | inspection | Inspection timestamp and total duration | +----------------+----------------------------------------------------+ For example, an inspection may tell you that a server negotiated TLS 1.3 using TLS_AES_256_GCM_SHA384 while also showing that TLS 1.2 is supported and TLS 1.0 and TLS 1.1 are not. The response can also include the complete certificate chain, SANs, fingerprints, public key information, validity periods, certificate extensions, issuer relationships and the PEM representation of certificates. In other words, the response can get fairly large. That is intentional. TLS PROTOCOL PROBING -------------------- tls.rest independently probes the major TLS protocol versions supported by the runtime. At the moment an inspection can contain results for: TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3 A result can therefore look conceptually like this: +---------+-----------+ | Version | Supported | +---------+-----------+ | TLS 1.0 | no | | TLS 1.1 | no | | TLS 1.2 | yes | | TLS 1.3 | yes | +---------+-----------+ For supported protocols, tls.rest may also report the protocol and cipher that were negotiated during that specific probe. The duration of individual probes is included where available. CERTIFICATES ------------ Certificate inspection goes considerably further than just showing an expiration date. For certificates in the discovered chain, tls.rest can expose information such as: subject and issuer serial number certificate role validity period days remaining signature algorithm Subject Alternative Names key usage extended key usage CA constraints fingerprints public key type and size EC curve information Authority Information Access CRL distribution points certificate policies hostname matching PEM certificate data The API also describes relationships between certificates in the discovered chain and whether those signatures could be validated. The exact information available depends on the certificate and remote server. VERIFICATION ------------ tls.rest first attempts to connect using normal certificate verification. If verification succeeds, the result can be reported as trusted and valid. If normal verification fails, tls.rest may continue inspecting the endpoint without normal verification so that there is still something useful to look at. This is important. A broken certificate is one of the situations where a TLS inspection tool is most useful. An expired certificate, self-signed certificate, hostname mismatch, incomplete chain or untrusted issuer should not automatically make the inspection itself useless. Where possible, tls.rest will still collect the certificate and connection information and report the verification problem in the response. tls.rest reports what it sees. It does not assign an A+, B, C or other simplified TLS security grade. CONNECTION INFORMATION ---------------------- The API also exposes information about the underlying connection. Depending on the result, this can include: remote address connection success connection duration timeout state stream information negotiated protocol negotiated cipher cipher strength DNS information and discovered IPv4 / IPv6 addresses may also be included by the inspection. HTTP STATUS CODES ----------------- For normal use, the two responses you are most likely to care about are: +--------+-----------------------------------------------------------+ | Status | Meaning | +--------+-----------------------------------------------------------+ | 200 | The TLS inspection completed and JSON was returned. | | 500 | The inspection could not be completed. | +--------+-----------------------------------------------------------+ A 500 does not necessarily mean that tls.rest itself is down. One of the most common reasons is simply that the requested hostname does not exist, cannot be resolved, cannot be reached, or does not provide a TLS service that can be inspected. For example: https://v1.tls.rest/this-domain-probably-does-not-exist.invalid may result in an inspection error because there is nothing useful for the service to connect to. If you receive a 500 and want to know whether the API itself is alive, check the health endpoint: GET https://v1.tls.rest/health or: curl https://v1.tls.rest/health Think of the distinction like this: /example.com -> "Can tls.rest inspect this server?" /health -> "Is tls.rest itself working?" A failed target inspection and a failed tls.rest service are not necessarily the same thing. CACHING ------- TLS inspections involve DNS resolution, network connections, certificate processing and several protocol probes. Repeating all of that every time somebody asks about the same hostname would be unnecessary. Inspection results are therefore cached for 24 hours. Successful inspection responses contain: X-Cache: MISS when tls.rest performed a fresh inspection, or: X-Cache: HIT when the response came from the cache. For example: $ curl -I https://v1.tls.rest/google.com X-Cache: HIT The cache is per hostname. This means repeated requests for the same host are cheap while still allowing the service to periodically re-inspect its TLS configuration. BAD TLS IS STILL INTERESTING ---------------------------- A TLS inspection service would not be particularly interesting if you could only point it at correctly configured servers. badssl.com maintains a collection of deliberately unusual and broken TLS endpoints that are useful for testing clients and TLS tooling. You can point tls.rest at them directly. Expired certificate: https://v1.tls.rest/expired.badssl.com Self-signed certificate: https://v1.tls.rest/self-signed.badssl.com Certificate signed by an untrusted root: https://v1.tls.rest/untrusted-root.badssl.com Hostname mismatch: https://v1.tls.rest/wrong.host.badssl.com Incomplete certificate chain: https://v1.tls.rest/incomplete-chain.badssl.com You can also experiment with protocol-specific endpoints: https://v1.tls.rest/tls-v1-0.badssl.com https://v1.tls.rest/tls-v1-1.badssl.com https://v1.tls.rest/tls-v1-2.badssl.com And different TLS configuration profiles: https://v1.tls.rest/mozilla-old.badssl.com https://v1.tls.rest/mozilla-intermediate.badssl.com https://v1.tls.rest/mozilla-modern.badssl.com These are useful for seeing how tls.rest behaves when the target is not a normal modern HTTPS server. Not every unusual target is guaranteed to produce a complete inspection. That is part of the point. USING THE API ------------- curl is probably the fastest way to try it: curl https://v1.tls.rest/google.com With jq: curl -s https://v1.tls.rest/google.com | jq Only interested in verification? curl -s https://v1.tls.rest/google.com | jq '.verification' Protocol support? curl -s https://v1.tls.rest/google.com | jq '.tls.protocols' The negotiated TLS session? curl -s https://v1.tls.rest/google.com | jq '.tls.negotiated' Certificate chain? curl -s https://v1.tls.rest/google.com | jq '.certificates.chain' From PHP: $json = file_get_contents( 'https://v1.tls.rest/google.com' ); $tls = json_decode($json, true); echo $tls['tls']['negotiated']['protocol']; From JavaScript: const response = await fetch( 'https://v1.tls.rest/google.com' ); const tls = await response.json(); console.log(tls.tls.negotiated.protocol); WHAT TLS.REST IS FOR -------------------- tls.rest is meant to be a small building block. You can use it manually when debugging a server, from a deployment script, inside a monitoring system, from CI/CD, from an internal dashboard, or as the backend for your own TLS tooling. For example, a deployment check could inspect a hostname after deployment and verify that TLS 1.2 and TLS 1.3 are available. A monitoring service could periodically inspect the certificate validity period. A debugging tool could display the exact chain returned by a server. Or you can just curl a domain because you want to know what is happening on the other side of port 443. WHAT TLS.REST IS NOT -------------------- tls.rest is not a vulnerability scanner. It is not a penetration-testing service. It does not attempt to decide whether your infrastructure is "secure". It does not replace understanding the TLS configuration being inspected. It collects technical information and returns it in a machine-readable form. What you do with that information is up to you. AVAILABILITY ------------ TLS in the real world is messy. Servers can close connections unexpectedly, DNS can fail, firewalls can drop packets, certificates can be malformed, protocol negotiation can fail and remote services can behave differently depending on network conditions. Because of that, not every hostname is guaranteed to produce a complete inspection. When something looks wrong, check: https://v1.tls.rest/health If health is OK but inspecting a particular hostname fails, the problem is probably related to that inspection rather than the API as a whole. VERSIONING ---------- The current public API version is: v1 Base URL: https://v1.tls.rest/ The version is part of the API hostname intentionally. Future incompatible versions can therefore exist separately without silently changing the behavior expected by clients using v1. AUTHORS ------- Kroatenwerk Gruppe (https://kroatenwerk.com)