Generating card keys via gpg-connect-agent

Werner Koch wk at gnupg.org
Tue Sep 10 18:23:37 CEST 2019


On Tue, 10 Sep 2019 16:33, jiri.kerestes at trustica.cz said:

> I'm trying to automate generating keys on a smart card using
> gpg-connect-agent. However, there is no documentation at all on using
> "SCD GENKEY" command. [1]

as with all IPC commands you can use help.  In this case:

# GENKEY [--force] [--timestamp=<isodate>] <keyref>
# 
# Generate a key on-card identified by <keyref>, which is application
# specific.  Return values are also application specific.  For OpenPGP
# cards 3 status lines are returned:
# 
#   S KEY-FPR  <hexstring>
#   S KEY-CREATED-AT <seconds_since_epoch>
#   S KEY-DATA [-|p|n] <hexdata>
# 
#   'p' and 'n' are the names of the RSA parameters; '-' is used to
#   indicate that HEXDATA is the first chunk of a parameter given
#   by the next KEY-DATA.  Only used by GnuPG version < 2.1.
# 
# --force is required to overwrite an already existing key.  The
# KEY-CREATED-AT is required for further processing because it is
# part of the hashed key material for the fingerprint.
# 
# If --timestamp is given an OpenPGP key will be created using this
# value.  The value needs to be in ISO Format; e.g.
# "--timestamp=20030316T120000" and after 1970-01-01 00:00:00.
# 
# The public part of the key can also later be retrieved using the
# READKEY command.

> Running this command generates the key, but the key is not added to the
> keyring.

You asked gpg-agent/scdaemon to create a key.  This is an internal (also
stable) command which is used by gpg to create key.

> Log inspection shows that 'gpg --card-edit' does not pass user-supplied
> information (e.g. name, email, key expiration date) to gpg-agent, so it
> must use some other mechanism.

You can use

  gpg --command-fd FD1 --status-fd FD2 --edit-key

to do that.  It is a bit complicated because you need to write a FSM to
answer the prompts from gpg.  Kleopatra and GPA use this method.

> Is it even possible to generate keys on smart card using just gpg-agent?

Yes, but you need to create a corresponding OpenPGP key then latter.
You use the 'keygrip' method for this.

If this is for a new project, I'd suggest that you look at gnupg's
master branch in the repo which features the new tool gpg-card which has
all kind of support to script stuff for cards.  The plan is to release
GnuPG 2.3 (i.e. master) by the end of the year.



Shalom-Salam,

   Werner



ps.
List of commands implemented in gpg-card:
--8<---------------cut here---------------start------------->8---
quit           quit this menu
help           show this help
list           list all available data
name           change card holder's name
url            change URL to retrieve key
fetch          fetch the key specified in the card URL
login          change the login name
lang           change the language preferences
salutation     change card holder's salutation
cafpr          change a CA fingerprint
forcesig       toggle the signature force PIN flag
generate       generate new keys
passwd         menu to change or unblock the PIN
verify         verify the PIN and list all data
unblock        unblock the PIN using a Reset Code
authenticate   authenticate to the card
reset          send a reset to the card daemon
factory-reset  destroy all keys and data
kdf-setup      setup KDF for PIN authentication
key-attr       change the key attribute
uif            change the User Interaction Flag
privatedo      change a private data object
readcert       read a certificate from a data object
writecert      store a certificate to a data object
writekey       store a private key to a data object
yubikey        Yubikey management commands
--8<---------------cut here---------------end--------------->8---


The man page (not up-to-date despite the recent date):

--8<---------------cut here---------------start------------->8---
GPG-CARD(1)                                GNU Privacy Guard 2.2                               GPG-CARD(1)



NAME
       gpg-card - Administrate Smart Cards

SYNOPSIS
       gpg-card [options]
       gpg-card [options] command { -- command }


DESCRIPTION

       The gpg-card is used to administrate smart cards and USB tokens.
       It provides a superset of fea- tures from gpg --card-edit an can
       be considered a frontend to scdaemon which is a daemon started by
       gpg-agent to handle smart cards.

       If gpg-card is invoked without commands an interactive mode is
       used.

       If gpg-card is invoked with one or more commands the same
       commands as available in the interactive mode are run from the
       command line.  These commands need to be delimited with a
       double-dash.  If a double-dash or a shell specific character is
       required as part of a command the entire command needs to be put
       in quotes.  If one of those commands returns an error the
       remaining commands are mot any- more run unless the command was
       prefixed with a single dash.

       A list of commands is available by using the command help and a
       detailed description of each com- mand is printed by using help
       COMMAND.

       See the NOTES sections for instructions pertaining to specific
       cards or card applications.


OPTIONS
       gpg-card understands these options:



       --with-colons
              This option has currently no effect.


       --status-fd n
       
              Write special status strings to the file descriptor n.
              This program returns only the status messages SUCCESS or
              FAILURE which are helpful when the caller uses a double
              fork approach and can't easily get the return code of the
              process.


       --verbose
              Enable extra informational output.


       --quiet
              Disable almost all informational output.


       --version
              Print version of the program and exit.


       --help Display a brief help page and exit.


       --no-autostart
       
              Do not start the gpg-agent if it has not yet been started
              and its service is required.  This option is mostly useful
              on machines where the connection to gpg-agent has been
              redirected to another machines.


       --agent-program file
       
              Specify the agent program to be started if none is
              running.  The default value is determined by running
              gpgconf with the option --list-dirs.


       --gpg-program file
              Specify a non-default gpg binary to be used by certain commands.


       --gpgsm-program file
              Specify a non-default gpgsm binary to be used by certain commands.


NOTES (OPENPGP)

       The support for OpenPGP cards in gpg-card is not yet complete.
       For missing features, please continue to use gpg --card-edit.


NOTES (PIV)

       GnuPG has support for PIV cards (``Personal Identity
       Verification'' as specified by NIST Special Publication
       800-73-4).  This section describes how to initialize
       (personalize) a fresh Yubikey token featuring the PIV application
       (requires Yubikey-5).  We assume that the credentials have not
       yet been changed and thus are:

       Authentication key
              This is a 24 byte key described by the hex string
              010203040506070801020304050607080102030405060708.

       PIV Application PIN
              This is the string 123456.

       PIN Unblocking Key
              This is the string 12345678.

       See the example section on how to change these defaults.  For
       production use it is important to use secure values for them.
       Note that the Authentication Key is not queried via the usual
       Pinentry dialog but needs to be entered manually or read from a
       file.  The use of a dedicated machine to personalize tokens is
       strongly suggested.

       To see what is on the card, the command list can be given.  We
       will use the interactive mode in the following (the string
       gpg/card> is the prompt).  An example output for a fresh card is:

         gpg/card> list
         Reader ...........: 1050:0407:X:0
         Card type ........: yubikey
         Card firmware ....: 5.1.2
         Serial number ....: D2760001240102010006090746250000
         Application type .: OpenPGP
         Version ..........: 2.1
         [...]

       It can be seen by the ``Application type'' line that GnuPG
       selected the OpenPGP application of the Yubikey.  This is because
       GnuPG assigns the highest priority to the OpenPGP application.
       To use the PIV application of the Yubikey several methods can be
       used:

       With a Yubikey 5 or later the OpenPGP application on the Yubikey
       can be disabled:

         gpg/card> yubikey disable all opgp
         gpg/card> yubikey list
         Application  USB    NFC
         -----------------------
         OTP          yes    yes
         U2F          yes    yes
         OPGP         no     no
         PIV          yes    no
         OATH         yes    yes
         FIDO2        yes    yes
         gpg/card> reset

       The reset is required so that the GnuPG system rereads the card.
       Note that disabled applications keep all their data and can at
       any time be re-enabled (use 'help yubikey').

       Another option, which works for all Yubikey versions, is to
       disable the support for OpenPGP cards in scdaemon.  This is done
       by adding the line

         disable-application openpgp

       to '~/.gnupg/scdaemon.conf' and by restarting scdaemon, either by
       killing the process or by using 'gpgconf --kill scdaemon'.
       Finally the default order in which card applications are tried by
       scdaemon can be changed.  For example to prefer PIV over OpenPGP
       it is sufficient to add

         application-priority piv

       to '~/.gnupg/scdaemon.conf' and to restart scdaemon.  This has an
       effect only on tokens which sup- port both, PIV and OpenPGP, but
       does not hamper the use of OpenPGP only tokens.

       With one of these methods employed the list command of gpg-card
       shows this:

         gpg/card> list
         Reader ...........: 1050:0407:X:0
         Card type ........: yubikey
         Card firmware ....: 5.1.2
         Serial number ....: FF020001008A77C1
         Application type .: PIV
         Version ..........: 1.0
         Displayed s/n ....: yk-9074625
         PIN usage policy .: app-pin
         PIN retry counter : - 3 -
         PIV authentication: [none]
               keyref .....: PIV.9A
         Card authenticat. : [none]
               keyref .....: PIV.9E
         Digital signature : [none]
               keyref .....: PIV.9C
         Key management ...: [none]
               keyref .....: PIV.9D

       In case several tokens are plugged into the computer, gpg-card
       will show only one.  To show another token the number of the
       token (0, 1, 2, ...) can be given as an argument to the list
       command.  The command 'list --cards' prints a list of all
       inserted tokens.

       Note that the ``Displayed s/n'' is printed on the token and also
       shown in Pinentry prompts asking for the PIN.  The four standard
       key slots are always shown, if other key slots are initialized
       they are shown as well.  The PIV authentication key (internal
       reference PIV.9A) is used to authenticate the card and the card
       holder.  The use of the associated private key is protected by
       the Applica- tion PIN which needs to be provided once and the key
       can the be used until the card is reset or removed from the
       reader or USB port.  GnuPG uses this key with its Secure Shell
       support.  The Card authentication key (PIV.9E) is also known as
       the CAK and used to support physical access applica- tions.  The
       private key is not protected by a PIN and can thus immediately be
       used.  The Digital signature key (PIV.9C) is used to digitally
       sign documents.  The use of the associated private key is
       protected by the Application PIN which needs to be provided for
       each signing operation.  The Key management key (PIV.9D) is used
       for encryption.  The use of the associated private key is
       protected by the Application PIN which needs to be provided only
       once so that decryption operations can then be done until the
       card is reset or removed from the reader or USB port.

       We now generate three of the four keys.  Note that GnuPG does
       currently not use the the Card authentication key; however, that
       key is mandatory by the PIV standard and thus we create it too.
       Key generation requires that we authenticate to the card.  This
       can be done either on the command line (which would reveal the
       key):

         gpg/card> auth 010203040506070801020304050607080102030405060708

       or by reading the key from a file.  That file needs to consist of
       one LF terminated line with the hex encoded key (as above):

         gpg/card> auth < myauth.key

       As usual 'help auth' gives help for this command.  An error
       message is printed if a non-matching key is used.  The
       authentication is valid until a reset of the card or until the
       card is removed from the reader or the USB port.  Note that that
       in non-interactive mode the '<' needs to be quoted so that the
       shell does not interpret it as a its own redirection symbol.


       Here are the actual commands to generate the keys:

         gpg/card> generate --algo=nistp384 PIV.9A
         PIV card no. yk-9074625 detected
         gpg/card> generate --algo=nistp256 PIV.9E
         PIV card no. yk-9074625 detected
         gpg/card> generate --algo=rsa2048 PIV.9C
         PIV card no. yk-9074625 detected

       If a key has already been created for one of the slots an error
       will be printed; to create a new key anyway the option '--force'
       can be used.  Note that only the private and public keys have
       been created but no certificates are stored in the key slots.  In
       fact, GnuPG uses its own non-standard method to store just the
       public key in place of the the certificate.  Other application
       will not be able to make use these keys until gpgsm or another
       tool has been used to create and store the respective
       certificates.  Let us see what the list command now shows:

         gpg/card> list
         Reader ...........: 1050:0407:X:0
         Card type ........: yubikey
         Card firmware ....: 5.1.2
         Serial number ....: FF020001008A77C1
         Application type .: PIV
         Version ..........: 1.0
         Displayed s/n ....: yk-9074625
         PIN usage policy .: app-pin
         PIN retry counter : - 3 -
         PIV authentication: 213D1825FDE0F8240CB4E4229F01AF90AC658C2E
               keyref .....: PIV.9A  (auth)
               algorithm ..: nistp384
         Card authenticat. : 7A53E6CFFE7220A0E646B4632EE29E5A7104499C
               keyref .....: PIV.9E  (auth)
               algorithm ..: nistp256
         Digital signature : 32A6C6FAFCB8421878608AAB452D5470DD3223ED
               keyref .....: PIV.9C  (sign,cert)
               algorithm ..: rsa2048
         Key management ...: [none]
               keyref .....: PIV.9D

       The primary information for each key is the keygrip, a 40 byte
       hex-string identifying the key.  This keygrip is a unique
       identifier for the specific parameters of a key.  It is used by
       gpg-agent and other parts of GnuPG to associate a private key to
       its protocol specific certificate format (X.509, OpenPGP, or
       SecureShell).  Below the keygrip the key reference along with the
       key usage capabilities are show.  Finally the algorithm is
       printed in the format used by {gpg}.  At that point no other
       information is shown because for these new keys gpg won't be able
       to find matching certificates.

       Although we could have created the Key management key also with
       the generate command, we will cre- ate that key off-card so that
       a backup exists.  To accomplish this a key needs to be created
       with either gpg or gpgsm or imported in one of these tools.  In
       our example we create a self-signed X.509 certificate (exit the
       gpg-card tool, first):

         $ gpgsm --gen-key -o encr.crt
            (1) RSA
            (2) Existing key
            (3) Existing key from card
         Your selection? 1
         What keysize do you want? (3072) 2048
         Requested keysize is 2048 bits
         Possible actions for a RSA key:
            (1) sign, encrypt
            (2) sign
            (3) encrypt
         Your selection? 3
         Enter the X.509 subject name: CN=Encryption key for yk-9074625,O=example,C=DE
         Enter email addresses (end with an empty line):
         > otto at example.net
         >
         Enter DNS names (optional; end with an empty line):
         >
         Enter URIs (optional; end with an empty line):
         >
         Create self-signed certificate? (y/N) y
         These parameters are used:
             Key-Type: RSA
             Key-Length: 2048
             Key-Usage: encrypt
             Serial: random
             Name-DN: CN=Encryption key for yk-9074625,O=example,C=DE
             Name-Email: otto at example.net

         Proceed with creation? (y/N)
         Now creating self-signed certificate.  This may take a while ...
         gpgsm: about to sign the certificate for key: &34798AAFE0A7565088101CC4AE31C5C8C74461CB
         gpgsm: certificate created
         Ready.
         $ gpgsm --import encr.crt
         gpgsm: certificate imported
         gpgsm: total number processed: 1
         gpgsm:               imported: 1

       Note the last step which imported the created certificate.  If
       you you instead created a certifi- cate signing request (CSR)
       instead of a self-signed certificate and sent this off to a CA
       you would do the same import step with the certificate received
       from the CA.  Take note of the keygrip (pre- fixed with an
       ampersand) as shown during the certificate creation or listed it
       again using 'gpgsm --with-keygrip -k otto at example.net'.  Now to
       move the key and certificate to the card start gpg- card again
       and enter:

         gpg/card> writekey PIV.9D 34798AAFE0A7565088101CC4AE31C5C8C74461CB
         gpg/card> writecert PIV.9D < encr.crt

       If you entered a passphrase to protect the private key, you will
       be asked for it via the Pinentry prompt.  On success the key and
       the certificate has been written to the card and a list command
       shows:

         [...]
         Key management ...: 34798AAFE0A7565088101CC4AE31C5C8C74461CB
               keyref .....: PIV.9D  (encr)
               algorithm ..: rsa2048
               used for ...: X.509
                 user id ..: CN=Encryption key for yk-9074625,O=example,C=DE
                 user id ..: <otto at example.net>

       In case the same key (identified by the keygrip) has been used
       for several certificates you will see several ``used for'' parts.
       With this the encryption key is now fully functional and can be
       used to decrypt messages encrypted to this certificate.  Take
       care: the original key is still stored on-disk and should be
       moved to a backup medium.  This can simply be done by copying the
       file '34798AAFE0A7565088101CC4AE31C5C8C74461CB.key' from the
       directory '~/.gnupg/private-keys-v1.d/' to the backup medium and
       deleting the file at its original place.

       The final example is to create a self-signed certificate for
       digital signatures.  Leave gpg-card using quit or by pressing
       Control-D and use gpgsm:

         $ gpgsm --learn
         $ gpgsm --gen-key -o sign.crt
         Please select what kind of key you want:
            (1) RSA
            (2) Existing key
            (3) Existing key from card
         Your selection? 3
         Serial number of the card: FF020001008A77C1
         Available keys:
            (1) 213D1825FDE0F8240CB4E4229F01AF90AC658C2E PIV.9A nistp384
            (2) 7A53E6CFFE7220A0E646B4632EE29E5A7104499C PIV.9E nistp256
            (3) 32A6C6FAFCB8421878608AAB452D5470DD3223ED PIV.9C rsa2048
            (4) 34798AAFE0A7565088101CC4AE31C5C8C74461CB PIV.9D rsa2048
         Your selection? 3
         Possible actions for a RSA key:
            (1) sign, encrypt
            (2) sign
            (3) encrypt
         Your selection? 2
         Enter the X.509 subject name: CN=Signing key for yk-9074625,O=example,C=DE
         Enter email addresses (end with an empty line):
         > otto at example.net
         >
         Enter DNS names (optional; end with an empty line):
         >
         Enter URIs (optional; end with an empty line):
         >
         Create self-signed certificate? (y/N)
         These parameters are used:
             Key-Type: card:PIV.9C
             Key-Length: 1024
             Key-Usage: sign
             Serial: random
             Name-DN: CN=Signing key for yk-9074625,O=example,C=DE
             Name-Email: otto at example.net

         Proceed with creation? (y/N) y
         Now creating self-signed certificate.  This may take a while ...
         gpgsm: about to sign the certificate for key: &32A6C6FAFCB8421878608AAB452D5470DD3223ED
         gpgsm: certificate created
         Ready.
         $ gpgsm --import sign.crt
         gpgsm: certificate imported
         gpgsm: total number processed: 1
         gpgsm:               imported: 1

       The use of 'gpgsm --learn' is currently necessary so that
       gpg-agent knows what keys are available on the card.  The need
       for this command will eventually be removed.  The remaining
       commands are similar to the creation of an on-disk key.  However,
       here we select the 'Digital signature' key.  During the creation
       process you will be asked for the Application PIN of the card.
       The final step is to write the certificate to the card using
       gpg-card:

         gpg/card> writecert PIV.9C < sign.crt

       By running list again we will see the fully initialized card:

         Reader ...........: 1050:0407:X:0
         Card type ........: yubikey
         Card firmware ....: 5.1.2
         Serial number ....: FF020001008A77C1
         Application type .: PIV
         Version ..........: 1.0
         Displayed s/n ....: yk-9074625
         PIN usage policy .: app-pin
         PIN retry counter : - [verified] -
         PIV authentication: 213D1825FDE0F8240CB4E4229F01AF90AC658C2E
               keyref .....: PIV.9A  (auth)
               algorithm ..: nistp384
         Card authenticat. : 7A53E6CFFE7220A0E646B4632EE29E5A7104499C
               keyref .....: PIV.9E  (auth)
               algorithm ..: nistp256
         Digital signature : 32A6C6FAFCB8421878608AAB452D5470DD3223ED
               keyref .....: PIV.9C  (sign,cert)
               algorithm ..: rsa2048
               used for ...: X.509
                 user id ..: CN=Signing key for yk-9074625,O=example,C=DE
                 user id ..: <otto at example.net>
         Key management ...: 34798AAFE0A7565088101CC4AE31C5C8C74461CB
               keyref .....: PIV.9D  (encr)
               algorithm ..: rsa2048
               used for ...: X.509
                 user id ..: CN=Encryption key for yk-9074625,O=example,C=DE
                 user id ..: <otto at example.net>

       It is now possible to sign and to encrypt with this card using
       gpgsm and to use the 'PIV authenti- cation' key with ssh:

         $ ssh-add -l
         384 SHA256:0qnJ0Y0ehWxKcx2frLfEljf6GCdlO55OZed5HqGHsaU cardno:yk-9074625 (ECDSA)

       As usual use ssh-add with the uppercase '-L' to list the public
       ssh key.  To use the certificates with Thunderbird or Mozilla,
       please consult the Scute manual for details.

       If you want to use the same PIV keys also for OpenPGP (for
       example on a Yubikey to avoid switching between OpenPGP and PIV),
       this is also possible:

         $ gpgsm --learn
         $ gpg --full-gen-key
         Please select what kind of key you want:
            (1) RSA and RSA (default)
            (2) DSA and Elgamal
            (3) DSA (sign only)
            (4) RSA (sign only)
           (14) Existing key from card
         Your selection? 14
         Serial number of the card: FF020001008A77C1
         Available keys:
            (1) 213D1825FDE0F8240CB4E4229F01AF90AC658C2E PIV.9A nistp384 (auth)
            (2) 7A53E6CFFE7220A0E646B4632EE29E5A7104499C PIV.9E nistp256 (auth)
            (3) 32A6C6FAFCB8421878608AAB452D5470DD3223ED PIV.9C rsa2048 (cert,sign)
            (4) 34798AAFE0A7565088101CC4AE31C5C8C74461CB PIV.9D rsa2048 (encr)
         Your selection? 3
         Please specify how long the key should be valid.
                  0 = key does not expire
               <n>  = key expires in n days
               <n>w = key expires in n weeks
               <n>m = key expires in n months
               <n>y = key expires in n years
         Key is valid for? (0)
         Key does not expire at all
         Is this correct? (y/N) y

         GnuPG needs to construct a user ID to identify your key.

         Real name:
         Email address: otto at example.net
         Comment:
         You selected this USER-ID:
             "otto at example.net"

         Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
         gpg: key C3AFA9ED971BB365 marked as ultimately trusted
         gpg: revocation certificate stored as '[...]D971BB365.rev'
         public and secret key created and signed.

         Note that this key cannot be used for encryption.  You may want to use
         the command "--edit-key" to generate a subkey for this purpose.
         pub   rsa2048 2019-04-04 [SC]
               7F899AE2FB73159DD68A1B20C3AFA9ED971BB365
         uid                      otto at example.net

       Note that you will be asked two times to enter the PIN of your
       PIV card.  If you run gpg in --expert mode you will also ge given
       the option to change the usage flags of the key.  The next
       typescript shows how to add the encryption subkey:

         $ gpg --edit-key 7F899AE2FB73159DD68A1B20C3AFA9ED971BB365
         Secret key is available.

         sec  rsa2048/C3AFA9ED971BB365
              created: 2019-04-04  expires: never       usage: SC
              card-no: FF020001008A77C1
              trust: ultimate      validity: ultimate
         [ultimate] (1). otto at example.net
         gpg> addkey
         Secret parts of primary key are stored on-card.
         Please select what kind of key you want:
            (3) DSA (sign only)
            (4) RSA (sign only)
            (5) Elgamal (encrypt only)
            (6) RSA (encrypt only)
           (14) Existing key from card
         Your selection? 14
         Serial number of the card: FF020001008A77C1
         Available keys:
            (1) 213D1825FDE0F8240CB4E4229F01AF90AC658C2E PIV.9A nistp384 (auth)
            (2) 7A53E6CFFE7220A0E646B4632EE29E5A7104499C PIV.9E nistp256 (auth)
            (3) 32A6C6FAFCB8421878608AAB452D5470DD3223ED PIV.9C rsa2048 (cert,sign)
            (4) 34798AAFE0A7565088101CC4AE31C5C8C74461CB PIV.9D rsa2048 (encr)
         Your selection? 4
         Please specify how long the key should be valid.
                  0 = key does not expire
               <n>  = key expires in n days
               <n>w = key expires in n weeks
               <n>m = key expires in n months
               <n>y = key expires in n years
         Key is valid for? (0)
         Key does not expire at all
         Is this correct? (y/N) y
         Really create? (y/N) y

         sec  rsa2048/C3AFA9ED971BB365
              created: 2019-04-04  expires: never       usage: SC
              card-no: FF020001008A77C1
              trust: ultimate      validity: ultimate
         ssb  rsa2048/7067860A98FCE6E1
              created: 2019-04-04  expires: never       usage: E
              card-no: FF020001008A77C1
         [ultimate] (1). otto at example.net

         gpg> save

       Now you can use your PIV card also with gpg.



SEE ALSO
       scdaemon(1)



GnuPG 2.3.0-beta911                             2019-08-30                                     GPG-CARD(1)
--8<---------------cut here---------------end--------------->8---


-- 
Die Gedanken sind frei.  Ausnahmen regelt ein Bundesgesetz.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20190910/82dac4d9/attachment-0001.sig>


More information about the Gnupg-devel mailing list