José: C Implementation of JOSE Standards

repository·master·Indexed 42 days ago

https://github.com/latchset/jose

A C-language implementation of the Javascript Object Signing and Encryption (JOSE) standards. It provides a CLI and tools for working with JSON Web Signature (JWS), JSON Web Encryption (JWE), JSON Web Key (JWK), JSON Web Algorithms (JWA), and JSON Web Token (JWT), supporting RFCs 7515, 7516, 7517, 7518, 7519, 7520, and 7638.

Tokens
26.6K
Snippets
103
Records
119
Agent score
52%

What's inside José

  1. Overview of the jose CLI utility

    master

    The jose command-line utility is a C-language implementation of the Javascript Object Signing and Encryption (JOSE) standards. It provides tools for managing keys, performing encoding/decoding, and handling cryptographic operations like signing, verification, encryption, and decryption.

    It implements the following RFC standards:

    • RFC 7515: JSON Web Signature (JWS)
    • RFC 7516: JSON Web Encryption (JWE)
    • RFC 7517: JSON Web Key (JWK)
    • RFC 7518: JSON Web Algorithms (JWA)
    • RFC 7519: JSON Web Token (JWT)
    • RFC 7520: Examples of Protecting Content Using JOSE
    • RFC 7638: JSON Web Key (JWK) Thumbprint
  2. Overview of José

    master

    José is a C-language implementation of the Javascript Object Signing and Encryption (JOSE) standards. It is designed to be extensively tested against RFC test vectors and supports the following standards:

    • RFC 7515: JSON Web Signature (JWS)
    • RFC 7516: JSON Web Encryption (JWE)
    • RFC 7517: JSON Web Key (JWK)
    • RFC 7518: JSON Web Algorithms (JWA)
    • RFC 7519: JSON Web Token (JWT)
    • RFC 7520: Examples of JOSE
    • RFC 7638: JSON Web Key (JWK) Thumbprint
  3. Use the jose-fmt CLI to manipulate JSON

    master

    The jose fmt command is a stack-based utility for building and parsing JSON objects from the command line. It operates on a stack where most commands act on the TOP item or the PREV item.

    Mental Model:

    • Commands push new values onto the stack or modify the current TOP.
    • Assertions (e.g., -A for array) check the type of the TOP item.
    • The program returns 0 on success or the index of the option that failed.
    jose fmt [OPTIONS]
  4. Sign a payload with jose jws sig

    master

    The jose jws sig command signs a payload using one or more JSON Web Keys (JWKs). You can provide the payload in its decoded form using the -I (or --detached) option, or embed it within an existing JWS using the -i (or --input) option.

    Key behaviors:

    • Detached JWS: Use the -O (or --detach) option to write the decoded payload to a file (or stdout) without including it in the resulting JWS.
    • Compact Serialization: If using a single key (-k), you can output the result in JWS Compact Serialization using the -c (or --compact) flag.
    • Template-based construction: You can provide JWS templates (-i) or JWS Signature Object templates (-r) to specify extended metadata. Note that the command automatically encodes the JWS Protected Header during the process.
    # Sign data with a symmetric key using JWE JSON Serialization
    $ jose jwk gen -i '{"alg":"HS256"}' -o key.jwk
    $ jose jws sig -I msg.txt -k key.jwk -o msg.jws
    
    # Sign data using detached JWE Compact Serialization
    $ jose jws sig -I msg.txt -k key.jwk -O /dev/null -c -o msg.jws
    
    # Sign with two keys
    $ jose jwk gen -i '{"alg":"ES256"}' -o ec.jwk
    $ jose jwk gen -i '{"alg":"RS256"}' -o rsa.jwk
    $ jose jws sig -I msg.txt -k ec.jwk -k rsa.jwk -o msg.jws
  5. Convert JWS serialization formats with jose jws fmt

    master

    The jose jws fmt command allows you to convert a JSON Web Signature (JWS) between different serialization formats. Specifically, you can use it to:

    • Attach a payload to a detached JWS.
    • Detach a payload from an existing JWS.
    • Convert between JWS Compact Serialization and JWS JSON Serialization.

    To output in Compact Serialization, use the -c or --compact flag. By default, the command outputs JSON Serialization.

    # Attach payload to a detached JWS and emit JWS Compact Serialization
    $ jose jws fmt -i msg.jws -I msg.txt -o compact.jws -c
    
    # Detach payload from a JWS
    $ jose jws fmt -i msg.jws -o detached.jws -O msg.txt
  6. Build and Install José from Source

    master

    José uses the meson build system. You will need ninja and meson installed.

    Standard Installation

    $ mkdir build && cd build
    $ meson setup .. --prefix=/usr
    $ ninja
    $ sudo ninja install

    FreeBSD / HardenedBSD / OPNsense

    On these platforms, you must first install dependencies via pkg as root.

    Dependencies: meson, pkgconf, jansson, openssl, asciidoc, jq.

    # (as root) 
    # pkg install meson pkgconf jansson openssl asciidoc jq
    
    $ mkdir build && cd build
    $ meson setup .. --prefix=/usr/local
    $ ninja
    $ meson test
    # (as root)
    # ninja install

    Note: After installation, the binary requires jansson and openssl to run, but does not require meson or pkgconf.

  7. Generate JWKs using the jose-jwk-gen CLI

    master

    The jose jwk gen command creates random JSON Web Keys (JWK) based on provided templates.

    Generation Strategies

    1. Algorithm-based (Recommended): Specify the alg property in your template. This is the preferred method because the tool automatically emits the appropriate key_ops parameter and assists with algorithm inference during signing or encryption.

    2. Key Type-based: Specify the kty (key type) property along with type-specific parameters (e.g., bits for RSA, crv for EC). Note that non-standard generation parameters like bytes or bits will be excluded from the final output JWK.

    Output Behavior

    • If a single template is provided, the output is a single JWK.
    • If multiple templates are provided, the output is a JWKSet containing all generated keys.
    • Use the -s or --set flag to force the output to always be a JWKSet.
    # Generate a key by algorithm
    $ jose jwk gen -i '{"alg":"HS256"}' -o oct.jwk
    
    # Generate a key by key type and parameters
    $ jose jwk gen -i '{"kty":"RSA","bits":4096}' -o rsa.jwk
  8. Encrypt data with `jose jwe enc`

    master

    The jose jwe enc command encrypts plaintext using one or more JSON Web Keys (JWK) or passwords.

    Key Features

    • Multi-key support: You can specify multiple keys (-k) or passwords (-p). Decryption will succeed if any one of the provided keys is valid.
    • Serialization modes: By default, it uses JSON Serialization. Use the -c or --compact flag to output the JWE using Compact Serialization (requires only one key).
    • Detached Ciphertext: Use the -O flag to create a detached JWE. The decoded ciphertext will be written to the specified output and excluded from the JWE itself.
    • Template-based construction: You can provide templates for the JWE itself (-i) or for the JWE Recipient Object (-r).
    • Automatic Algorithm Inference: If no templates are provided, the command automatically infers the correct alg and enc parameters from the provided keys.
    • Header-driven behavior: Specifying certain JOSE Header Parameters in templates (like zip) will change the command's behavior (e.g., compressing the plaintext before encryption).
    ### Encrypt with a symmetric key (JSON Serialization)
    $ jose jwk gen -i '{"alg":"A128GCM"}' -o key.jwk
    $ jose jwe enc -I msg.txt -k key.jwk -o msg.jwe
    
    ### Encrypt with a password (Compact Serialization)
    $ jose jwe enc -I msg.txt -p -c -o msg.jwe
    
    ### Compress plaintext before encryption
    $ jose jwe enc -i '{"protected":{"zip":"DEF"}}' -I msg.txt -k key.jwk -o msg.jwe
    
    ### Encrypt with multiple keys and passwords
    $ jose jwk gen -i '{"alg":"ECDH-ES+A128KW"}' -o ec.jwk
    $ jose jwk gen -i '{"alg":"RSA1_5"}' -o rsa.jwk
    $ jose jwe enc -I msg.txt -p -k ec.jwk -p -k rsa.jwk -o msg.jwe
  9. Verify a JWS using the jose jws ver command

    master

    The jose jws ver command is used to verify a JSON Web Signature (JWS) using one or more JSON Web Keys (JWKs).

    Verification Logic

    • Default Behavior: If multiple keys are provided via -k, the command succeeds if any of the provided JWKs successfully verify the signature.
    • All-Keys Mode: If the -a or --all flag is used, the command succeeds only if all provided JWKs successfully verify the signature.

    Detached JWS

    If the JWS is 'detached' (the payload is stored externally in binary form rather than inside the JWS), you must provide the payload using the -I or --detached option.

    Security Warning

    If you use the -O or --detach option to output the decoded payload, the payload will be output regardless of whether the signature is valid. Always check the command's return value before trusting the output data.

    jose jws ver -i JWS [-I PAY] -k JWK [-a] [-O PAY]
  10. Decrypt a JWE using the jose-jwe-dec command

    master

    The jose jwe dec command is used to decrypt a JSON Web Encryption (JWE) object using either a JSON Web Key (JWK), a JWK Set, or a password. Decryption succeeds if any provided key is capable of performing the decryption.

    Detached JWEs

    If you are working with a detached JWE (where the ciphertext is stored in binary form external to the JWE itself), you must provide the path to the decoded ciphertext using the -I or --detached flag.

    Security Warning

    When using the -O option to output plaintext, the output begins before ciphertext validation is complete. You must check the return value of the command to ensure decryption was successful before trusting or using the output data.

    # Decrypt a JWE with a JWK
    $ jose jwe dec -i msg.jwe -k rsa.key -O msg.txt
    
    # Decrypt a JWE with a password
    $ jose jwe dec -i msg.jwe -p -O msg.txt
    
    # Decrypt a JWE with either of two JWKs
    $ jose jwe dec -i msg.jwe -k ec.jwk -k rsa.jwk -O msg.txt
  11. Calculate JWK thumbprints with jose jwk thp

    master

    The jose jwk thp command is used to calculate the thumbprint of one or more JSON Web Keys (JWKs) or JWK Sets. You can provide input via a JSON string, a file, or standard input, and specify the hash algorithm to use. Thumbprints can be written to a file or standard output.

    jose jwk thp -i JWK [-H ALG] [-o THP]
  12. Handle input and output with the José CLI

    master

    The jose CLI provides flexible ways to specify input and output sources:

    • Standard Input/Output: Use - to represent stdin for input or stdout for output.
    • Files: Provide a file path to read from or write to.
    • Compact Format: Some commands can accept a compact JWS/JWE string (e.g., header.payload.signature) directly as an argument instead of a file.
    • JSON Objects: Commands can accept raw JSON strings or files containing JSON objects.