Inspect key, certificates, messages and the like

Sometimes you want a closer look on the objects sq works with, for instance if you want to troubleshoot a failing operation. sq offers two levels of details: inspect and the subcommand hierarchy under sq packet.

The workhorse of these two is sq inspect. It show a human readable extract of the object passed to it. The most general application is:

$ sq inspect FILE

FILE can be a certificate, a key, a message - it can be any file even a non-OpenPGP one:

$ sq inspect /etc/fstab 
/etc/fstab: No OpenPGP data.

The output of a certificate looks like this:

$ sq inspect bob.cert
bob.cert: OpenPGP Certificate.

      Fingerprint: 265BA2AB62FFF0B67AF62A70A9FE49218A6A88B0
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:31:56 UTC
  Expiration time: 2027-10-29 04:58:17 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: certification

           Subkey: 8600DB2A7FB8BFE5DAAA922884B61A3ABEACD605
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:31:56 UTC
  Expiration time: 2027-10-29 04:58:17 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: authentication

           Subkey: 60F64238FDD763AFF76677928A880E8E21CC6C3E
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:31:56 UTC
  Expiration time: 2027-10-29 04:58:17 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: signing

           Subkey: 41E5C9C3AC983EA9CC04649A9754F1AB759E21AF
  Public-key algo: ECDH
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:31:56 UTC
  Expiration time: 2027-10-29 04:58:17 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: transport encryption, data-at-rest encryption

           UserID: <bob@example.com>
   Certifications: 1, use --certifications to list

           UserID: Bob

If FILE is omitted sq inspect reads from STDIN.

$ echo "hello" | sq encrypt --for-email alice@example.com | sq inspect
-: Encrypted OpenPGP Message.

      Recipient: 70481B0CCFC64D03

In this example, we create an encrypted message on the fly. The message in clear ("hello") is passed through sq encrypt and then forwarded to sq inspect.

A revocation certificate looks like:

$ sq inspect bob.rev
bob.rev: Revocation Certificate.

      Fingerprint: 7C4A15AD3C51181E43B534DE120862007D362AF2
                   Revoked:
                    - No reason specified
                      On: 2024-10-28 11:36:16 UTC
                      Message: Unspecified
                   Invalid: No binding signature at time 2024-10-28T13:25:00Z
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:36:16 UTC

You can experiment with sq inspect - as it only reads data, it will not cause any damage.

Data from within the certificate store is also accessible:

$ sq inspect --cert 7C4A15AD3C51181E43B534DE120862007D362AF2
OpenPGP Certificate.
[...]

When inspecting certificates, certifications of this certificate are hidden. You can display certifications by passing --certifications to sq inspect.

$ sq inspect --cert 7C4A15AD3C51181E43B534DE120862007D362AF2 --certifications
OpenPGP Certificate.

      Fingerprint: 7C4A15AD3C51181E43B534DE120862007D362AF2
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:36:16 UTC
  Expiration time: 2027-10-29 05:02:37 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: certification

           Subkey: F753DAA5EE1633D6B6B7071F4ED3187E3CE8EC04
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:36:16 UTC
  Expiration time: 2027-10-29 05:02:37 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: signing

           Subkey: DF676EC1ADA16D84DF6B197881FE2BA966469B1E
  Public-key algo: EdDSA
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:36:16 UTC
  Expiration time: 2027-10-29 05:02:37 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: authentication

           Subkey: 3B5DE910F20C2D9A4989D15E90E3343A16CA864D
  Public-key algo: ECDH
  Public-key size: 256 bits
    Creation time: 2024-10-28 11:36:16 UTC
  Expiration time: 2027-10-29 05:02:37 UTC (creation time + 2years 11months 30days 9h 16m 45s)
        Key flags: transport encryption, data-at-rest encryption

           UserID: <bob@example.com>
    Certification: Creation time: 2024-10-28 11:38:35 UTC
                   Expiration time: 2029-10-28 16:42:30 UTC (after 5 years)
                   Trust depth: 1
                   Trust amount: 120
                   Regular expression: "<[^>]+[@.]example\\.com>$"
                   Alleged certifier: 188C014A41FD5FF4D83A35A0A879D7033A9B6293
                       <alice@example.com> (authenticated)
                   Hash algorithm: SHA512
    Certification: Creation time: 2024-10-28 11:36:25 UTC
                   Trust depth: 255
                   Trust amount: 120
                   Alleged certifier: B9C899C70BE20C10D794E924288ADA34F36309B1
                       Local Trust Root (authenticated)
                   Hash algorithm: SHA512
             Note: Certifications have NOT been verified!

Packet dump

There is a even deeper dive possible. You can list the packets an OpenPGP artifact (message, certificate, signature, etc) is comprised of.

In this example, we generate an encrypted message and display it's packet structure:

$ echo "hello" | sq encrypt --for-email bob@example.com | sq packet dump
Public-Key Encrypted Session Key Packet, new CTB, 94 bytes
    Version: 3
    Recipient: 90E3343A16CA864D
    Pk algo: ECDH
  
Public-Key Encrypted Session Key Packet, new CTB, 94 bytes
    Version: 3
    Recipient: 90E3343A16CA864D
    Pk algo: ECDH
  
Sym. Encrypted and Integrity Protected Data Packet, new CTB, 55 bytes
│   Version: 1
│   Session key: E2A9BB6A3A94127C240346792AE53806A722B45BCB8DEB1A249F8E43405F5D9C
│   Symmetric algo: AES-256
│   Decryption successful
│ 
├── Literal Data Packet, new CTB, 12 bytes
│       Format: Binary data
│       Content: "hello\n"
│     
└── Modification Detection Code Packet, new CTB, 20 bytes
        Digest: EA9382CBE41EB2A2F1B40E9E6C3529873B67FE8F
        Computed digest: EA9382CBE41EB2A2F1B40E9E6C3529873B67FE8F

The output of sq packet dump shows the wire format - the sequence and content of the different packets composing an OpenPGP artifact.

Objects from the certificate store are also available:

$ sq packet dump --cert 7C4A15AD3C51181E43B534DE120862007D362AF2

Like sq inspect sq packet dump only reads data, so it's save to experiment with it.