/src/opensc/src/libopensc/pkcs15-tcos.c
Line | Count | Source |
1 | | /* |
2 | | * PKCS15 emulation layer for TCOS based preformatted cards |
3 | | * |
4 | | * Copyright (C) 2011, Peter Koch <pk@opensc-project.org> |
5 | | * |
6 | | * This library is free software; you can redistribute it and/or |
7 | | * modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * This library 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 GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this library; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | */ |
20 | | |
21 | | #ifdef HAVE_CONFIG_H |
22 | | #include "config.h" |
23 | | #endif |
24 | | |
25 | | #include <stdlib.h> |
26 | | #include <string.h> |
27 | | #include <stdio.h> |
28 | | |
29 | | #include "common/compat_strlcpy.h" |
30 | | #include "common/compat_strlcat.h" |
31 | | #include "internal.h" |
32 | | #include "pkcs15.h" |
33 | | #include "cardctl.h" |
34 | | #include "log.h" |
35 | | |
36 | | static int insert_cert( |
37 | | sc_pkcs15_card_t *p15card, |
38 | | const char *path, |
39 | | unsigned char id, |
40 | | int writable, |
41 | | const char *label |
42 | 0 | ){ |
43 | 0 | sc_card_t *card=p15card->card; |
44 | 0 | sc_context_t *ctx=p15card->card->ctx; |
45 | 0 | struct sc_pkcs15_cert_info cert_info; |
46 | 0 | struct sc_pkcs15_object cert_obj; |
47 | 0 | unsigned char cert[20]; |
48 | 0 | size_t cert_len = 0; |
49 | 0 | int r; |
50 | |
|
51 | 0 | memset(&cert_info, 0, sizeof(cert_info)); |
52 | 0 | cert_info.id.len = 1; |
53 | 0 | cert_info.id.value[0] = id; |
54 | 0 | cert_info.authority = 0; |
55 | 0 | sc_format_path(path, &cert_info.path); |
56 | |
|
57 | 0 | memset(&cert_obj, 0, sizeof(cert_obj)); |
58 | 0 | strlcpy(cert_obj.label, label, sizeof(cert_obj.label)); |
59 | 0 | cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0; |
60 | |
|
61 | 0 | if (sc_select_file(card, &cert_info.path, NULL) != SC_SUCCESS) { |
62 | 0 | sc_log(ctx, "Select(%s) failed", path); |
63 | 0 | return 1; |
64 | 0 | } |
65 | 0 | r = sc_read_binary(card, 0, cert, sizeof(cert), 0); |
66 | 0 | if (r <= 0) { |
67 | 0 | sc_log(ctx, "ReadBinary(%s) failed\n", path); |
68 | 0 | return 2; |
69 | 0 | } |
70 | 0 | cert_len = r; /* actual number of read bytes */ |
71 | 0 | if (cert_len < 4) { |
72 | 0 | sc_log(ctx, "Invalid certificate length"); |
73 | 0 | return 3; |
74 | 0 | } |
75 | 0 | if (cert[0] != 0x30 || cert[1] != 0x82) { |
76 | 0 | sc_log(ctx, "Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]); |
77 | 0 | return 3; |
78 | 0 | } |
79 | | |
80 | | /* some certificates are prefixed by an OID */ |
81 | 0 | if (cert_len >= 5 && (size_t)(7 + cert[5]) <= cert_len && |
82 | 0 | cert[4] == 0x06 && cert[5] < 10 && cert[6 + cert[5]] == 0x30 && |
83 | 0 | cert[7 + cert[5]] == 0x82) { |
84 | 0 | if ((size_t)(9 + cert[5]) > cert_len) { |
85 | 0 | sc_log(ctx, "Invalid certificate length"); |
86 | 0 | return 3; |
87 | 0 | } |
88 | 0 | cert_info.path.index=6+cert[5]; |
89 | 0 | cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4; |
90 | 0 | } else { |
91 | 0 | cert_info.path.index=0; |
92 | 0 | cert_info.path.count=(cert[2]<<8) + cert[3] + 4; |
93 | 0 | } |
94 | | |
95 | 0 | r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); |
96 | 0 | if (r != SC_SUCCESS) { |
97 | 0 | sc_log(ctx, "sc_pkcs15emu_add_x509_cert(%s) failed", path); |
98 | 0 | return 4; |
99 | 0 | } |
100 | 0 | sc_log(ctx, "%s: OK, Index=%d, Count=%d", path, cert_info.path.index, cert_info.path.count); |
101 | 0 | return 0; |
102 | 0 | } |
103 | | |
104 | | static int insert_key( |
105 | | sc_pkcs15_card_t *p15card, |
106 | | const char *path, |
107 | | unsigned char id, |
108 | | unsigned char key_reference, |
109 | | int key_length, |
110 | | unsigned char auth_id, |
111 | | const char *label |
112 | | ) |
113 | 0 | { |
114 | 0 | sc_card_t *card = p15card->card; |
115 | 0 | sc_context_t *ctx = p15card->card->ctx; |
116 | 0 | sc_file_t *f; |
117 | 0 | struct sc_pkcs15_prkey_info prkey_info; |
118 | 0 | struct sc_pkcs15_object prkey_obj; |
119 | 0 | int r, can_sign, can_crypt; |
120 | |
|
121 | 0 | memset(&prkey_info, 0, sizeof(prkey_info)); |
122 | 0 | prkey_info.id.len = 1; |
123 | 0 | prkey_info.id.value[0] = id; |
124 | 0 | prkey_info.native = 1; |
125 | 0 | prkey_info.key_reference = key_reference; |
126 | 0 | prkey_info.modulus_length = key_length; |
127 | 0 | sc_format_path(path, &prkey_info.path); |
128 | |
|
129 | 0 | memset(&prkey_obj, 0, sizeof(prkey_obj)); |
130 | 0 | strlcpy(prkey_obj.label, label, sizeof(prkey_obj.label)); |
131 | 0 | prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; |
132 | 0 | prkey_obj.auth_id.len = 1; |
133 | 0 | prkey_obj.auth_id.value[0] = auth_id; |
134 | |
|
135 | 0 | can_sign = can_crypt = 0; |
136 | 0 | if (card->type == SC_CARD_TYPE_TCOS_V3) { |
137 | 0 | unsigned char buf[256]; |
138 | 0 | int i, rec_no = 0; |
139 | 0 | if (prkey_info.path.len >= 2) |
140 | 0 | prkey_info.path.len -= 2; |
141 | 0 | sc_append_file_id(&prkey_info.path, 0x5349); |
142 | 0 | if (sc_select_file(card, &prkey_info.path, NULL) != SC_SUCCESS) { |
143 | 0 | sc_log(ctx, "Select(%s) failed", sc_print_path(&prkey_info.path)); |
144 | 0 | return 1; |
145 | 0 | } |
146 | 0 | sc_log(ctx, "Searching for Key-Ref %02X", key_reference); |
147 | 0 | while ((r = sc_read_record(card, ++rec_no, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { |
148 | 0 | int found = 0; |
149 | 0 | if (buf[0] != 0xA0 || r < 2) |
150 | 0 | continue; |
151 | 0 | for (i = 2; i < buf[1] + 2 && i < r - 2; i += 2 + buf[i + 1]) { |
152 | 0 | if (buf[i] == 0x83 && buf[i + 1] == 1 && buf[i + 2] == key_reference) |
153 | 0 | ++found; |
154 | 0 | } |
155 | 0 | if (found) |
156 | 0 | break; |
157 | 0 | } |
158 | 0 | if (r <= 0) { |
159 | 0 | sc_log(ctx, "No EF_KEYD-Record found"); |
160 | 0 | return 1; |
161 | 0 | } |
162 | 0 | for (i = 0; i + 1 < r; i += 2 + buf[i + 1]) { |
163 | 0 | if (buf[i] == 0xB6) |
164 | 0 | can_sign++; |
165 | 0 | if (buf[i] == 0xB8) |
166 | 0 | can_crypt++; |
167 | 0 | } |
168 | 0 | } else { |
169 | 0 | if (sc_select_file(card, &prkey_info.path, &f) != SC_SUCCESS |
170 | 0 | || !f->prop_attr || f->prop_attr_len < 2){ |
171 | 0 | sc_log(ctx, "Select(%s) failed", sc_print_path(&prkey_info.path)); |
172 | 0 | sc_file_free(f); |
173 | 0 | return 1; |
174 | 0 | } |
175 | 0 | if (f->prop_attr[1] & 0x04) |
176 | 0 | can_crypt = 1; |
177 | 0 | if (f->prop_attr[1] & 0x08) |
178 | 0 | can_sign = 1; |
179 | 0 | sc_file_free(f); |
180 | 0 | } |
181 | 0 | prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN; |
182 | 0 | if (can_crypt) |
183 | 0 | prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; |
184 | 0 | if (can_sign) |
185 | 0 | prkey_info.usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; |
186 | |
|
187 | 0 | r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); |
188 | 0 | if(r != SC_SUCCESS) { |
189 | 0 | sc_log(ctx, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", path); |
190 | 0 | return 4; |
191 | 0 | } |
192 | 0 | sc_log(ctx, "%s: OK%s%s\n", path, can_sign ? ", Sign" : "", can_crypt ? ", Crypt" : ""); |
193 | 0 | return 0; |
194 | 0 | } |
195 | | |
196 | | static int insert_pin( |
197 | | sc_pkcs15_card_t *p15card, |
198 | | const char *path, |
199 | | unsigned char id, |
200 | | unsigned char auth_id, |
201 | | unsigned char pin_reference, |
202 | | int min_length, |
203 | | const char *label, |
204 | | int pin_flags |
205 | 0 | ){ |
206 | 0 | sc_card_t *card=p15card->card; |
207 | 0 | sc_context_t *ctx=p15card->card->ctx; |
208 | 0 | sc_file_t *f = NULL; |
209 | 0 | struct sc_pkcs15_auth_info pin_info; |
210 | 0 | struct sc_pkcs15_object pin_obj; |
211 | 0 | int r; |
212 | |
|
213 | 0 | memset(&pin_info, 0, sizeof(pin_info)); |
214 | 0 | pin_info.auth_id.len = 1; |
215 | 0 | pin_info.auth_id.value[0] = id; |
216 | 0 | pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN; |
217 | 0 | pin_info.attrs.pin.reference = pin_reference; |
218 | 0 | pin_info.attrs.pin.flags = pin_flags; |
219 | 0 | pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; |
220 | 0 | pin_info.attrs.pin.min_length = min_length; |
221 | 0 | pin_info.attrs.pin.stored_length = 16; |
222 | 0 | pin_info.attrs.pin.max_length = 16; |
223 | 0 | pin_info.attrs.pin.pad_char = '\0'; |
224 | 0 | pin_info.logged_in = SC_PIN_STATE_UNKNOWN; |
225 | 0 | sc_format_path(path, &pin_info.path); |
226 | |
|
227 | 0 | memset(&pin_obj, 0, sizeof(pin_obj)); |
228 | 0 | strlcpy(pin_obj.label, label, sizeof(pin_obj.label)); |
229 | 0 | pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; |
230 | 0 | pin_obj.auth_id.len = auth_id ? 0 : 1; |
231 | 0 | pin_obj.auth_id.value[0] = auth_id; |
232 | |
|
233 | 0 | if(card->type == SC_CARD_TYPE_TCOS_V3) { |
234 | 0 | unsigned char buf[256]; |
235 | 0 | int i, rec_no=0; |
236 | 0 | if (pin_info.path.len >= 2) { |
237 | 0 | pin_info.path.len -= 2; |
238 | 0 | } |
239 | 0 | sc_append_file_id(&pin_info.path, 0x5049); |
240 | 0 | if (sc_select_file(card, &pin_info.path, NULL) != SC_SUCCESS) { |
241 | 0 | sc_log(ctx, "Select(%s) failed", sc_print_path(&pin_info.path)); |
242 | 0 | return 1; |
243 | 0 | } |
244 | 0 | sc_log(ctx, "Searching for PIN-Ref %02X", pin_reference); |
245 | 0 | while ((r = sc_read_record(card, ++rec_no, 0, buf, sizeof(buf), SC_RECORD_BY_REC_NR)) > 0) { |
246 | 0 | int found = 0, fbz = -1; |
247 | 0 | if (r < 2 || buf[0] != 0xA0) |
248 | 0 | continue; |
249 | 0 | for (i = 2; i < buf[1] + 2 && (i + 2) < r; i += 2 + buf[i + 1]) { |
250 | 0 | if (buf[i] == 0x83 && buf[i + 1] == 1 && buf[i + 2] == pin_reference) { |
251 | 0 | ++found; |
252 | 0 | } |
253 | 0 | if (buf[i] == 0x90 && (i + 1 + buf[i + 1]) < r) { |
254 | 0 | fbz = buf[i + 1 + buf[i + 1]]; |
255 | 0 | } |
256 | 0 | } |
257 | 0 | if (found) { |
258 | 0 | pin_info.tries_left = fbz; |
259 | 0 | break; |
260 | 0 | } |
261 | 0 | } |
262 | 0 | if (r <= 0) { |
263 | 0 | sc_log(ctx, "No EF_PWDD-Record found\n"); |
264 | 0 | return 1; |
265 | 0 | } |
266 | 0 | } else { |
267 | 0 | if (sc_select_file(card, &pin_info.path, &f) != SC_SUCCESS |
268 | 0 | || !f->prop_attr || f->prop_attr_len < 4){ |
269 | 0 | sc_log(ctx, "Select(%s) failed\n", path); |
270 | 0 | sc_file_free(f); |
271 | 0 | return 1; |
272 | 0 | } |
273 | 0 | pin_info.tries_left = f->prop_attr[3]; |
274 | 0 | sc_file_free(f); |
275 | 0 | } |
276 | | |
277 | 0 | r=sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); |
278 | 0 | if(r!=SC_SUCCESS){ |
279 | 0 | sc_log(ctx, "sc_pkcs15emu_add_pin_obj(%s) failed\n", path); |
280 | 0 | return 4; |
281 | 0 | } |
282 | 0 | sc_log(ctx, "%s: OK, FBZ=%d\n", path, pin_info.tries_left); |
283 | 0 | return 0; |
284 | 0 | } |
285 | | |
286 | 0 | static char *dirpath(char *dir, const char *path){ |
287 | 0 | static char buf[SC_MAX_PATH_STRING_SIZE]; |
288 | |
|
289 | 0 | strlcpy(buf,dir,sizeof buf); |
290 | 0 | strlcat(buf,path,sizeof buf); |
291 | 0 | return buf; |
292 | 0 | } |
293 | | |
294 | | static int detect_netkey( |
295 | | sc_pkcs15_card_t *p15card |
296 | 0 | ){ |
297 | 0 | sc_card_t *card=p15card->card; |
298 | 0 | sc_path_t p; |
299 | 0 | sc_file_t *f; |
300 | 0 | int keylen; |
301 | 0 | char dir[10]; |
302 | 0 | const char *c_auth; |
303 | | |
304 | | /* NKS-Applikation ? */ |
305 | 0 | memset(&p, 0, sizeof(sc_path_t)); |
306 | 0 | p.type=SC_PATH_TYPE_DF_NAME; |
307 | 0 | memcpy(p.value, "\xD2\x76\x00\x00\x03\x01\x02", p.len=7); |
308 | 0 | if (sc_select_file(card,&p,&f)!=SC_SUCCESS) return 1; |
309 | 0 | sprintf(dir,"%04X", f->id); |
310 | 0 | sc_file_free(f); |
311 | |
|
312 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "TeleSec GmbH"); |
313 | 0 | set_string(&p15card->tokeninfo->label, card->type==SC_CARD_TYPE_TCOS_V3 ? "NetKey V3 Card" : "NetKey Card"); |
314 | 0 | keylen= card->type==SC_CARD_TYPE_TCOS_V3 ? 2048 : 1024; |
315 | 0 | c_auth= card->type==SC_CARD_TYPE_TCOS_V3 ? "C500" : "C100"; |
316 | |
|
317 | 0 | insert_cert(p15card, dirpath(dir,"4331"), 0x45, 1, "Signatur Zertifikat 1"); |
318 | 0 | insert_cert(p15card, dirpath(dir,"4332"), 0x45, 1, "Signatur Zertifikat 2"); |
319 | 0 | insert_cert(p15card, dirpath(dir,"C000"), 0x45, 0, "Telesec Signatur Zertifikat"); |
320 | 0 | insert_cert(p15card, dirpath(dir,"43B1"), 0x46, 1, "Verschluesselungs Zertifikat 1"); |
321 | 0 | insert_cert(p15card, dirpath(dir,"43B2"), 0x46, 1, "Verschluesselungs Zertifikat 2"); |
322 | 0 | insert_cert(p15card, dirpath(dir,"C200"), 0x46, 0, "Telesec Verschluesselungs Zertifikat"); |
323 | 0 | insert_cert(p15card, dirpath(dir,"4371"), 0x47, 1, "Authentifizierungs Zertifikat 1"); |
324 | 0 | insert_cert(p15card, dirpath(dir,"4372"), 0x47, 1, "Authentifizierungs Zertifikat 2"); |
325 | 0 | insert_cert(p15card, dirpath(dir,c_auth), 0x47, 0, "Telesec Authentifizierungs Zertifikat"); |
326 | 0 | insert_cert(p15card, dirpath(dir,"C201"), 0x48, 0, "Telesec 1024bit Zertifikat"); |
327 | |
|
328 | 0 | insert_key(p15card, dirpath(dir,"5331"), 0x45, 0x80, keylen, 4, "Signatur Schluessel"); |
329 | 0 | insert_key(p15card, dirpath(dir,"53B1"), 0x46, 0x81, keylen, 3, "Verschluesselungs Schluessel"); |
330 | 0 | insert_key(p15card, dirpath(dir,"5371"), 0x47, 0x82, keylen, 3, "Authentifizierungs Schluessel"); |
331 | 0 | insert_key(p15card, dirpath(dir,"0000"), 0x48, 0x83, 1024, 3, "1024bit Schluessel"); |
332 | |
|
333 | 0 | insert_pin(p15card, "5000", 1, 2, 0x00, 6, "PIN", |
334 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED |
335 | 0 | ); |
336 | 0 | insert_pin(p15card, "5001", 2, 0, 0x01, 8, "PUK", |
337 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | |
338 | 0 | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN |
339 | 0 | ); |
340 | 0 | if(card->type==SC_CARD_TYPE_TCOS_V3){ |
341 | 0 | insert_pin(p15card, dirpath(dir,"0000"), 3, 1, 0x83, 6, "NetKey PIN2", |
342 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
343 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
344 | 0 | ); |
345 | 0 | } else { |
346 | 0 | insert_pin(p15card, dirpath(dir,"5080"), 3, 1, 0x80, 6, "NetKey PIN0", |
347 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
348 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
349 | 0 | ); |
350 | 0 | } |
351 | 0 | insert_pin(p15card, dirpath(dir,"5081"), 4, 1, 0x81, 6, "NetKey PIN1", |
352 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
353 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
354 | 0 | ); |
355 | | |
356 | | /* SigG-Applikation */ |
357 | 0 | p.len=7; p.type=SC_PATH_TYPE_DF_NAME; |
358 | 0 | memcpy(p.value, "\xD2\x76\x00\x00\x66\x01", p.len=6); |
359 | 0 | if (sc_select_file(card,&p,&f)==SC_SUCCESS){ |
360 | 0 | sprintf(dir,"%04X", f->id); |
361 | 0 | sc_file_free(f); |
362 | |
|
363 | 0 | insert_cert(p15card, dirpath(dir,"C000"), 0x49, 1, "SigG Zertifikat 1"); |
364 | 0 | insert_cert(p15card, dirpath(dir,"4331"), 0x49, 1, "SigG Zertifikat 2"); |
365 | 0 | insert_cert(p15card, dirpath(dir,"4332"), 0x49, 1, "SigG Zertifikat 3"); |
366 | |
|
367 | 0 | if(card->type==SC_CARD_TYPE_TCOS_V3){ |
368 | 0 | insert_key(p15card, dirpath(dir,"0000"), 0x49, 0x84, 2048, 5, "SigG Schluessel"); |
369 | 0 | } else { |
370 | 0 | insert_key(p15card, dirpath(dir,"5331"), 0x49, 0x80, 1024, 5, "SigG Schluessel"); |
371 | 0 | } |
372 | |
|
373 | 0 | insert_pin(p15card, dirpath(dir,"5081"), 5, 0, 0x81, 6, "SigG PIN", |
374 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
375 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
376 | 0 | ); |
377 | 0 | if(card->type==SC_CARD_TYPE_TCOS_V3){ |
378 | 0 | insert_pin(p15card, dirpath(dir,"0000"), 6, 0, 0x83, 8, "SigG PIN2", |
379 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
380 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
381 | 0 | ); |
382 | 0 | } |
383 | 0 | } |
384 | |
|
385 | 0 | return 0; |
386 | 0 | } |
387 | | |
388 | | static int detect_idkey( |
389 | | sc_pkcs15_card_t *p15card |
390 | 0 | ){ |
391 | 0 | sc_card_t *card=p15card->card; |
392 | 0 | sc_path_t p; |
393 | | |
394 | | /* TCKEY-Applikation ? */ |
395 | 0 | memset(&p, 0, sizeof(sc_path_t)); |
396 | 0 | p.type=SC_PATH_TYPE_DF_NAME; |
397 | 0 | memcpy(p.value, "\xD2\x76\x00\x00\x03\x0C\x01", p.len=7); |
398 | 0 | if (sc_select_file(card,&p,NULL)!=SC_SUCCESS) return 1; |
399 | | |
400 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "TeleSec GmbH"); |
401 | 0 | set_string(&p15card->tokeninfo->label, "IDKey Card"); |
402 | |
|
403 | 0 | insert_cert(p15card, "DF074331", 0x45, 1, "Signatur Zertifikat 1"); |
404 | 0 | insert_cert(p15card, "DF074332", 0x46, 1, "Signatur Zertifikat 2"); |
405 | 0 | insert_cert(p15card, "DF074333", 0x47, 1, "Signatur Zertifikat 3"); |
406 | 0 | insert_cert(p15card, "DF084331", 0x4B, 1, "Verschluesselungs Zertifikat 1"); |
407 | 0 | insert_cert(p15card, "DF084332", 0x4C, 1, "Verschluesselungs Zertifikat 2"); |
408 | 0 | insert_cert(p15card, "DF084333", 0x4D, 1, "Verschluesselungs Zertifikat 3"); |
409 | | /* TODO should others come here too? */ |
410 | |
|
411 | 0 | insert_key(p15card, "DF074E03", 0x45, 0x84, 2048, 1, "IDKey1"); |
412 | 0 | insert_key(p15card, "DF074E04", 0x46, 0x85, 2048, 1, "IDKey2"); |
413 | 0 | insert_key(p15card, "DF074E05", 0x47, 0x86, 2048, 1, "IDKey3"); |
414 | 0 | insert_key(p15card, "DF074E06", 0x48, 0x87, 2048, 1, "IDKey4"); |
415 | 0 | insert_key(p15card, "DF074E07", 0x49, 0x88, 2048, 1, "IDKey5"); |
416 | 0 | insert_key(p15card, "DF074E08", 0x4A, 0x89, 2048, 1, "IDKey6"); |
417 | 0 | insert_key(p15card, "DF084E01", 0x4B, 0x81, 2048, 1, "IDKey7"); |
418 | 0 | insert_key(p15card, "DF084E02", 0x4C, 0x82, 2048, 1, "IDKey8"); |
419 | 0 | insert_key(p15card, "DF084E03", 0x4D, 0x83, 2048, 1, "IDKey9"); |
420 | |
|
421 | 0 | insert_pin(p15card, "5000", 1, 2, 0x00, 6, "PIN", |
422 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED |
423 | 0 | ); |
424 | 0 | insert_pin(p15card, "5001", 2, 0, 0x01, 8, "PUK", |
425 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | |
426 | 0 | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN |
427 | 0 | ); |
428 | |
|
429 | 0 | return 0; |
430 | 0 | } |
431 | | |
432 | | static int detect_signtrust( |
433 | | sc_pkcs15_card_t *p15card |
434 | 0 | ){ |
435 | 0 | if(insert_cert(p15card,"8000DF01C000", 0x45, 1, "Signatur Zertifikat")) return 1; |
436 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "Deutsche Post"); |
437 | 0 | set_string(&p15card->tokeninfo->label, "SignTrust Card"); |
438 | |
|
439 | 0 | insert_cert(p15card,"800082008220", 0x46, 1, "Verschluesselungs Zertifikat"); |
440 | 0 | insert_cert(p15card,"800083008320", 0x47, 1, "Authentifizierungs Zertifikat"); |
441 | |
|
442 | 0 | insert_key(p15card,"8000DF015331", 0x45, 0x80, 1024, 1, "Signatur Schluessel"); |
443 | 0 | insert_key(p15card,"800082008210", 0x46, 0x80, 1024, 2, "Verschluesselungs Schluessel"); |
444 | 0 | insert_key(p15card,"800083008310", 0x47, 0x80, 1024, 3, "Authentifizierungs Schluessel"); |
445 | |
|
446 | 0 | insert_pin(p15card,"8000DF010000", 1, 0, 0x81, 6, "Signatur PIN", |
447 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
448 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
449 | 0 | ); |
450 | 0 | insert_pin(p15card,"800082000040", 2, 0, 0x81, 6, "Verschluesselungs PIN", |
451 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
452 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
453 | 0 | ); |
454 | 0 | insert_pin(p15card,"800083000040", 3, 0, 0x81, 6, "Authentifizierungs PIN", |
455 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | |
456 | 0 | SC_PKCS15_PIN_FLAG_INITIALIZED |
457 | 0 | ); |
458 | |
|
459 | 0 | return 0; |
460 | 0 | } |
461 | | |
462 | | static int detect_datev( |
463 | | sc_pkcs15_card_t *p15card |
464 | 0 | ){ |
465 | 0 | if(insert_cert(p15card,"3000C500", 0x45, 0, "Signatur Zertifikat")) return 1; |
466 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "DATEV"); |
467 | 0 | set_string(&p15card->tokeninfo->label, "DATEV Classic"); |
468 | |
|
469 | 0 | insert_cert(p15card,"DF02C200", 0x46, 0, "Verschluesselungs Zertifikat"); |
470 | 0 | insert_cert(p15card,"DF02C500", 0x47, 0, "Authentifizierungs Zertifikat"); |
471 | |
|
472 | 0 | insert_key(p15card,"30005371", 0x45, 0x82, 1024, 1, "Signatur Schluessel"); |
473 | 0 | insert_key(p15card,"DF0253B1", 0x46, 0x81, 1024, 1, "Verschluesselungs Schluessel"); |
474 | 0 | insert_key(p15card,"DF025371", 0x47, 0x82, 1024, 1, "Authentifizierungs Schluessel"); |
475 | |
|
476 | 0 | insert_pin(p15card,"5001", 1, 0, 0x01, 6, "PIN", |
477 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED |
478 | 0 | ); |
479 | |
|
480 | 0 | return 0; |
481 | 0 | } |
482 | | |
483 | | static int detect_unicard( |
484 | | sc_pkcs15_card_t *p15card |
485 | 0 | ){ |
486 | 0 | if(!insert_cert(p15card,"41004352", 0x45, 1, "Zertifikat 1")){ |
487 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "JLU Giessen"); |
488 | 0 | set_string(&p15card->tokeninfo->label, "JLU Giessen Card"); |
489 | |
|
490 | 0 | insert_cert(p15card,"41004353", 0x46, 1, "Zertifikat 2"); |
491 | 0 | insert_cert(p15card,"41004354", 0x47, 1, "Zertifikat 3"); |
492 | 0 | insert_key(p15card,"41005103", 0x45, 0x83, 1024, 1, "Schluessel 1"); |
493 | 0 | insert_key(p15card,"41005104", 0x46, 0x84, 1024, 1, "Schluessel 2"); |
494 | 0 | insert_key(p15card,"41005105", 0x47, 0x85, 1024, 1, "Schluessel 3"); |
495 | |
|
496 | 0 | } else if(!insert_cert(p15card,"41014352", 0x45, 1, "Zertifikat 1")){ |
497 | 0 | set_string(&p15card->tokeninfo->manufacturer_id, "TU Darmstadt"); |
498 | 0 | set_string(&p15card->tokeninfo->label, "TUD Card"); |
499 | |
|
500 | 0 | insert_cert(p15card,"41014353", 0x46, 1, "Zertifikat 2"); |
501 | 0 | insert_cert(p15card,"41014354", 0x47, 1, "Zertifikat 3"); |
502 | 0 | insert_key(p15card,"41015103", 0x45, 0x83, 1024, 1, "Schluessel 1"); |
503 | 0 | insert_key(p15card,"41015104", 0x46, 0x84, 1024, 1, "Schluessel 2"); |
504 | 0 | insert_key(p15card,"41015105", 0x47, 0x85, 1024, 1, "Schluessel 3"); |
505 | |
|
506 | 0 | } else return 1; |
507 | | |
508 | 0 | insert_pin(p15card,"5000", 1, 2, 0x00, 6, "PIN", |
509 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED |
510 | 0 | ); |
511 | 0 | insert_pin(p15card,"5008", 2, 0, 0x01, 8, "PUK", |
512 | 0 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | |
513 | 0 | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN |
514 | 0 | ); |
515 | |
|
516 | 0 | return 0; |
517 | 0 | } |
518 | | |
519 | | int sc_pkcs15emu_tcos_init_ex( |
520 | | sc_pkcs15_card_t *p15card, |
521 | | struct sc_aid *aid |
522 | 9.44k | ){ |
523 | 9.44k | sc_card_t *card = p15card->card; |
524 | 9.44k | sc_context_t *ctx = p15card->card->ctx; |
525 | 9.44k | sc_serial_number_t serialnr; |
526 | 9.44k | char serial[30]; |
527 | 9.44k | int r; |
528 | | |
529 | | /* check if we have the correct card OS unless SC_PKCS15EMU_FLAGS_NO_CHECK */ |
530 | 9.44k | if (card->type!=SC_CARD_TYPE_TCOS_V2 && card->type!=SC_CARD_TYPE_TCOS_V3) return SC_ERROR_WRONG_CARD; |
531 | | |
532 | | /* get the card serial number */ |
533 | 0 | r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); |
534 | 0 | if (r < 0) { |
535 | 0 | sc_log(ctx, "unable to get ICCSN"); |
536 | 0 | return SC_ERROR_WRONG_CARD; |
537 | 0 | } |
538 | 0 | r = sc_bin_to_hex(serialnr.value, serialnr.len, serial, sizeof(serial), 0); |
539 | 0 | if (r != SC_SUCCESS) { |
540 | 0 | sc_log(ctx, "serial number invalid"); |
541 | 0 | return SC_ERROR_INTERNAL; |
542 | 0 | } |
543 | | |
544 | 0 | serial[19] = '\0'; |
545 | 0 | set_string(&p15card->tokeninfo->serial_number, serial); |
546 | |
|
547 | 0 | if(!detect_netkey(p15card)) return SC_SUCCESS; |
548 | 0 | if(!detect_idkey(p15card)) return SC_SUCCESS; |
549 | 0 | if(!detect_unicard(p15card)) return SC_SUCCESS; |
550 | 0 | if(!detect_signtrust(p15card)) return SC_SUCCESS; |
551 | 0 | if(!detect_datev(p15card)) return SC_SUCCESS; |
552 | | |
553 | 0 | sc_pkcs15_card_clear(p15card); |
554 | 0 | return SC_ERROR_INTERNAL; |
555 | 0 | } |