Curious Pandas

Two TLS errors, one message

A wrong name and an untrusted issuer look identical in a browser and in curl. One verify code tells them apart, and they have opposite fixes.

15 min+40 XP for finishing

During the TLS stage the server hands over a certificate. It says, roughly, “I am shop.bamboo.example, and Bamboo Root CA vouches for me.” Your machine checks two separate things:

  1. The name. Does the certificate list the name you asked for? Certificates carry their names in a field called the Subject Alternative Name (SAN).
  2. The trust. Can it follow the chain of signatures up to a root certificate that your machine already trusts? Your operating system and browser ship with a list of trusted roots, the trust store.
Visual guideTwo checks on one certificate
Two checks on one certificateThe server's certificate for shop.bamboo.example is signed by an intermediate, which is signed by a root. Check one compares the name you asked for with the certificate's name list; a miss is verify code 62. Check two follows the signatures up and needs the root to be in your trust store; a miss is verify code 20.server certificateshop.bamboo.exampleintermediateBamboo Issuing CAroot certificateBamboo Root CAyour trust storeroots you trustcheck 1: namemissing: code 62check 2: trustnot trusted: code 20signed bysigned bylisted in?SAN listTwo checks on one certificateThe server's certificate for shop.bamboo.example is signed by an intermediate, which is signed by a root. Check one compares the name you asked for with the certificate's name list; a miss is verify code 62. Check two follows the signatures up and needs the root to be in your trust store; a miss is verify code 20.server certificateshop.bamboo.exampleintermediateBamboo Issuing CAroot certificateBamboo Root CAyour trust storeroots you trustcheck 1: namemissing: code 62check 2: trustnot trusted: code 20signed bysigned bylisted in?SAN list
  1. The server hands over its certificate: the names it is valid for, and who signed it.
  2. Check one: is the name you asked for in its name list? If not, OpenSSL reports 62. The fix is a new certificate.
  3. Check two follows the signatures upward. Real chains usually have an intermediate between the server and the root.
  4. The chain must end at a root already in your trust store. If it does not, you get 20. The fix is the trust store, or the chain the server sends.

Fail either one and you get the same scary browser page and the same curl exit code: 60. That sameness is the trap. The two failures have opposite fixes, and fixing the wrong one wastes an afternoon.

Same symptom, different code

OpenSSL’s s_client does tell them apart, with a numbered verify code:

Verify code Meaning Fix
62 hostname mismatch the chain is trusted; the name isn’t on the certificate edit the certificate: add the name
20 unable to get local issuer certificate the name is right; nothing you trust signed it fix the trust store (or the chain the server sends)

Codes 18 to 21 are the family of trust failures. 18, for example, is a self-signed certificate. The rule from tilt lab 04 is short: 62 means go edit the certificate; 18 to 21 mean go fix the trust store.

Name or trust?real curl output
    $ curl -v https://shop.bamboo.example/

    Check yourself+10 XP

    curl says exit 60 for your internal site. openssl s_client says 'Verify return code: 62 (hostname mismatch)'. What do you change?

    Check yourself+10 XP

    A brand-new laptop gets code 20 against a site that works on every other machine in the office. Most likely cause?

    Do it for real · your machine+50 XP bonus

    Everything above ran in your browser. Now do it on a real cluster with tilt lab 04-break-tls (profile minimal). You need Docker, kind and Tilt, about 15 GB of free disk and 8 GB of spare RAM. Setup guide · Can my machine run it?

    Tilt lab 04 does this for real, against a certificate that cert-manager issues on your cluster:

    ./labs/04-break-tls/break.sh mismatch
    ./labs/04-break-tls/probe.sh hello.localhost             # Verify return code: 62
    ./labs/04-break-tls/fix.sh
    ./labs/04-break-tls/probe.sh hello.localhost --untrusted # Verify return code: 20
    ./scripts/platform.sh lab 04

    Without the platform, the public test site badssl.com has one host per failure:

    openssl s_client -connect wrong.host.badssl.com:443 -servername wrong.host.badssl.com -verify_hostname wrong.host.badssl.com </dev/null | grep "Verify return"
    Self-reported. We can't see your machine, and we don't want to. This is a bonus, never required.

    Sources

    Finished reading?

    Missions and quizzes above earn their own XP. This marks the lesson done.