~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to scd/app-p15.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* app-p15.c - The pkcs#15 card application.
 
2
 *      Copyright (C) 2004 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
#include <errno.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <assert.h>
 
27
#include <time.h>
 
28
 
 
29
#include "scdaemon.h"
 
30
 
 
31
#include "iso7816.h"
 
32
#include "app-common.h"
 
33
#include "tlv.h"
 
34
 
 
35
 
 
36
/* Context local to this application. */
 
37
struct app_local_s 
 
38
{
 
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.  */
 
42
  struct
 
43
  {
 
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;
 
53
  } odf;  
 
54
 
 
55
 
 
56
};
 
57
 
 
58
 
 
59
 
 
60
 
 
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. */
 
65
static gpg_error_t 
 
66
select_and_read_binary (int slot, unsigned short efid, const char *efid_desc,
 
67
                        unsigned char **buffer, size_t *buflen)
 
68
{
 
69
  gpg_error_t err;
 
70
 
 
71
  err = iso7816_select_file (slot, efid, 0, NULL, NULL);
 
72
  if (err)
 
73
    {
 
74
      log_error ("error selecting %s (0x%04X): %s\n",
 
75
                 efid_desc, efid, gpg_strerror (err));
 
76
      return err;
 
77
    }
 
78
  err = iso7816_read_binary (slot, 0, 0, buffer, buflen);
 
79
  if (err)
 
80
    {
 
81
      log_error ("error reading %s (0x%04X): %s\n",
 
82
                 efid_desc, efid, gpg_strerror (err));
 
83
      return err;
 
84
    }
 
85
  return 0;
 
86
}
 
87
 
 
88
 
 
89
 
 
90
 
 
91
/* Read and parse the Object Directory File and store away the
 
92
   pointers.
 
93
 
 
94
   Example of such a file:
 
95
 
 
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
 
101
    
 
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.
 
105
*/
 
106
static gpg_error_t
 
107
read_ef_odf (app_t app)
 
108
{
 
109
  gpg_error_t err;
 
110
  unsigned char *buffer, *p;
 
111
  size_t buflen;
 
112
  unsigned short value;
 
113
 
 
114
  err = select_and_read_binary (app->slot, 0x5031, "ODF", &buffer, &buflen);
 
115
  if (err)
 
116
    return err;
 
117
 
 
118
  if (len < 8)
 
119
    {
 
120
      log_error ("error: ODF too short\n");
 
121
      xfree (buffer);
 
122
      return gpg_error (GPG_ERR_INV_OBJ);
 
123
    }
 
124
  for (p=buffer; buflen >= 8; p += 8, buflen -= 8)
 
125
    {
 
126
      if ( (p[0] & 0xf0) != 0xA0
 
127
           || memcmp (p+1, "\x06\x30\x04\x04\x02", 5) )
 
128
        {
 
129
          log_error ("ODF format is not supported by us\n");
 
130
          xfree (buffer);
 
131
          return gpg_error (GPG_ERR_INV_OBJ);
 
132
        }
 
133
      switch ((p[0] & 0x0f))
 
134
        {
 
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;
 
145
        }
 
146
      if (value)
 
147
        {
 
148
          log_error ("duplicate object type %d in ODF ignored\n",(p[0)&0x0f));
 
149
          continue;
 
150
        }
 
151
      value = ((p[6] << 8) | p[7]);
 
152
      switch ((p[0] & 0x0f))
 
153
        {
 
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;
 
163
        default: 
 
164
          log_error ("unknown object type %d in ODF ignored\n", (p[0)&0x0f));
 
165
        }
 
166
    }
 
167
 
 
168
  if (buflen)
 
169
    log_info ("warning: %u bytes of garbage detected at end of ODF\n", buflen);
 
170
 
 
171
  xfree (buffer);
 
172
  return 0;
 
173
}
 
174
 
 
175
 
 
176
 
 
177
/* Read and  parse the Private Key Directory Files. */
 
178
/*
 
179
  6034 (privatekeys)
 
180
 
 
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   ................
 
197
 
 
198
*/
 
199
static gpg_error_t
 
200
read_ef_prkdf (app_t app)
 
201
{
 
202
 
 
203
 
 
204
}
 
205
 
 
206
/* Read and  parse the Public Key Directory Files. */
 
207
static gpg_error_t
 
208
read_ef_pukdf (app_t app)
 
209
{
 
210
 
 
211
 
 
212
}
 
213
 
 
214
 
 
215
/* Read and parse the Certificate Directory Files. */
 
216
/* 
 
217
 
 
218
6035 (certificates)
 
219
 
 
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   ................
 
236
 
 
237
   0   42: SEQUENCE {
 
238
   2   21:   SEQUENCE {   -- commonObjectAttributes
 
239
   4   12:     UTF8String 'C_X509.CH.DS'
 
240
  18    2:     BIT STRING 6 unused bits
 
241
         :       '10'B (bit 1)
 
242
  22    1:     OCTET STRING 0A
 
243
         :     }
 
244
  25    3:   SEQUENCE {   -- commonCertificateAttributes
 
245
  27    1:     OCTET STRING 01
 
246
         :     }
 
247
  30   12:   [1] {        -- certAttributes
 
248
  32   10:     SEQUENCE {
 
249
  34    8:       SEQUENCE {
 
250
  36    6:         OCTET STRING 3F 00 40 16 C0 00
 
251
         :         }
 
252
         :       }
 
253
         :     }
 
254
         :   }
 
255
 
 
256
 
 
257
 
 
258
6036 (trustedcertificates)
 
259
 
 
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   ................
 
272
 
 
273
   0   53: SEQUENCE {
 
274
   2    6:   SEQUENCE {
 
275
   4    2:     BIT STRING
 
276
         :       '00000000'B
 
277
         :       Error: Spurious zero bits in bitstring.
 
278
   8    0:     OCTET STRING
 
279
         :       Error: Object has zero length.
 
280
         :     }
 
281
  10   22:   SEQUENCE {
 
282
  12   20:     OCTET STRING '-6393394039776401216'
 
283
         :     }
 
284
  34   19:   [1] {
 
285
  36   17:     SEQUENCE {
 
286
  38   15:       SEQUENCE {
 
287
  40    6:         OCTET STRING 3F 00 40 16 C7 08
 
288
  48    1:         INTEGER 0       -- index
 
289
  51    2:         [0] 02 29       -- length
 
290
         :         }
 
291
         :       }
 
292
         :     }
 
293
         :   }
 
294
 
 
295
 
 
296
*/
 
297
static gpg_error_t
 
298
read_ef_cdf (app_t app)
 
299
{
 
300
  gpg_error_t err;
 
301
  unsigned char *buffer = NULL;
 
302
  size_t buflen;
 
303
  unsigned short value;
 
304
  unsigned short fid;
 
305
  const unsigned char *p;
 
306
  size_t n, objlen, hdrlen;
 
307
  int class, tag, constructed, ndef;
 
308
  
 
309
  fid = app->app_local->odf.certificates;
 
310
  if (!fid)
 
311
    return 0; /* No certificates. */
 
312
  
 
313
  err = select_and_read_binary (app->slot, fid, "CDF", &buffer, &buflen);
 
314
  if (err)
 
315
    return err;
 
316
  
 
317
  p = buffer;
 
318
  n = buflen;
 
319
 
 
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)
 
324
    {
 
325
      const unsigned char *pp;
 
326
      size_t nn;
 
327
 
 
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);
 
332
      if (err)
 
333
        {
 
334
          log_error ("error parsing CDF record: %s\n", gpg_strerror (err));
 
335
          goto leave;
 
336
        }
 
337
      pp = p;
 
338
      nn = objlen;
 
339
      p += objlen;
 
340
      n -= objlen;
 
341
 
 
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);
 
347
      if (err)
 
348
        {
 
349
          log_error ("error parsing CDF record: %s - skipped\n",
 
350
                     gpg_strerror (err));
 
351
          continue;
 
352
        }
 
353
      pp += objlen;
 
354
      nn -= objlen;
 
355
 
 
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);
 
361
      if (err)
 
362
        {
 
363
          log_error ("error parsing CDF record: %s - skipped\n",
 
364
                     gpg_strerror (err));
 
365
          continue;
 
366
        }
 
367
      pp += objlen;
 
368
      nn -= objlen;
 
369
 
 
370
      /* FIXME: Check that this is a reference to a certificate. */
 
371
 
 
372
 
 
373
    }
 
374
 
 
375
 
 
376
 leave:
 
377
  xfree (buffer);
 
378
  return err;
 
379
}
 
380
 
 
381
/* Read and parse Authentication Object Directory Files.  */
 
382
static gpg_error_t 
 
383
read_ef_aodf (app_t app)
 
384
{
 
385
 
 
386
}
 
387
 
 
388
 
 
389
/* 6037 (dataobjects)
 
390
 
 
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                            @.......        
 
415
 
 
416
   0   30: SEQUENCE {
 
417
   2   11:   SEQUENCE {
 
418
   4    6:     UTF8String 'EF.GDO'
 
419
  12    1:     OCTET STRING 0A
 
420
         :     }
 
421
  15    2:   SEQUENCE {
 
422
  17    0:     UTF8String
 
423
         :       Error: Object has zero length.
 
424
         :     }
 
425
  19   11:   [1] {
 
426
  21    9:     SEQUENCE {
 
427
  23    4:       OCTET STRING 3F 00 2F 02
 
428
  29    1:       [0] 0E
 
429
         :       }
 
430
         :     }
 
431
         :   }
 
432
 
 
433
 
 
434
 
 
435
6038 (authobjects)
 
436
 
 
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...?.@. 
 
445
 
 
446
   0   42: SEQUENCE {
 
447
   2   11:   SEQUENCE {
 
448
   4    5:     UTF8String 'basic'
 
449
  11    2:     BIT STRING
 
450
         :       '00000011'B
 
451
         :       Error: Spurious zero bits in bitstring.
 
452
         :     }
 
453
  15    3:   SEQUENCE {
 
454
  17    1:     OCTET STRING 0A
 
455
         :     }
 
456
  20   22:   [1] {
 
457
  22   20:     SEQUENCE {
 
458
  24    3:       BIT STRING
 
459
         :         '0000100000110000'B
 
460
         :         Error: Spurious zero bits in bitstring.
 
461
  29    1:       ENUMERATED 1
 
462
  32    1:       INTEGER 6
 
463
  35    1:       INTEGER 6
 
464
  38    1:       INTEGER 8
 
465
  41    1:       [0] 01
 
466
         :       }
 
467
         :     }
 
468
         :   }
 
469
 
 
470
 
 
471
 
 
472
*/
 
473
 
 
474
 
 
475
/* Read and parse the EF(TokenInfo). 
 
476
 
 
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,
 
486
    ...,
 
487
    issuerId            [3] Label OPTIONAL,
 
488
    holderId            [4] Label OPTIONAL,
 
489
    lastUpdate          [5] LastUpdate OPTIONAL,
 
490
    preferredLanguage   PrintableString OPTIONAL -- In accordance with
 
491
    -- IETF RFC 1766 
 
492
} (CONSTRAINED BY { -- Each AlgorithmInfo.reference value must be unique --})
 
493
 
 
494
TokenFlags ::= BIT STRING {
 
495
    readonly            (0),
 
496
    loginRequired       (1),
 
497
    prnGeneration       (2),
 
498
    eidCompliant        (3)
 
499
}
 
500
 
 
501
 
 
502
 5032:
 
503
 
 
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   ................
 
509
 
 
510
   0   49: SEQUENCE {
 
511
   2    1:   INTEGER 0
 
512
   5    4:   OCTET STRING 05 45 36 9F
 
513
  11   12:   UTF8String 'D-Trust GmbH'
 
514
  25   20:   [0] 'Office identity card'
 
515
  47    2:   BIT STRING
 
516
         :     '00000010'B (bit 1)
 
517
         :     Error: Spurious zero bits in bitstring.
 
518
         :   }
 
519
 
 
520
 
 
521
 
 
522
 
 
523
 */
 
524
static gpg_error_t
 
525
read_ef_tokeninfo (app_t app)
 
526
{
 
527
  unsigned short efid = 0x5032;
 
528
 
 
529
}
 
530
 
 
531
 
 
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
 
534
   initialization. */
 
535
static gpg_error_t
 
536
read_p15_info (app_t app)
 
537
{
 
538
  gpg_error_t err;
 
539
 
 
540
  err = read_ed_odf (app);
 
541
  if (err)
 
542
    return err;
 
543
 
 
544
}
 
545
 
 
546
 
 
547
static int
 
548
do_learn_status (APP app, CTRL ctrl)
 
549
{
 
550
  gpg_error_t err;
 
551
  char ct_buf[100], id_buf[100];
 
552
  int i;
 
553
 
 
554
  /* Output information about all useful objects. */
 
555
  for (i=0; objlist[i].fid; i++)
 
556
    {
 
557
      if (filelist[i].certtype)
 
558
        {
 
559
          size_t len;
 
560
 
 
561
          len = app_help_read_length_of_cert (app->slot,
 
562
                                              filelist[i].fid, NULL);
 
563
          if (len)
 
564
            {
 
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), 
 
573
                                NULL, (size_t)0);
 
574
            }
 
575
        }
 
576
      else if (filelist[i].iskeypair)
 
577
        {
 
578
          char gripstr[40+1];
 
579
 
 
580
          err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr);
 
581
          if (err)
 
582
            log_error ("can't get keygrip from FID 0x%04X: %s\n",
 
583
                       filelist[i].fid, gpg_strerror (err));
 
584
          else
 
585
            {
 
586
              sprintf (id_buf, "P15-DF01.%04X", filelist[i].fid);
 
587
              send_status_info (ctrl, "KEYPAIRINFO",
 
588
                                gripstr, 40, 
 
589
                                id_buf, strlen (id_buf), 
 
590
                                NULL, (size_t)0);
 
591
            }
 
592
        }
 
593
    }
 
594
 
 
595
  return 0;
 
596
}
 
597
 
 
598
 
 
599
 
 
600
 
 
601
/* Release all resources.  */
 
602
static void
 
603
do_deinit (app_t app)
 
604
{
 
605
  if (app && app->app_local)
 
606
    {
 
607
      xfree (app->app_local);
 
608
      app->app_local = NULL;
 
609
    }
 
610
}
 
611
 
 
612
 
 
613
/* Select the PKCS#15 application on the card in SLOT.  */
 
614
int
 
615
app_select_p15 (APP app)
 
616
{
 
617
  static char const aid[] = { 0xA0, 0, 0, 0, 0x63,
 
618
                              0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
 
619
  int slot = app->slot;
 
620
  int rc;
 
621
  
 
622
  rc = iso7816_select_application (slot, aid, sizeof aid);
 
623
  if (!rc)
 
624
    {
 
625
      app->apptype = "P15";
 
626
 
 
627
      app->app_local = xtrycalloc (1, sizeof *app->app_local);
 
628
      if (!app->app_local)
 
629
        {
 
630
          rc = gpg_error_from_errno (errno);
 
631
          goto leave;
 
632
        }
 
633
 
 
634
      /* Read basic information and check whether this is a real
 
635
         card.  */
 
636
      rc = read_p15_info (app);
 
637
      
 
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))
 
642
        {
 
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;
 
647
          char *p;
 
648
          
 
649
          if (!efser)
 
650
            efser = "";
 
651
          
 
652
          xfree (*serial);
 
653
          *serial = NULL;
 
654
          p = xtrymalloc (strlen (efser) + 7);
 
655
          if (!p)
 
656
            rc = gpg_error (gpg_err_code_from_errno (errno));
 
657
          else
 
658
            {
 
659
              strcpy (p, "FF0100");
 
660
              strcpy (p+6, efser);
 
661
              *serial = p;
 
662
            }
 
663
        }
 
664
      else
 
665
        rc = app_munge_serialno (app);
 
666
 
 
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;
 
678
 
 
679
    leave:
 
680
      if (rc)
 
681
        {
 
682
          xfree (app->app_local);
 
683
          app->app_local = NULL;
 
684
        }
 
685
      
 
686
   }
 
687
 
 
688
  return rc;
 
689
}
 
690
 
 
691