[CONTACT]

[ABOUT]

[POLICY]

gpg regex Followup Followup GPG Cac

Found at: demu.red:70/blog/007-gpg_cache_check.md

Title: How to check if your GPG key is in cache
Date: 2016-06-26 02:00
Category: gpg
Tags: gpg, unix, CLI, gpg-agent, awk, regex
**Followup [Part2]**  
**Followup [Part3]**  
###GPG Cache Checking
Until this week I had been using a *hacky* way of checking if my laptop GPG key was cached.
Well, it is more that I corrected my GPG set up by clearing my yubikey neo, and reconfiguring it to work again, at which point the reaction was no longer as desired.
####Digression: Yubikey Neo GPG Reset
Resetting the GPG Smartcard side of the Yubikey Neo isn't immediately obvious.
What do I mean?
Well, in `gpg2 --card-edit` the `factory-reset` option is not supported.
So, the solution was to create a file containing the following:
    :::php
    /hex
    scd serialno
    scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    scd apdu 00 e6 00 00
    scd apdu 00 44 00 00
    /echo Card has been successfully reset.
And then run `gpg-connect-agent -f FILE_NAME`.
This wiped the smartcard clean, and allowed me to start fresh.
###Broken Hack
My previous solution, `echo "1234" | gpg2 --no-tty --quiet --batch --local-user KEY_HERE -as - >/dev/null 2>&1 && echo "1" || echo "0"`, was based on a snippet of code which was intended as a quick way to make sure you knew the correct passphrase.
Unfortunately (or perhaps fortunately, as it spurred me to find a clean way and write this post) this hack no longer worked after I reconfigured my Yubikey and left stubfiles on my laptop.
####My Keys
The *"Laptop Encryption key"* is a key I use for `pass` and [My Backups].
The first three subkeys live on my yubikey, and it must be inserted to use them.
#####Digression: Master and Subkeys
There are a number of benefits.
Two of the big ones:
* You can keep the master key offline
    * This is used for new key creation, and web-of-trust signing
* You can revoke subkeys, while maintaning your master key's web-of-trust
    * The alternative is to start from ground zero
There is a very long conversation to be had here.
####Why it Broke
The old hack fails now, as my Signature subkey no longer lives on the laptop.
###A Clean Solution
After a few hours of exercising my Google Fu, interrupted by a social gathering, I noticed a few uses of `gpg-connect-agent` that made it looked promising.
The man page doesn't really cover the command adequately in my opinion.
At this point I guessed that it might actually have an interactive shell, and found that it did.
After reading through all the `help COMMAND` outputs, I saw a few that looked promising and used some more Google Fu.
    :::bash
    ~ -> gpg-connect-agent 'help keyinfo' /bye
    # KEYINFO [--[ssh-]list] [--data] [--ssh-fpr] [--with-ssh] 
    # 
    # Return information about the key specified by the KEYGRIP.  If the
    # key is not available GPG_ERR_NOT_FOUND is returned.  If the option
    # --list is given the keygrip is ignored and information about all
    # available keys are returned.  If --ssh-list is given information
    # about all keys listed in the sshcontrol are returned.  With --with-ssh
    # information from sshcontrol is always added to the info. Unless --data
    # is given, the information is returned as a status line using the format:
    # 
    #   KEYINFO       
    # 
    # KEYGRIP is the keygrip.
    # 
    # TYPE is describes the type of the key:
    #     'D' - Regular key stored on disk,
    #     'T' - Key is stored on a smartcard (token),
    #     'X' - Unknown type,
    #     '-' - Key is missing.
    # 
    # SERIALNO is an ASCII string with the serial number of the
    #          smartcard.  If the serial number is not known a single
    #          dash '-' is used instead.
    # 
    # IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it
    #       is not known a dash is used instead.
    # 
    # CACHED is 1 if the passphrase for the key was found in the key cache.
    #        If not, a '-' is used instead.
    # 
    # PROTECTION describes the key protection type:
    #     'P' - The key is protected with a passphrase,
    #     'C' - The key is not protected,
    #     '-' - Unknown protection.
    # 
    # FPR returns the formatted ssh-style fingerprint of the key.  It is only
    #     printed if the option --ssh-fpr has been used.  It defaults to '-'.
    # 
    # TTL is the TTL in seconds for that key or '-' if n/a.
    # 
    # FLAGS is a word consisting of one-letter flags:
    #       'D' - The key has been disabled,
    #       'S' - The key is listed in sshcontrol (requires --with-ssh),
    #       'c' - Use of the key needs to be confirmed,
    #       '-' - No flags given.
    # 
    # More information may be added in the future.
    OK
This is where I found that `keyinfo --list`, or non interactively `gpg-connect-agent 'keyinfo --list' /bye` will spit out some tasty info.
    :::bash
    ~ -> gpg-connect-agent 'keyinfo --list' /bye
    S KEYINFO REDACTEDREDACTEDREDACTEDREDACTEDREDACTED D - - - P - - -
    S KEYINFO REDACTEDREDACTEDREDACTEDREDACTEDREDACTED D - - 1 P - - -
    S KEYINFO REDACTEDREDACTEDREDACTEDREDACTEDREDACTED T REDACTEDREDACTEDREDACTEDREDACTED OPENPGP.1 - - - - -
    S KEYINFO REDACTEDREDACTEDREDACTEDREDACTEDREDACTED T REDACTEDREDACTEDREDACTEDREDACTED OPENPGP.3 - - - - -
    S KEYINFO REDACTEDREDACTEDREDACTEDREDACTEDREDACTED T REDACTEDREDACTEDREDACTEDREDACTED OPENPGP.2 - - - - -
    OK
Notice that singular '1'?  
**YES!**
Now time to Regex this beauty!
And some AWK for good measure.
    :::bash
    gpg-connect-agent 'keyinfo --list' /bye 2>/dev/null | awk 'BEGIN{CACHED=0} /^S/ {match($0, /S\sKEYINFO\s\S+\s\S\s\S+\s\S+\s(\S)\s\S\s\S+\s\S+\s\S/, m); if(m[1]==1){CACHED=1}} END{print CACHED}'
**EDIT 19FEB2017:** In hind sight, there is a better awk, which now doesn't have to be gawk:
    :::bash
    gpg-connect-agent 'keyinfo --list' /bye 2>/dev/null | awk 'BEGIN{CACHED=0} /^S/ {if($7==1){CACHED=1}} END{if($0!=""){print CACHED} else {print "none"}}'
###Links
[Part2]  
[Part3]  
[WM's bar]  
[My Backups]  
[Creating the Perfect GPG Keypair]  
[Part2]: {filename}009-gpg_cache_check_part2.md
[Part3]: {filename}015-gpg_smartcard_cache_check_part3.md
[WM's bar]: https://notabug.org/demure/dotfiles/src/master/i3/lemonbar
[Creating the Perfect GPG Keypair]: https://alexcabal.com/creating-the-perfect-gpg-keypair/
[My Backups]: {filename}006-backups_options_and_effort.md


AD: