Update error handling to match gpg-error in CVS.
[gnupg.git] / scd / card-dinsig.c
1 /* card-dinsig.c - German signature law (DINSIG) functions
2  *      Copyright (C) 2002 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 /* The German signature law and its bylaw (SigG and SigV) is currently
22    used with an interface specification described in DIN V 66291-1.
23    The AID to be used is: 'D27600006601'.
24
25    The file IDs for certificates utilize the generic format: 
26         Cxyz
27     C being the hex digit 'C' (12).
28     x being the service indicator:
29          '0' := SigG conform digital signature.
30          '1' := entity authentication.
31          '2' := key encipherment.
32          '3' := data encipherment.
33          '4' := key agreement.
34          other values are reserved for future use.
35     y being the security environment number using '0' for cards
36       not supporting a SE number.
37     z being the certificate type:
38          '0'        := C.CH (base certificate of ard holder) or C.ICC.
39          '1' .. '7' := C.CH (business or professional certificate
40                        of card holder.
41          '8' .. 'D' := C.CA (certificate of a CA issue by the Root-CA).
42          'E'        := C.RCA (self certified certificate of the Root-CA).
43          'F'        := reserved.
44    
45    The file IDs used by default are:
46    '1F00'  EF.SSD (security service descriptor). [o,o]
47    '2F02'  EF.GDO (global data objects) [m,m]
48    'A000'  EF.PROT (signature log).  Cyclic file with 20 records of 53 byte.
49            Read and update after user authentication. [o,o]
50    'B000'  EF.PK.RCA.DS (public keys of Root-CA).  Size is 512b or size 
51            of keys. [m (unless a 'C00E' is present),m]
52    'B001'  EF.PK.CA.DS (public keys of CAs).  Size is 512b or size
53            of keys. [o,o]
54    'C00n'  EF.C.CH.DS (digital signature certificate of card holder)
55            with n := 0 .. 7.  Size is 2k or size of cert.  Read and
56            update allowed after user authentication. [m,m]
57    'C00m'  EF.C.CA.DS (digital signature certificate of CA)
58            with m := 8 .. E.  Size is 1k or size of cert.  Read always 
59            allowed, update after uder authentication. [o,o]
60    'C100'  EF.C.ICC.AUT (AUT certificate of ICC) [o,m]
61    'C108'  EF.C.CA.AUT (AUT certificate of CA) [o,m]
62    'D000'  EF.DM (display message) [-,m]
63    
64    The letters in brackets indicate optional or mandatory files: The
65    first for card terminals under full control and the second for
66    "business" card terminals.
67
68    FIXME: Needs a lot more explanation.
69
70 */
71
72
73 #include <config.h>
74 #include <errno.h>
75 #include <stdio.h>
76 #include <stdlib.h>
77 #include <string.h>
78 #include <time.h>
79
80 #ifdef HAVE_OPENSC
81 #include <opensc/pkcs15.h>
82 #include <ksba.h>
83
84 #include "scdaemon.h"
85 #include "card-common.h"
86
87 static int dinsig_read_cert (CARD card, const char *certidstr,
88                              unsigned char **cert, size_t *ncert);
89
90
91
92 /* See card.c for interface description.  Frankly we don't do any real
93    enumeration but just check whether the well know files are
94    available.  */
95 static int
96 dinsig_enum_keypairs (CARD card, int idx,
97                       unsigned char *keygrip, char **keyid)
98 {
99   int rc;
100   unsigned char *buf;
101   size_t buflen;
102   KsbaError krc;
103   KsbaCert cert;
104
105   /* fixme: We should locate the application via the EF(DIR) and not
106      assume a Netkey card */
107   if (!idx)
108     rc = dinsig_read_cert (card, "DINSIG-DF01.C000", &buf, &buflen);
109   else if (idx == 1)
110     rc = dinsig_read_cert (card, "DINSIG-DF01.C200", &buf, &buflen);
111   else
112     rc = -1;
113   if (rc)
114     return rc;
115
116   cert = ksba_cert_new ();
117   if (!cert)
118     {
119       gpg_error_t tmperr = out_of_core ();
120       xfree (buf);
121       return tmperr;
122     }
123
124   krc = ksba_cert_init_from_mem (cert, buf, buflen); 
125   xfree (buf);
126   if (krc)
127     {
128       log_error ("failed to parse the certificate at idx %d: %s\n",
129                  idx, ksba_strerror (krc));
130       ksba_cert_release (cert);
131       return gpg_error (GPG_ERR_CARD);
132     }
133   if (card_help_get_keygrip (cert, keygrip))
134     {
135       log_error ("failed to calculate the keygrip at index %d\n", idx);
136       ksba_cert_release (cert);
137       return gpg_error (GPG_ERR_CARD);
138     }      
139   ksba_cert_release (cert);
140
141   /* return the iD */
142   if (keyid)
143     {
144       *keyid = xtrymalloc (17);
145       if (!*keyid)
146         return out_of_core ();
147       if (!idx)
148         strcpy (*keyid, "DINSIG-DF01.C000");
149       else
150         strcpy (*keyid, "DINSIG-DF01.C200");
151     }
152   
153   return 0;
154 }
155
156
157 \f
158 /* See card.c for interface description */
159 static int
160 dinsig_read_cert (CARD card, const char *certidstr,
161                   unsigned char **cert, size_t *ncert)
162 {
163   int rc;
164   struct sc_path path;
165   struct sc_file *file;
166   unsigned char *buf;
167   int buflen;
168
169   if (!strcmp (certidstr, "DINSIG-DF01.C000"))
170     sc_format_path ("3F00DF01C000", &path);
171   else if (!strcmp (certidstr, "DINSIG-DF01.C200"))
172     sc_format_path ("3F00DF01C200", &path);
173   else
174     return gpg_error (GPG_ERR_INV_ID);
175
176   rc = sc_select_file (card->scard, &path, &file);
177   if (rc) 
178     {
179       log_error ("sc_select_file failed: %s\n", sc_strerror (rc));
180       return map_sc_err (rc);
181     }
182   if (file->type != SC_FILE_TYPE_WORKING_EF
183       || file->ef_structure != SC_FILE_EF_TRANSPARENT)
184     {
185       log_error ("wrong type or structure of certificate EF\n");
186       sc_file_free (file);
187       return gpg_error (GPG_ERR_CARD);
188     }
189   if (file->size < 20) /* check against a somewhat arbitrary length */
190     { 
191       log_error ("certificate EF too short\n");
192       sc_file_free (file);
193       return gpg_error (GPG_ERR_CARD);
194     }
195   buf = xtrymalloc (file->size);
196   if (!buf)
197     {
198       gpg_error_t tmperr = out_of_core ();
199       sc_file_free (file);
200       return tmperr;
201     }
202       
203   rc = sc_read_binary (card->scard, 0, buf, file->size, 0);
204   if (rc >= 0 && rc != file->size)
205     {
206       log_error ("short read on certificate EF\n");
207       sc_file_free (file);
208       xfree (buf);
209       return gpg_error (GPG_ERR_CARD);
210     }
211   sc_file_free (file);
212   if (rc < 0) 
213     {
214       log_error ("error reading certificate EF: %s\n", sc_strerror (rc));
215       xfree (buf);
216       return map_sc_err (rc);
217     }
218   buflen = rc;
219
220   /* The object is not a plain certificate but wrapped into id-at
221      userCertificate - fixme: we should check the specs and decided
222      whether libksba should support it */
223   if (buflen > 9 && buf[0] == 0x30 && buf[4] == 6 && buf[5] == 3
224       && buf[6] == 0x55 && buf[7] == 4 && buf[8] == 0x24)
225     {
226       /* We have to strip the padding.  Although this is a good idea
227          anyway, we have to do it due to a KSBA problem; KSBA does not
228          work correct when the buffer is larger than the ASN.1
229          structure and the certificates here are padded with FF.  So
230          as a workaround we look at the outer structure to get the
231          size of the entire thing and adjust the buflen.  We can only
232          do this when there is a 2 byte length field */
233       size_t seqlen;
234       if (buf[1] == 0x82)
235         {
236           seqlen = ((buf[2] << 8) | buf[3]) + 4;
237           if (seqlen < buflen)
238             buflen = seqlen;
239         }
240       memmove (buf, buf+9, buflen-9);
241       buflen -= 9;
242     } 
243
244   *cert = buf;
245   *ncert = buflen;
246   return 0;
247 }
248
249
250
251
252 /* Bind our operations to the card */
253 void
254 card_dinsig_bind (CARD card)
255 {
256   card->fnc.enum_keypairs = dinsig_enum_keypairs;
257   card->fnc.read_cert     = dinsig_read_cert;
258
259 }
260 #endif /*HAVE_OPENSC*/