summaryrefslogtreecommitdiffstats
path: root/doc/gpg-card.texi
blob: be19704cccf1dc96b98e26faf41e457e5473ab48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
@c card-tool.texi - man page for gpg-card-tool
@c Copyright (C) 2019 g10 Code GmbH
@c This is part of the GnuPG manual.
@c For copying conditions, see the file GnuPG.texi.

@include defs.inc

@node Smart Card Tool
@chapter Smart Card Tool

GnuPG comes with a tool to administrate smart cards and USB tokens.
This tool is an enhanced version of the @option{--edit-key} command
available with @command{gpg}.

@menu
* gpg-card::             Administrate smart cards.
@end menu

@c
@c  GPG-CARD-TOOL
@c
@manpage gpg-card.1
@node gpg-card
@section Administrate smart cards.
@ifset manverb
.B gpg-card
\- Administrate Smart Cards
@end ifset

@mansect synopsis
@ifset manverb
.B gpg-card
.RI [ options ]
.br
.B gpg-card
.RI [ options ]
.I command
.RI {
.B --
.I command
.RI }
@end ifset

@mansect description
The @command{gpg-card} is used to administrate smart cards and USB
tokens.  It provides a superset of features from @command{gpg
--card-edit} an can be considered a frontend to @command{scdaemon}
which is a daemon started by @command{gpg-agent} to handle smart
cards.

If @command{gpg-card} is invoked without commands an interactive
mode is used.

If @command{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 not anymore
run unless the command was prefixed with a single dash.

A list of commands is available by using the command @code{help} and a
detailed description of each command is printed by using @code{help
COMMAND}.

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

@mansect options
@noindent
@command{gpg-card} understands these options:

@table @gnupgtabopt

@item --with-colons
@opindex with-colons
This option has currently no effect.

@item --status-fd @var{n}
@opindex status-fd
Write special status strings to the file descriptor @var{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.

@item --verbose
@opindex verbose
Enable extra informational output.

@item --quiet
@opindex quiet
Disable almost all informational output.

@item --version
@opindex version
Print version of the program and exit.

@item --help
@opindex help
Display a brief help page and exit.

@item --no-autostart
@opindex 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.

@item --no-history
@opindex --no-history
In interactive mode the command line history is usually saved and
restored to and from a file below the GnuPG home directory.  This
option inhibits the use of that file.

@item --agent-program @var{file}
@opindex agent-program
Specify the agent program to be started if none is running.  The
default value is determined by running @command{gpgconf} with the
option @option{--list-dirs}.

@item --gpg-program @var{file}
@opindex gpg-program
Specify a non-default gpg binary to be used by certain commands.

@item --gpgsm-program @var{file}
@opindex gpgsm-program
Specify a non-default gpgsm binary to be used by certain commands.

@end table

@mansect notes (OpenPGP)
The support for OpenPGP cards in @command{gpg-card} is not yet
complete.  For missing features, please continue to use @code{gpg
--card-edit}.

@mansect notes (PIV)
@noindent
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:
@table @asis
@item Authentication key
This is a 24 byte key described by the hex string @*
@code{010203040506070801020304050607080102030405060708}.
@item PIV Application PIN
This is the string @code{123456}.
@item PIN Unblocking Key
This is the string @code{12345678}.
@end table
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 @code{list} can be given.  We
will use the interactive mode in the following (the string
@emph{gpg/card>} is the prompt).  An example output for a fresh card
is:

@example
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
[...]
@end example

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:

@example
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
@end example

The @code{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 @kbd{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

@smallexample
disable-application openpgp
@end smallexample

to @file{~/.gnupg/scdaemon.conf} and by restarting scdaemon, either by
killing the process or by using @kbd{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

@smallexample
application-priority piv
@end smallexample

to @file{~/.gnupg/scdaemon.conf} and to restart @command{scdaemon}.
This has an effect only on tokens which support both, PIV and OpenPGP,
but does not hamper the use of OpenPGP only tokens.

With one of these methods employed the @code{list} command of
@command{gpg-card} shows this:

@example
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
@end example

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 @code{list} command.  The
command @kbd{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 @emph{PIV authentication} key (internal reference
@emph{PIV.9A}) is used to authenticate the card and the card holder.
The use of the associated private key is protected by the Application
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 @emph{Secure Shell} support.  The @emph{Card
authentication} key (@emph{PIV.9E}) is also known as the CAK and used
to support physical access applications.  The private key is not
protected by a PIN and can thus immediately be used.  The @emph{Digital
signature} key (@emph{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
@emph{Key management} key (@emph{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 @emph{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):

@example
gpg/card> auth 010203040506070801020304050607080102030405060708
@end example

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):

@example
gpg/card> auth < myauth.key
@end example

As usual @samp{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 @samp{<} needs to be quoted so that the shell does not interpret
it as a its own redirection symbol.

@noindent
Here are the actual commands to generate the keys:

@example
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
@end example

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 @samp{--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 @command{gpgsm} or another tool has been used to
create and store the respective certificates.   Let us see what the
list command now shows:

@example
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
@end example

The primary information for each key is the @emph{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
@command{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 @command {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 @emph{Key management} key also with
the generate command, we will create that key off-card so that a
backup exists.  To accomplish this a key needs to be created with
either @command{gpg} or @command{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):

@example
$ 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@@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@@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
@end example

Note the last step which imported the created certificate.  If you
you instead created a certificate 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 (prefixed with an ampersand) as shown during the
certificate creation or listed it again using @samp{gpgsm
--with-keygrip -k otto@@example.net}.  Now to move the key and
certificate to the card start @command{gpg-card} again and enter:

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

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 @code{list} command
shows:

@example
[...]
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@@example.net>
@end example

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.  @sc{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
@file{34798AAFE0A7565088101CC4AE31C5C8C74461CB.key} from the directory
@file{~/.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 @command{gpg-card} using @code{quit} or by pressing
Control-D and use gpgsm:

@example
$ 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@@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@@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
@end example

The use of @samp{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 @samp{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 @command{gpg-card}:

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

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

@example
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@@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@@example.net>
@end example

It is now possible to sign and to encrypt with this card using gpgsm
and to use the @samp{PIV authentication} key with ssh:

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

As usual use ssh-add with the uppercase @samp{-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:

@example
$ 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@@example.net
Comment:
You selected this USER-ID:
    "otto@@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@@example.net
@end example

Note that you will be asked two times to enter the PIN of your PIV
card.  If you run @command{gpg} in @option{--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:

@example
$ 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@@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@@example.net

gpg> save
@end example

Now you can use your PIV card also with @command{gpg}.

@c @mansect examples

@mansect see also
@ifset isman
@command{scdaemon}(1)
@end ifset