Skip to content

tls

stable

Utilities for working with PEM and DER certificate formats, computing SHA-256 and SHA-1 fingerprints, inspecting TLS protocol versions, listing cipher suites, and encoding/decoding base64 — all implemented in pure Rust with no external dependencies.

use plugin tls::{is_pem, pem_type, pem_to_der, …}
12 functions Cryptography
/ filter jk navigate Esc clear
Functions (12)
  1. is_pem Check whether a string contains a PEM block
  2. pem_type Extract the type label from a PEM header
  3. pem_to_der Decode PEM base64 body to raw DER bytes
  4. der_to_pem Encode DER bytes into a PEM string
  5. fingerprint_sha256 Compute SHA-256 fingerprint of DER bytes
  6. fingerprint_sha1 Compute SHA-1 fingerprint of DER bytes
  7. parse_pem_sections Parse all PEM sections from a multi-block string
  8. pem_count Count PEM sections in a string
  9. cipher_suites Return a list of known TLS cipher suites
  10. protocol_version Get version details for a TLS protocol name
  11. base64_encode Encode bytes or a string to base64
  12. base64_decode Decode a base64 string to bytes

Overview

tls is a dependency-free toolkit for the low-level plumbing around X.509 certificates and TLS metadata. Its core concept is the pair of certificate encodings: PEM (the base64 text wrapped in -----BEGIN ...----- markers) and DER (the raw binary the base64 decodes to). The plugin converts freely between the two, computes the SHA-256 and SHA-1 fingerprints that identify a certificate, and exposes static reference data about TLS protocol versions and cipher suites. Everything is pure Rust with no OpenSSL or system dependency, so it behaves identically across native, VM, and WASM backends.

The mental model is a small pipeline: take certificate text, check it with is_pem / pem_type, decode it to DER bytes with pem_to_der (or split a chain with parse_pem_sections), then fingerprint the DER with fingerprint_sha256. The base64 helpers (base64_encode / base64_decode) and the protocol_version / cipher_suites lookups round out the set for general encoding and TLS introspection tasks.

Common patterns

Identify a certificate and fingerprint it in one pass:

use plugin tls::{is_pem, pem_type, pem_to_der, fingerprint_sha256}

let cert = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
if is_pem(cert) {
  let der = pem_to_der(cert)
  print("{pem_type(cert)} -> {fingerprint_sha256(der)}")
}

Walk every block in a certificate chain and report each one:

use plugin tls::{pem_count, parse_pem_sections, fingerprint_sha1}

let chain = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
print("blocks: {pem_count(chain)}")
for section in parse_pem_sections(chain) {
  print("{section["type"]}: {fingerprint_sha1(section["der_bytes"])}")
}

Flag a connection that negotiated a deprecated protocol version:

use plugin tls::{protocol_version}

let info = protocol_version("TLS 1.0")
if info["deprecated"] {
  print("warning: {info["hex"]} is deprecated")
}

Check whether a string contains a PEM block

Returns true if the string contains both -----BEGIN and -----END markers, indicating it holds at least one PEM block.

use plugin tls::{is_pem}

let cert_text = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
print(is_pem(cert_text))
print(is_pem("just a plain string"))

Extract the type label from a PEM header

Extracts the type label from the first -----BEGIN <TYPE>----- header found in the string. Returns strings like "CERTIFICATE", "PRIVATE KEY", or "RSA PRIVATE KEY".

use plugin tls::{pem_type}

let pem = "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----"
let t = pem_type(pem)
print(t)

Decode PEM base64 body to raw DER bytes

Strips the PEM header/footer and decodes the base64-encoded body, returning the raw DER binary. Only the first PEM block is decoded; use parse_pem_sections for multi-block input.

use plugin tls::{pem_to_der, fingerprint_sha256}

let pem = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
let der = pem_to_der(pem)
print(fingerprint_sha256(der))

Encode DER bytes into a PEM string

Wraps raw DER bytes into a PEM string with the given type label. The base64 body is line-wrapped at 64 characters per PEM convention.

use plugin tls::{pem_to_der, der_to_pem}

let pem_in = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
let der = pem_to_der(pem_in)
let pem_out = der_to_pem(der, "CERTIFICATE")
print(pem_out)

It also re-labels a block: decode a private key and re-emit it under a different type label without touching the key material:

use plugin tls::{pem_to_der, der_to_pem}

let key = "-----BEGIN PRIVATE KEY-----\nMIIE...\n-----END PRIVATE KEY-----"
let der = pem_to_der(key)
print(der_to_pem(der, "RSA PRIVATE KEY"))

Compute SHA-256 fingerprint of DER bytes

Computes the SHA-256 hash of the DER bytes and returns it as a colon-separated lowercase hex string (e.g. "ab:cd:ef:..."). This is the standard format used by browsers and TLS tools.

use plugin tls::{pem_to_der, fingerprint_sha256}

let pem = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
let der = pem_to_der(pem)
let fp = fingerprint_sha256(der)
print("SHA-256: {fp}")

Because it accepts any DER bytes, you can also fingerprint the output of a base64 decode directly without going through PEM:

use plugin tls::{base64_decode, fingerprint_sha256}

let der = base64_decode("MIIBdummyDERbase64...")
print("SHA-256: {fingerprint_sha256(der)}")

Compute SHA-1 fingerprint of DER bytes

Computes the SHA-1 hash of the DER bytes as a colon-separated hex string. SHA-1 fingerprints are still widely used for certificate identification despite SHA-1 being deprecated for signing.

use plugin tls::{pem_to_der, fingerprint_sha1}

let pem = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
let der = pem_to_der(pem)
print("SHA-1: {fingerprint_sha1(der)}")

Parse all PEM sections from a multi-block string

Parses all PEM blocks from a string (e.g. a certificate chain file) and returns a list of {type, der_bytes} tables, one per block.

use plugin tls::{parse_pem_sections}

let chain = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
let sections = parse_pem_sections(chain)
let first = sections[1]
print("Type: {first["type"]}")

Each entry carries the decoded der_bytes, so you can fingerprint every block of a chain in a loop:

use plugin tls::{parse_pem_sections, fingerprint_sha256}

let chain = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
for section in parse_pem_sections(chain) {
  print("{section["type"]}: {fingerprint_sha256(section["der_bytes"])}")
}

Count PEM sections in a string

Counts the number of -----BEGIN ...----- headers in the text, effectively counting how many PEM blocks are present.

use plugin tls::{pem_count}

let chain_pem = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
print("Sections: {pem_count(chain_pem)}")

Return a list of known TLS cipher suites

Returns a static list of well-known TLS cipher suites. Each entry is a table with name, protocol (e.g. "TLS 1.3"), and type (e.g. "AEAD"). Useful for validation and documentation.

use plugin tls::{cipher_suites}

let suites = cipher_suites()
let first = suites[1]
print("{first["name"]} ({first["protocol"]})")

Iterate the full table to list only the modern TLS 1.3 suites:

use plugin tls::{cipher_suites}

for suite in cipher_suites() {
  if suite["protocol"] == "TLS 1.3" {
    print(suite["name"])
  }
}

Get version details for a TLS protocol name

Returns version metadata for a TLS/SSL protocol name. Accepts "TLS 1.0", "TLS 1.1", "TLS 1.2", "TLS 1.3", "SSL 3.0" (and short forms like "1.2", "tls13"). Returns {major, minor, hex, deprecated}.

use plugin tls::{protocol_version}

let info = protocol_version("TLS 1.3")
print("Hex: {info["hex"]}, Deprecated: {info["deprecated"]}")

let old = protocol_version("TLS 1.0")
print("TLS 1.0 deprecated: {old["deprecated"]}")

Encode bytes or a string to base64

Encodes bytes or a string to standard base64. No line wrapping is applied to the output.

use plugin tls::{base64_encode, base64_decode}

let encoded = base64_encode("Hello, world!")
print(encoded)

It accepts raw bytes too, so it pairs with pem_to_der to re-encode a certificate body as a single unwrapped base64 line:

use plugin tls::{pem_to_der, base64_encode}

let pem = "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----"
let der = pem_to_der(pem)
print(base64_encode(der))

Decode a base64 string to bytes

Decodes a standard base64 string to raw bytes. Whitespace within the input is ignored. Raises an error on invalid characters or malformed padding.

use plugin tls::{base64_encode, base64_decode}

let encoded = base64_encode("Hello")
let raw = base64_decode(encoded)
print("Decoded {raw} bytes")
enespt-br