1
/* app-p15.c - The pkcs#15 card application.
2
* Copyright (C) 2004 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
32
#include "app-common.h"
36
/* Context local to this application. */
39
unsigned short home_df; /* The home DF. Note, that we don't yet
40
support a multilevel hierachy. Thus we
41
assume this is directly below the MF. */
44
unsigned short private_keys;
45
unsigned short public_keys;
46
unsigned short trusted_public_keys;
47
unsigned short secret_keys;
48
unsigned short certificates;
49
unsigned short trusted_certificates;
50
unsigned short useful_certificates;
51
unsigned short data_objects;
52
unsigned short auth_objects;
61
/* Do a select and a read for the file with EFID. EFID is a
62
desctription of the EF to be used with error messages. On success
63
BUFFER and BUFLEN contain the entire content of the EF. The caller
64
must free BUFFER but only on success. */
66
select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
67
unsigned char **buffer, size_t *buflen)
71
err = iso7816_select_file (slot, efid, 0, NULL, NULL);
74
log_error ("error selecting %s (0x%04X): %s\n",
75
efid_desc, efid, gpg_strerror (err));
78
err = iso7816_read_binary (slot, 0, 0, buffer, buflen);
81
log_error ("error reading %s (0x%04X): %s\n",
82
efid_desc, efid, gpg_strerror (err));
91
/* Read and parse the Object Directory File and store away the
94
Example of such a file:
96
A0 06 30 04 04 02 60 34 = Private Keys
97
A4 06 30 04 04 02 60 35 = Certificates
98
A5 06 30 04 04 02 60 36 = TrustedCertificates
99
A7 06 30 04 04 02 60 37 = DataObjects
100
A8 06 30 04 04 02 60 38 = AuthObjects
102
These are all PathOrObjects using the path CHOICE. The paths are
103
octet strings of length 2. Using this Path CHOICE is recommended,
104
so we only implement that for now.
107
read_ef_odf (app_t app)
110
unsigned char *buffer, *p;
112
unsigned short value;
114
err = select_and_read_binary (app->slot, 0x5031, "ODF", &buffer, &buflen);
120
log_error ("error: ODF too short\n");
122
return gpg_error (GPG_ERR_INV_OBJ);
124
for (p=buffer; buflen >= 8; p += 8, buflen -= 8)
126
if ( (p[0] & 0xf0) != 0xA0
127
|| memcmp (p+1, "\x06\x30\x04\x04\x02", 5) )
129
log_error ("ODF format is not supported by us\n");
131
return gpg_error (GPG_ERR_INV_OBJ);
133
switch ((p[0] & 0x0f))
135
case 0: value = app->app_local->odf.private_keys; break;
136
case 1: value = app->app_local->odf.public_keys; break;
137
case 2: value = app->app_local->odf.trusted_public_keys; break;
138
case 3: value = app->app_local->odf.secret_keys; break;
139
case 4: value = app->app_local->odf.certificates; break;
140
case 5: value = app->app_local->odf.trusted_certificates; break;
141
case 6: value = app->app_local->odf.useful_certificates; break;
142
case 7: value = app->app_local->odf.data_objects; break;
143
case 8: value = app->app_local->odf.auth_objects; break;
144
default: value = 0; break;
148
log_error ("duplicate object type %d in ODF ignored\n",(p[0)&0x0f));
151
value = ((p[6] << 8) | p[7]);
152
switch ((p[0] & 0x0f))
154
case 0: app->app_local->odf.private_keys = value; break;
155
case 1: app->app_local->odf.public_keys = value; break;
156
case 2: app->app_local->odf.trusted_public_keys = value; break;
157
case 3: app->app_local->odf.secret_keys = value; break;
158
case 4: app->app_local->odf.certificates = value; break;
159
case 5: app->app_local->odf.trusted_certificates = value; break;
160
case 6: app->app_local->odf.useful_certificates = value; break;
161
case 7: app->app_local->odf.data_objects = value; break;
162
case 8: app->app_local->odf.auth_objects = value; break;
164
log_error ("unknown object type %d in ODF ignored\n", (p[0)&0x0f));
169
log_info ("warning: %u bytes of garbage detected at end of ODF\n", buflen);
177
/* Read and parse the Private Key Directory Files. */
181
30 33 30 11 0C 08 53 4B 2E 43 48 2E 44 53 03 02 030...SK.CH.DS..
182
06 80 04 01 07 30 0C 04 01 01 03 03 06 00 40 02 .....0........@.
183
02 00 50 A1 10 30 0E 30 08 04 06 3F 00 40 16 00 ..P..0.0...?.@..
184
50 02 02 04 00 30 33 30 11 0C 08 53 4B 2E 43 48 P....030...SK.CH
185
2E 4B 45 03 02 06 80 04 01 0A 30 0C 04 01 0C 03 .KE.......0.....
186
03 06 44 00 02 02 00 52 A1 10 30 0E 30 08 04 06 ..D....R..0.0...
187
3F 00 40 16 00 52 02 02 04 00 30 34 30 12 0C 09 ?.@..R....040...
188
53 4B 2E 43 48 2E 41 55 54 03 02 06 80 04 01 0A SK.CH.AUT.......
189
30 0C 04 01 0D 03 03 06 20 00 02 02 00 51 A1 10 0....... ....Q..
190
30 0E 30 08 04 06 3F 00 40 16 00 51 02 02 04 00 0.0...?.@..Q....
191
30 37 30 15 0C 0C 53 4B 2E 43 48 2E 44 53 2D 53 070...SK.CH.DS-S
192
50 58 03 02 06 80 04 01 0A 30 0C 04 01 02 03 03 PX.......0......
193
06 20 00 02 02 00 53 A1 10 30 0E 30 08 04 06 3F . ....S..0.0...?
194
00 40 16 00 53 02 02 04 00 00 00 00 00 00 00 00 .@..S...........
195
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
196
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
200
read_ef_prkdf (app_t app)
206
/* Read and parse the Public Key Directory Files. */
208
read_ef_pukdf (app_t app)
215
/* Read and parse the Certificate Directory Files. */
220
30 2A 30 15 0C 0C 43 5F 58 35 30 39 2E 43 48 2E 0*0...C_X509.CH.
221
44 53 03 02 06 40 04 01 0A 30 03 04 01 01 A1 0C DS...@...0......
222
30 0A 30 08 04 06 3F 00 40 16 C0 00 30 2A 30 15 0.0...?.@...0*0.
223
0C 0C 43 5F 58 35 30 39 2E 43 48 2E 4B 45 03 02 ..C_X509.CH.KE..
224
06 40 04 01 0A 30 03 04 01 0C A1 0C 30 0A 30 08 .@...0......0.0.
225
04 06 3F 00 40 16 C2 00 30 2B 30 16 0C 0D 43 5F ..?.@...0+0...C_
226
58 35 30 39 2E 43 48 2E 41 55 54 03 02 06 40 04 X509.CH.AUT...@.
227
01 0A 30 03 04 01 0D A1 0C 30 0A 30 08 04 06 3F ..0......0.0...?
228
00 40 16 C5 00 30 2E 30 19 0C 10 43 5F 58 35 30 .@...0.0...C_X50
229
39 2E 43 48 2E 44 53 2D 53 50 58 03 02 06 40 04 9.CH.DS-SPX...@.
230
01 0A 30 03 04 01 02 A1 0C 30 0A 30 08 04 06 3F ..0......0.0...?
231
00 40 16 C1 20 00 00 00 00 00 00 00 00 00 00 00 .@.. ...........
232
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
233
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
234
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
235
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
238
2 21: SEQUENCE { -- commonObjectAttributes
239
4 12: UTF8String 'C_X509.CH.DS'
240
18 2: BIT STRING 6 unused bits
242
22 1: OCTET STRING 0A
244
25 3: SEQUENCE { -- commonCertificateAttributes
245
27 1: OCTET STRING 01
247
30 12: [1] { -- certAttributes
250
36 6: OCTET STRING 3F 00 40 16 C0 00
258
6036 (trustedcertificates)
260
30 35 30 06 03 02 00 00 04 00 30 16 04 14 2D 36 050.......0...-6
261
33 39 33 33 39 34 30 33 39 37 37 36 34 30 31 32 3933940397764012
262
31 36 A1 13 30 11 30 0F 04 06 3F 00 40 16 C7 08 16..0.0...?.@...
263
02 01 00 80 02 02 29 30 35 30 06 03 02 00 00 04 ......)050......
264
00 30 16 04 14 2D 34 30 31 39 30 35 32 37 32 36 .0...-4019052726
265
38 30 31 36 39 33 34 39 32 A1 13 30 11 30 0F 04 801693492..0.0..
266
06 3F 00 40 16 C7 0E 02 01 00 80 02 04 12 30 34 .?.@..........04
267
30 06 03 02 00 00 04 00 30 15 04 13 37 39 36 33 0.......0...7963
268
32 38 33 36 35 30 37 36 36 34 38 32 39 36 30 A1 283650766482960.
269
13 30 11 30 0F 04 06 3F 00 40 16 C0 08 02 01 00 .0.0...?.@......
270
80 02 04 11 00 00 00 00 00 00 00 00 00 00 00 00 ................
271
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
277
: Error: Spurious zero bits in bitstring.
279
: Error: Object has zero length.
282
12 20: OCTET STRING '-6393394039776401216'
287
40 6: OCTET STRING 3F 00 40 16 C7 08
288
48 1: INTEGER 0 -- index
289
51 2: [0] 02 29 -- length
298
read_ef_cdf (app_t app)
301
unsigned char *buffer = NULL;
303
unsigned short value;
305
const unsigned char *p;
306
size_t n, objlen, hdrlen;
307
int class, tag, constructed, ndef;
309
fid = app->app_local->odf.certificates;
311
return 0; /* No certificates. */
313
err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen);
320
/* Loop over the records. We stop as soon as we detect a new record
321
starting with 0x00 or 0xff as these values are commonly used to pad
322
the the read datablocks and are no valid ASN.1 encoding. */
323
while (n && *p && *p == 0xff)
325
const unsigned char *pp;
328
err = parse_ber_header (&p, &n, &class, &tag, &constructed,
329
&ndef, &objlen, &hdrlen);
330
if (!err && (objlen > n || tag != TAG_SEQUENCE))
331
err = gpg_error (GPG_ERR_INV_OBJ);
334
log_error ("error parsing CDF record: %s\n", gpg_strerror (err));
342
/* Skip the commonObjectAttributes. */
343
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
344
&ndef, &objlen, &hdrlen);
345
if (!err && (objlen > nn || tag != TAG_SEQUENCE))
346
err = gpg_error (GPG_ERR_INV_OBJ);
349
log_error ("error parsing CDF record: %s - skipped\n",
356
/* Skip the commonCertificateAttributes. */
357
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
358
&ndef, &objlen, &hdrlen);
359
if (!err && (objlen > nn || tag != TAG_SEQUENCE))
360
err = gpg_error (GPG_ERR_INV_OBJ);
363
log_error ("error parsing CDF record: %s - skipped\n",
370
/* FIXME: Check that this is a reference to a certificate. */
381
/* Read and parse Authentication Object Directory Files. */
383
read_ef_aodf (app_t app)
389
/* 6037 (dataobjects)
391
30 1E 30 0B 0C 06 45 46 2E 47 44 4F 04 01 0A 30 0.0...EF.GDO...0
392
02 0C 00 A1 0B 30 09 04 04 3F 00 2F 02 80 01 0E .....0...?./....
393
30 30 30 18 0C 0F 64 69 73 70 6C 61 79 20 6D 65 000...display me
394
73 73 61 67 65 03 02 06 C0 04 01 0A 30 05 0C 03 ssage.......0...
395
42 53 53 A1 0D 30 0B 04 06 3F 00 40 16 D0 00 80 BSS..0...?.@....
396
01 20 30 2B 30 0C 0C 03 53 53 4F 03 02 06 C0 04 . 0+0...SSO.....
397
01 0A 30 0B 0C 09 53 61 66 65 47 75 61 72 64 A1 ..0...SafeGuard.
398
0E 30 0C 04 06 3F 00 0F FF 30 02 80 02 03 00 30 .0...?...0.....0
399
30 30 11 0C 08 53 47 41 53 64 61 74 61 03 02 06 00...SGASdata...
400
C0 04 01 0A 30 0B 0C 09 53 61 66 65 47 75 61 72 ....0...SafeGuar
401
64 A1 0E 30 0C 04 06 3F 00 0F FF 40 01 80 02 00 d..0...?...@....
402
80 30 30 30 11 0C 08 55 73 65 72 64 61 74 61 03 .000...Userdata.
403
02 06 40 04 01 0A 30 0B 0C 09 53 61 66 65 47 75 ..@...0...SafeGu
404
61 72 64 A1 0E 30 0C 04 06 3F 00 0F FF 30 01 80 ard..0...?...0..
405
02 01 00 30 2C 30 13 0C 0A 62 61 73 69 63 20 64 ...0,0...basic d
406
61 74 61 03 02 06 C0 04 01 0A 30 05 0C 03 49 44 ata.......0...ID
407
44 A1 0E 30 0C 04 06 3F 00 40 17 D0 01 80 02 02 D..0...?.@......
408
00 30 2F 30 16 0C 0D 65 78 74 65 6E 64 65 64 20 .0/0...extended
409
64 61 74 61 03 02 06 C0 04 01 0A 30 05 0C 03 49 data.......0...I
410
44 44 A1 0E 30 0C 04 06 3F 00 40 17 D0 02 80 02 DD..0...?.@.....
411
08 00 30 34 30 1B 0C 12 73 70 65 63 69 61 6C 20 ..040...special
412
70 72 69 76 69 6C 65 67 65 73 03 02 06 C0 04 01 privileges......
413
0A 30 05 0C 03 49 44 44 A1 0E 30 0C 04 06 3F 00 .0...IDD..0...?.
414
40 17 D0 03 80 02 04 00 @.......
418
4 6: UTF8String 'EF.GDO'
419
12 1: OCTET STRING 0A
423
: Error: Object has zero length.
427
23 4: OCTET STRING 3F 00 2F 02
437
30 2A 30 0B 0C 05 62 61 73 69 63 03 02 00 C0 30 0*0...basic....0
438
03 04 01 0A A1 16 30 14 03 03 00 0C 10 0A 01 01 ......0.........
439
02 01 06 02 01 06 02 01 08 80 01 01 30 51 30 19 ............0Q0.
440
0C 13 73 70 65 63 69 66 69 63 20 50 49 4E 20 66 ..specific PIN f
441
6F 72 20 44 53 03 02 00 C0 30 03 04 01 07 A1 2F or DS....0...../
442
30 2D 03 03 00 4C 10 0A 01 01 02 01 06 02 01 06 0-...L..........
443
02 01 08 80 01 02 18 0F 32 30 30 32 30 34 31 39 ........20020419
444
31 32 31 33 34 31 5A 30 06 04 04 3F 00 40 16 121341Z0...?.@.
448
4 5: UTF8String 'basic'
451
: Error: Spurious zero bits in bitstring.
454
17 1: OCTET STRING 0A
459
: '0000100000110000'B
460
: Error: Spurious zero bits in bitstring.
475
/* Read and parse the EF(TokenInfo).
477
TokenInfo ::= SEQUENCE {
478
version INTEGER {v1(0)} (v1,...),
479
serialNumber OCTET STRING,
480
manufacturerID Label OPTIONAL,
481
label [0] Label OPTIONAL,
482
tokenflags TokenFlags,
483
seInfo SEQUENCE OF SecurityEnvironmentInfo OPTIONAL,
484
recordInfo [1] RecordInfo OPTIONAL,
485
supportedAlgorithms [2] SEQUENCE OF AlgorithmInfo OPTIONAL,
487
issuerId [3] Label OPTIONAL,
488
holderId [4] Label OPTIONAL,
489
lastUpdate [5] LastUpdate OPTIONAL,
490
preferredLanguage PrintableString OPTIONAL -- In accordance with
492
} (CONSTRAINED BY { -- Each AlgorithmInfo.reference value must be unique --})
494
TokenFlags ::= BIT STRING {
504
30 31 02 01 00 04 04 05 45 36 9F 0C 0C 44 2D 54 01......E6...D-T
505
72 75 73 74 20 47 6D 62 48 80 14 4F 66 66 69 63 rust GmbH..Offic
506
65 20 69 64 65 6E 74 69 74 79 20 63 61 72 64 03 e identity card.
507
02 00 40 20 63 61 72 64 03 02 00 40 00 00 00 00 ..@ card...@....
508
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
512
5 4: OCTET STRING 05 45 36 9F
513
11 12: UTF8String 'D-Trust GmbH'
514
25 20: [0] 'Office identity card'
516
: '00000010'B (bit 1)
517
: Error: Spurious zero bits in bitstring.
525
read_ef_tokeninfo (app_t app)
527
unsigned short efid = 0x5032;
532
/* Get all the basic information from the pkcs#15 card, check the
533
structure and init our context. This is used once at application
536
read_p15_info (app_t app)
540
err = read_ed_odf (app);
548
do_learn_status (APP app, CTRL ctrl)
551
char ct_buf[100], id_buf[100];
554
/* Output information about all useful objects. */
555
for (i=0; objlist[i].fid; i++)
557
if (filelist[i].certtype)
561
len = app_help_read_length_of_cert (app->slot,
562
filelist[i].fid, NULL);
565
/* FIXME: We should store the length in the application's
566
context so that a following readcert does only need to
567
read that many bytes. */
568
sprintf (ct_buf, "%d", filelist[i].certtype);
569
sprintf (id_buf, "P15-DF01.%04X", filelist[i].fid);
570
send_status_info (ctrl, "CERTINFO",
571
ct_buf, strlen (ct_buf),
572
id_buf, strlen (id_buf),
576
else if (filelist[i].iskeypair)
580
err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr);
582
log_error ("can't get keygrip from FID 0x%04X: %s\n",
583
filelist[i].fid, gpg_strerror (err));
586
sprintf (id_buf, "P15-DF01.%04X", filelist[i].fid);
587
send_status_info (ctrl, "KEYPAIRINFO",
589
id_buf, strlen (id_buf),
601
/* Release all resources. */
603
do_deinit (app_t app)
605
if (app && app->app_local)
607
xfree (app->app_local);
608
app->app_local = NULL;
613
/* Select the PKCS#15 application on the card in SLOT. */
615
app_select_p15 (APP app)
617
static char const aid[] = { 0xA0, 0, 0, 0, 0x63,
618
0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
619
int slot = app->slot;
622
rc = iso7816_select_application (slot, aid, sizeof aid);
625
app->apptype = "P15";
627
app->app_local = xtrycalloc (1, sizeof *app->app_local);
630
rc = gpg_error_from_errno (errno);
634
/* Read basic information and check whether this is a real
636
rc = read_p15_info (app);
638
/* Special serial number munging. We need to do one case here
639
because we need to access the EF(TokenInfo). */
640
if (app->serialnolen == 12
641
&& !memcmp (app->serial, "\xD2\x76\0\0\0\0\0\0\0\0\0\0", 12))
643
/* This is a German card with a silly serial number. Try to get
644
the serial number from the EF(TokenInfo). We indicate such a
645
serial number by the using the prefix: "FF0100". */
646
const char *efser = card->p15card->serial_number;
654
p = xtrymalloc (strlen (efser) + 7);
656
rc = gpg_error (gpg_err_code_from_errno (errno));
659
strcpy (p, "FF0100");
665
rc = app_munge_serialno (app);
667
app->fnc.deinit = do_deinit;
668
app->fnc.learn_status = do_learn_status;
669
app->fnc.readcert = do_readcert;
670
app->fnc.getattr = NULL;
671
app->fnc.setattr = NULL;
672
app->fnc.genkey = NULL;
673
app->fnc.sign = do_sign;
674
app->fnc.auth = NULL;
675
app->fnc.decipher = do_decipher;
676
app->fnc.change_pin = NULL;
677
app->fnc.check_pin = NULL;
682
xfree (app->app_local);
683
app->app_local = NULL;