8000 GitHub - fisherdarling/pls: Pls just parse some certs.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fisherdarling/pls

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pls

pls is a human-first tool for working with x509 certificates and other WebPKI/TLS primitives. You ask it nicely to parse a file or get a server's certs and It Just Works.

TL;DR

Reading a chain of certificates:

pls:

pls parse ./test-data/certs/chain.pem

openssl:

openssl storeutl -noout -text -certs ./test-data/certs/chain.pem

It. Just. Works.

No fussing with arguments, no "whoops, the file is chain. Guess I need to manually split it up somehow". Or, "how do I connect to a server and just get its chain? Wait, I need to pipe some output into sed. Why is my terminal hanging? What's this debug stuff?"

Oh, and pls also handles certs mixed with yaml, json, or w/e just fine. Good luck getting that to work with openssl.

And because it's 2025, there's json output with the --json flag. If you pipe pls' output into another cli tool, json output is automatic.

pls parse ./test-data/certs/chain.pem | jq '.certs|map(.subject.name)'
[
  "CN=lan.fish",
  "C=US, O=Let's Encrypt, CN=E6",
  "C=US, O=Internet Security Research Group, CN=ISRG Root X2"
]

I'm still missing some fields in the json output, that's coming.

Chains are assumed. Yes it's annoying to put a .[0]| in front of jq filters, but for that everything just works if you end up "accidentally" parsing a chain.

It's also much more concise:

$ openssl x509 -in ./test-data/certs/lan-fish.pem -text -noout | wc -l
      73
$ pls parse ./test-data/certs/lan-fish.pem --text | wc -l
      25

Parsing certs in nearly any medium

As long as the ----BEGIN and ----END "headers" exist somewhere in the file, and the base64 characters in those headers are valid, pls can parse it.

pls will parse:

  • a stack of PEM certificates (a chain).
  • certs spread throughout a yaml file with multiple indentations
  • certs in escaped json
  • other PEM entities in a file. Things like public/private keys and CSRs.

Installation

Right now pls only supports Rust toolchain based installation:

cargo install --locked --git https://github.com/fisherdarling/pls

We're currently using a fork of boring which adds more support for reading x509 fields.

Examples

Parsing a cert

pls parse ./certs/cloudflare.pem

image

Coloring is a little weird with termshot.

Connect to a server and viewing its certificate (QUIC coming soon!)

pls connect 1.1.1.1

image

Easily force Post-Quantum Crypto for the handshake

pls connect 1.1.1.1 --pqc --no-cert

image

Use a specific curve list

pls connect 1.1.1.1 --curves X25519MLKEM768 --no-cert

image

JSON output

Unless another option is set, e.g. --pem or --text, pls will output json if stdout is not a TTY.

There's a ton of fields in the json output and many are redundant. The goal is to make writing jq filters very easy.

{
  "certs": [
    {
      "subject": {
        "name": "CN=lan.fish",
        "ski": "a5bc6f4ea76b6de4f56bcf85ec86921c85b852b7",
        "sans": {
          "dns": ["lan.fish", "p2p.lan.fish"]
        }
      },
      "serial": "0347bb00b7415c11d012f7ca5686100f4474",
      "issuer": {
        "name": "C=US, O=Let's Encrypt, CN=E6",
        "aki": "9327469803a951688e98d6c44248db23bf5894d2"
      },
      "not_before": "2025-01-03T13:18:47Z",
      "not_after": "2025-04-03T13:18:46Z",
      "expires_in": 3737794,
      "valid_in": -4038204,
      "valid": null,
      "verify_result": null,
      "ski": "a5bc6f4ea76b6de4f56bcf85ec86921c85b852b7",
      "aki": "9327469803a951688e98d6c44248db23bf5894d2",
      "public_key": {
        "bits": 256,
        "curve": "id-ecPublicKey",
        "type": "ec",
        "group": "prime256v1",
        "key": "02886615260d6c0d06713f3d9a90f51f2214b799a07bf732335ef793fa05192cad"
      },
      "key_usage": {
        "critical": true,
        "digital_signature": true,
        "content_commitment": false,
        "key_encipherment": false,
        "data_encipherment": false,
        "key_agreement": false,
        "key_cert_sign": false,
        "crl_sign": false,
        "encipher_only": false,
        "decipher_only": false,
        "extended": {
          "critical": false,
          "server_auth": true,
          "client_auth": true,
          "code_signing": false,
          "email_protection": false,
          "time_stamping": false,
          "ocsp_signing": false,
          "custom": []
        }
      },
      "signature": {
        "algorithm": "ecdsa-with-SHA384",
        "value": "3066023100ca00eb23cb0df9dc246ccbc5e98cb2d1630cb8f0c0d3f8bf251bc933bd3efcf1eb6dae7516caaa73793fa8b371b78160023100ee555bfcea977132ce2a96cb102d9aaeb6f3a615ffe20d3221f47ae383b9ebc6e7e2e13c144f5267d31dde16b96c66da"
      },
      "extensions": {},
      "sha256": "876172fb012989edbc93d2c4c34399f1dff9b5e90f0f30b9c6d2ed82ec184620",
      "sha1": "e317da2ee772c724754f489c4f06eb8f0fa14f37",
      "md5": "146f1fa78dee36f9421126e2a7cc589a",
      "pem": "</snip>"
    }
  ],
  "csrs": [],
  "private_keys": []
}

TODO

  • Parse and display PEM encoded entities:
    • x509 Certificates
    • CSRs
      • fingerprint: sha256 digest of DER
    • Public/Private Keys
      • fingerprint: sha256 digest of DER
  • Parse and display DER encoded entities
  • Automatically output JSON
  • Output PEM on request
  • Parse every file in a folder
  • Entity specific commands, rather than only a catch-call parse.
    • cert parse
    • csr parse
    • pub parse
    • priv/key parse

FAQ

Why does this use boringssl?

Because boringssl is awesome. If the library can't parse something that openssl, sorry about that.

Why the name pls?

After doing 12 cert rotations involving modifying and looking at random PEM in yaml, you start begging openssl to just pls do the right thing.

Why does openssl default to PEM output??? It's useless. And if you specify -text you still need to add -noout. What? Oh, and dealing with chains in a single file is clearly blasphemous.

And another gripe of mine is the usage of ssl in both openssl and boringssl. I refuse to put ssl in the name of this tool. There's a reason TLS exists. pls is close to tls while being short and sweet.

Why do you only support x509 v3?

In my rather short experience working with certificates, I've only every seen v3 x509 certs. I believe the spec is 20 years old now. I'm not putting in effort to support older versions.

The library doesn't support a curve!

If the curve is supported by boringssl, it's probably just not handled by pls. Please raise an issue.

The library panics on my cert!

The "parser" is rather opnionated (read: full of unwrap()s) on what's considered optional. If the cert is a useful variant of x509 v3, please open an issue and I'll see about fixing things / making it optional.

About

Pls just parse some certs.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

0