1 /* app-nks.c - The Telesec NKS card application.
2 * Copyright (C) 2004, 2007, 2008, 2009 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 3 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, see <http://www.gnu.org/licenses/>.
22 - We are now targeting TCOS 3 cards and it may happen that there is
23 a regression towards TCOS 2 cards. Please report.
25 - The TKS3 AUT key is not used. It seems that it is only useful for
26 the internal authentication command and not accessible by other
27 applications. The key itself is in the encryption class but the
28 corresponding certificate has only the digitalSignature
31 - If required, we automagically switch between the NKS application
32 and the SigG application. This avoids to use the DINSIG
33 application which is somewhat limited, has no support for Secure
34 Messaging as required by TCOS 3 and has no way to change the PIN
35 or even set the NullPIN.
37 - We use the prefix NKS-DF01 for TCOS 2 cards and NKS-NKS3 for newer
38 cards. This is because the NKS application has moved to DF02 with
39 TCOS 3 and thus we better use a DF independent tag.
41 - We use only the global PINs for the NKS application.
56 #include "app-common.h"
60 static char const aid_nks
[] = { 0xD2, 0x76, 0x00, 0x00, 0x03, 0x01, 0x02 };
61 static char const aid_sigg
[] = { 0xD2, 0x76, 0x00, 0x00, 0x66, 0x01 };
66 int is_sigg
; /* Valid for SigG application. */
67 int fid
; /* File ID. */
68 int nks_ver
; /* 0 for NKS version 2, 3 for version 3. */
69 int certtype
; /* Type of certificate or 0 if it is not a certificate. */
70 int iskeypair
; /* If true has the FID of the corresponding certificate. */
71 int issignkey
; /* True if file is a key usable for signing. */
72 int isenckey
; /* True if file is a key usable for decryption. */
73 unsigned char kid
; /* Corresponding key references. */
75 { 0, 0x4531, 0, 0, 0xC000, 1, 0, 0x80 }, /* EF_PK.NKS.SIG */
76 { 0, 0xC000, 0, 101 }, /* EF_C.NKS.SIG */
77 { 0, 0x4331, 0, 100 },
78 { 0, 0x4332, 0, 100 },
79 { 0, 0xB000, 0, 110 }, /* EF_PK.RCA.NKS */
80 { 0, 0x45B1, 0, 0, 0xC200, 0, 1, 0x81 }, /* EF_PK.NKS.ENC */
81 { 0, 0xC200, 0, 101 }, /* EF_C.NKS.ENC */
82 { 0, 0x43B1, 0, 100 },
83 { 0, 0x43B2, 0, 100 },
84 /* The authentication key is not used. */
85 /* { 0, 0x4571, 3, 0, 0xC500, 0, 0, 0x82 }, /\* EF_PK.NKS.AUT *\/ */
86 /* { 0, 0xC500, 3, 101 }, /\* EF_C.NKS.AUT *\/ */
87 { 0, 0x45B2, 3, 0, 0xC201, 0, 1, 0x83 }, /* EF_PK.NKS.ENC1024 */
88 { 0, 0xC201, 3, 101 }, /* EF_C.NKS.ENC1024 */
89 { 1, 0x4531, 3, 0, 0xC000, 1, 1, 0x84 }, /* EF_PK.CH.SIG */
90 { 1, 0xC000, 0, 101 }, /* EF_C.CH.SIG */
91 { 1, 0xC008, 3, 101 }, /* EF_C.CA.SIG */
92 { 1, 0xC00E, 3, 111 }, /* EF_C.RCA.SIG */
98 /* Object with application (i.e. NKS) specific data. */
100 int nks_version
; /* NKS version. */
102 int sigg_active
; /* True if switched to the SigG application. */
107 static gpg_error_t
switch_application (app_t app
, int enable_sigg
);
111 /* Release local data. */
113 do_deinit (app_t app
)
115 if (app
&& app
->app_local
)
117 xfree (app
->app_local
);
118 app
->app_local
= NULL
;
123 /* Read the file with FID, assume it contains a public key and return
124 its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */
126 keygripstr_from_pk_file (app_t app
, int fid
, char *r_gripstr
)
129 unsigned char grip
[20];
130 unsigned char *buffer
[2];
134 int offset
[2] = { 0, 0 };
136 err
= iso7816_select_file (app
->slot
, fid
, 0, NULL
, NULL
);
139 err
= iso7816_read_record (app
->slot
, 1, 1, 0, &buffer
[0], &buflen
[0]);
142 err
= iso7816_read_record (app
->slot
, 2, 1, 0, &buffer
[1], &buflen
[1]);
149 if (app
->app_local
->nks_version
< 3)
151 /* Old versions of NKS store the values in a TLV encoded format.
152 We need to do some checks. */
153 for (i
=0; i
< 2; i
++)
155 /* Check that the value appears like an integer encoded as
156 Simple-TLV. We don't check the tag because the tests cards I
157 have use 1 for both, the modulus and the exponent - the
158 example in the documentation gives 2 for the exponent. */
160 err
= gpg_error (GPG_ERR_TOO_SHORT
);
161 else if (buffer
[i
][1] != buflen
[i
]-2 )
162 err
= gpg_error (GPG_ERR_INV_OBJ
);
169 /* Remove leading zeroes to get a correct keygrip. Take care of
170 negative numbers. We should also fix it the same way in
171 libgcrypt but we can't yet rely on it yet. */
172 for (i
=0; i
< 2; i
++)
174 while (buflen
[i
]-offset
[i
] > 1
175 && !buffer
[i
][offset
[i
]]
176 && !(buffer
[i
][offset
[i
]+1] & 0x80))
181 /* Check whether negative values are not prefixed with a zero and
183 for (i
=0; i
< 2; i
++)
185 if ((buflen
[i
]-offset
[i
]) && (buffer
[i
][offset
[i
]] & 0x80))
187 unsigned char *newbuf
;
190 newlen
= 1 + buflen
[i
] - offset
[i
];
191 newbuf
= xtrymalloc (newlen
);
196 return gpg_error_from_syserror ();
199 memcpy (newbuf
+1, buffer
[i
]+offset
[i
], buflen
[i
] - offset
[i
]);
208 err
= gcry_sexp_build (&sexp
, NULL
,
209 "(public-key (rsa (n %b) (e %b)))",
210 (int)buflen
[0]-offset
[0], buffer
[0]+offset
[0],
211 (int)buflen
[1]-offset
[1], buffer
[1]+offset
[1]);
218 if (!gcry_pk_get_keygrip (sexp
, grip
))
220 err
= gpg_error (GPG_ERR_INTERNAL
); /* i.e. RSA not supported by
225 bin2hex (grip
, 20, r_gripstr
);
227 gcry_sexp_release (sexp
);
232 /* TCOS responds to a verify with empty data (i.e. without the Lc
233 byte) with the status of the PIN. PWID is the PIN ID, If SIGG is
234 true, the application is switched into SigG mode.
236 -1 = Error retrieving the data,
240 n >= 0 = Number of verification attempts left. */
242 get_chv_status (app_t app
, int sigg
, int pwid
)
244 unsigned char *result
= NULL
;
249 if (switch_application (app
, sigg
))
250 return sigg
? -2 : -1; /* No such PIN / General error. */
257 if (apdu_send_direct (app
->slot
, 0, command
, 4, 0, &result
, &resultlen
))
258 rc
= -1; /* Error. */
259 else if (resultlen
< 2)
260 rc
= -1; /* Error. */
263 unsigned int sw
= ((result
[resultlen
-2] << 8) | result
[resultlen
-1]);
266 rc
= -2; /* No such PIN. */
267 else if (sw
== 0x6983)
268 rc
= -3; /* PIN is blocked. */
269 else if (sw
== 0x6985)
270 rc
= -4; /* NullPIN is activ. */
271 else if ((sw
& 0xfff0) == 0x63C0)
272 rc
= (sw
& 0x000f); /* PIN has N tries left. */
274 rc
= -1; /* Other error. */
282 /* Implement the GETATTR command. This is similar to the LEARN
283 command but returns just one value via the status interface. */
285 do_getattr (app_t app
, ctrl_t ctrl
, const char *name
)
292 { "NKS-VERSION", 2 },
300 err
= switch_application (app
, 0);
304 for (idx
=0; table
[idx
].name
&& strcmp (table
[idx
].name
, name
); idx
++)
306 if (!table
[idx
].name
)
307 return gpg_error (GPG_ERR_INV_NAME
);
309 switch (table
[idx
].special
)
311 case 1: /* $AUTHKEYID */
313 /* NetKey 3.0 cards define an authentication key but according
314 to the specs this key is only usable for encryption and not
315 signing. it might work anyway but it has not yet been
316 tested - fixme. Thus for now we use the NKS signature key
317 for authentication. */
318 char const tmp
[] = "NKS-NKS3.4531";
319 send_status_info (ctrl
, table
[idx
].name
, tmp
, strlen (tmp
), NULL
, 0);
323 case 2: /* NKS-VERSION */
324 snprintf (buffer
, sizeof buffer
, "%d", app
->app_local
->nks_version
);
325 send_status_info (ctrl
, table
[idx
].name
,
326 buffer
, strlen (buffer
), NULL
, 0);
329 case 3: /* CHV-STATUS */
331 /* Returns: PW1.CH PW2.CH PW1.CH.SIG PW2.CH.SIG That are the
332 two global passwords followed by the two SigG passwords.
333 For the values, see the function get_chv_status. */
336 /* We use a helper array so that we can control that there is
337 no superfluous application switch. Note that PW2.CH.SIG
338 really has the identifier 0x83 and not 0x82 as one would
340 tmp
[0] = get_chv_status (app
, 0, 0x00);
341 tmp
[1] = get_chv_status (app
, 0, 0x01);
342 tmp
[2] = get_chv_status (app
, 1, 0x81);
343 tmp
[3] = get_chv_status (app
, 1, 0x83);
344 snprintf (buffer
, sizeof buffer
,
345 "%d %d %d %d", tmp
[0], tmp
[1], tmp
[2], tmp
[3]);
346 send_status_info (ctrl
, table
[idx
].name
,
347 buffer
, strlen (buffer
), NULL
, 0);
353 err
= gpg_error (GPG_ERR_NOT_IMPLEMENTED
);
363 do_learn_status_core (app_t app
, ctrl_t ctrl
, unsigned int flags
, int is_sigg
)
366 char ct_buf
[100], id_buf
[100];
372 else if (app
->app_local
->nks_version
< 3)
377 /* Output information about all useful objects in the NKS application. */
378 for (i
=0; filelist
[i
].fid
; i
++)
380 if (filelist
[i
].nks_ver
> app
->app_local
->nks_version
)
383 if (!!filelist
[i
].is_sigg
!= !!is_sigg
)
386 if (filelist
[i
].certtype
&& !(flags
&1))
390 len
= app_help_read_length_of_cert (app
->slot
,
391 filelist
[i
].fid
, NULL
);
394 /* FIXME: We should store the length in the application's
395 context so that a following readcert does only need to
396 read that many bytes. */
397 snprintf (ct_buf
, sizeof ct_buf
, "%d", filelist
[i
].certtype
);
398 snprintf (id_buf
, sizeof id_buf
, "NKS-%s.%04X",
399 tag
, filelist
[i
].fid
);
400 send_status_info (ctrl
, "CERTINFO",
401 ct_buf
, strlen (ct_buf
),
402 id_buf
, strlen (id_buf
),
406 else if (filelist
[i
].iskeypair
)
410 err
= keygripstr_from_pk_file (app
, filelist
[i
].fid
, gripstr
);
412 log_error ("can't get keygrip from FID 0x%04X: %s\n",
413 filelist
[i
].fid
, gpg_strerror (err
));
416 snprintf (id_buf
, sizeof id_buf
, "NKS-%s.%04X",
417 tag
, filelist
[i
].fid
);
418 send_status_info (ctrl
, "KEYPAIRINFO",
420 id_buf
, strlen (id_buf
),
431 do_learn_status (app_t app
, ctrl_t ctrl
, unsigned int flags
)
435 err
= switch_application (app
, 0);
439 do_learn_status_core (app
, ctrl
, flags
, 0);
441 err
= switch_application (app
, 1);
443 return 0; /* Silently ignore if we can't switch to SigG. */
445 do_learn_status_core (app
, ctrl
, flags
, 1);
453 /* Read the certificate with id CERTID (as returned by learn_status in
454 the CERTINFO status lines) and return it in the freshly allocated
455 buffer put into CERT and the length of the certificate put into
458 do_readcert (app_t app
, const char *certid
,
459 unsigned char **cert
, size_t *certlen
)
463 unsigned char *buffer
;
464 const unsigned char *p
;
466 int class, tag
, constructed
, ndef
;
467 size_t totobjlen
, objlen
, hdrlen
;
474 if (!strncmp (certid
, "NKS-NKS3.", 9))
476 else if (!strncmp (certid
, "NKS-DF01.", 9))
478 else if (!strncmp (certid
, "NKS-SIGG.", 9))
481 return gpg_error (GPG_ERR_INV_ID
);
483 err
= switch_application (app
, is_sigg
);
488 if (!hexdigitp (certid
) || !hexdigitp (certid
+1)
489 || !hexdigitp (certid
+2) || !hexdigitp (certid
+3)
491 return gpg_error (GPG_ERR_INV_ID
);
492 fid
= xtoi_4 (certid
);
493 for (i
=0; filelist
[i
].fid
; i
++)
494 if ((filelist
[i
].certtype
|| filelist
[i
].iskeypair
)
495 && filelist
[i
].fid
== fid
)
497 if (!filelist
[i
].fid
)
498 return gpg_error (GPG_ERR_NOT_FOUND
);
500 /* If the requested objects is a plain public key, redirect it to
501 the corresponding certificate. The whole system is a bit messy
502 because we sometime use the key directly or let the caller
503 retrieve the key from the certificate. The rationale for
504 that is to support not-yet stored certificates. */
505 if (filelist
[i
].iskeypair
)
506 fid
= filelist
[i
].iskeypair
;
509 /* Read the entire file. fixme: This could be optimized by first
510 reading the header to figure out how long the certificate
512 err
= iso7816_select_file (app
->slot
, fid
, 0, NULL
, NULL
);
515 log_error ("error selecting FID 0x%04X: %s\n", fid
, gpg_strerror (err
));
519 err
= iso7816_read_binary (app
->slot
, 0, 0, &buffer
, &buflen
);
522 log_error ("error reading certificate from FID 0x%04X: %s\n",
523 fid
, gpg_strerror (err
));
527 if (!buflen
|| *buffer
== 0xff)
529 log_info ("no certificate contained in FID 0x%04X\n", fid
);
530 err
= gpg_error (GPG_ERR_NOT_FOUND
);
534 /* Now figure something out about the object. */
537 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
538 &ndef
, &objlen
, &hdrlen
);
541 if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
)
543 else if ( class == CLASS_UNIVERSAL
&& tag
== TAG_SET
&& constructed
)
546 return gpg_error (GPG_ERR_INV_OBJ
);
547 totobjlen
= objlen
+ hdrlen
;
548 assert (totobjlen
<= buflen
);
550 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
551 &ndef
, &objlen
, &hdrlen
);
557 else if (class == CLASS_UNIVERSAL
&& tag
== TAG_OBJECT_ID
&& !constructed
)
559 const unsigned char *save_p
;
561 /* The certificate seems to be contained in a userCertificate
562 container. Skip this and assume the following sequence is
566 err
= gpg_error (GPG_ERR_INV_OBJ
);
572 err
= parse_ber_header (&p
, &n
, &class, &tag
, &constructed
,
573 &ndef
, &objlen
, &hdrlen
);
576 if ( !(class == CLASS_UNIVERSAL
&& tag
== TAG_SEQUENCE
&& constructed
) )
577 return gpg_error (GPG_ERR_INV_OBJ
);
578 totobjlen
= objlen
+ hdrlen
;
579 assert (save_p
+ totobjlen
<= buffer
+ buflen
);
580 memmove (buffer
, save_p
, totobjlen
);
585 *certlen
= totobjlen
;
594 basic_pin_checks (const char *pinvalue
, int minlen
, int maxlen
)
596 if (strlen (pinvalue
) < minlen
)
598 log_error ("PIN is too short; minimum length is %d\n", minlen
);
599 return gpg_error (GPG_ERR_BAD_PIN
);
601 if (strlen (pinvalue
) > maxlen
)
603 log_error ("PIN is too large; maximum length is %d\n", maxlen
);
604 return gpg_error (GPG_ERR_BAD_PIN
);
610 /* Verify the PIN if required. */
612 verify_pin (app_t app
, int pwid
, const char *desc
,
613 gpg_error_t (*pincb
)(void*, const char *, char **),
616 iso7816_pininfo_t pininfo
;
622 memset (&pininfo
, 0, sizeof pininfo
);
627 if (!opt
.disable_keypad
628 && !iso7816_check_keypad (app
->slot
, ISO7816_VERIFY
, &pininfo
) )
630 rc
= pincb (pincb_arg
, desc
, NULL
);
633 log_info (_("PIN callback returned error: %s\n"),
638 rc
= iso7816_verify_kp (app
->slot
, pwid
, "", 0, &pininfo
);
639 pincb (pincb_arg
, NULL
, NULL
); /* Dismiss the prompt. */
645 rc
= pincb (pincb_arg
, desc
, &pinvalue
);
648 log_info ("PIN callback returned error: %s\n", gpg_strerror (rc
));
652 rc
= basic_pin_checks (pinvalue
, pininfo
.minlen
, pininfo
.maxlen
);
659 rc
= iso7816_verify (app
->slot
, pwid
, pinvalue
, strlen (pinvalue
));
665 if ( gpg_err_code (rc
) == GPG_ERR_USE_CONDITIONS
)
666 log_error (_("the NullPIN has not yet been changed\n"));
668 log_error ("verify PIN failed\n");
677 /* Create the signature and return the allocated result in OUTDATA.
678 If a PIN is required the PINCB will be used to ask for the PIN;
679 that callback should return the PIN in an allocated buffer and
680 store that in the 3rd argument. */
682 do_sign (app_t app
, const char *keyidstr
, int hashalgo
,
683 gpg_error_t (*pincb
)(void*, const char *, char **),
685 const void *indata
, size_t indatalen
,
686 unsigned char **outdata
, size_t *outdatalen
)
688 static unsigned char sha1_prefix
[15] = /* Object ID is 1.3.14.3.2.26 */
689 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
690 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
691 static unsigned char rmd160_prefix
[15] = /* Object ID is 1.3.36.3.2.1 */
692 { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
693 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
698 unsigned char data
[83]; /* Must be large enough for a SHA-1 digest
699 + the largest OID prefix. */
702 if (!keyidstr
|| !*keyidstr
)
703 return gpg_error (GPG_ERR_INV_VALUE
);
706 case 16: case 20: case 35: case 47: case 51: case 67: case 83: break;
707 default: return gpg_error (GPG_ERR_INV_VALUE
);
710 /* Check that the provided ID is valid. This is not really needed
711 but we do it to enforce correct usage by the caller. */
712 if (!strncmp (keyidstr
, "NKS-NKS3.", 9) )
714 else if (!strncmp (keyidstr
, "NKS-DF01.", 9) )
716 else if (!strncmp (keyidstr
, "NKS-SIGG.", 9) )
719 return gpg_error (GPG_ERR_INV_ID
);
722 rc
= switch_application (app
, is_sigg
);
726 if (!hexdigitp (keyidstr
) || !hexdigitp (keyidstr
+1)
727 || !hexdigitp (keyidstr
+2) || !hexdigitp (keyidstr
+3)
729 return gpg_error (GPG_ERR_INV_ID
);
730 fid
= xtoi_4 (keyidstr
);
731 for (i
=0; filelist
[i
].fid
; i
++)
732 if (filelist
[i
].iskeypair
&& filelist
[i
].fid
== fid
)
734 if (!filelist
[i
].fid
)
735 return gpg_error (GPG_ERR_NOT_FOUND
);
736 if (!filelist
[i
].issignkey
)
737 return gpg_error (GPG_ERR_INV_ID
);
738 kid
= filelist
[i
].kid
;
740 /* Prepare the DER object from INDATA. */
741 if (app
->app_local
->nks_version
> 2 && (indatalen
== 35
747 /* The caller send data matching the length of the ASN.1 encoded
748 hash for SHA-{1,224,256,384,512}. Assume that is okay. */
749 assert (indatalen
<= sizeof data
);
750 memcpy (data
, indata
, indatalen
);
753 else if (indatalen
== 35)
755 /* Alright, the caller was so kind to send us an already
756 prepared DER object. This is for TCOS 2. */
757 if (hashalgo
== GCRY_MD_SHA1
&& !memcmp (indata
, sha1_prefix
, 15))
759 else if (hashalgo
== GCRY_MD_RMD160
&& !memcmp (indata
,rmd160_prefix
,15))
762 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
763 memcpy (data
, indata
, indatalen
);
766 else if (indatalen
== 20)
768 if (hashalgo
== GCRY_MD_SHA1
)
769 memcpy (data
, sha1_prefix
, 15);
770 else if (hashalgo
== GCRY_MD_RMD160
)
771 memcpy (data
, rmd160_prefix
, 15);
773 return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM
);
774 memcpy (data
+15, indata
, indatalen
);
778 return gpg_error (GPG_ERR_INV_VALUE
);
781 /* Send an MSE for PSO:Computer_Signature. */
782 if (app
->app_local
->nks_version
> 2)
784 unsigned char mse
[6];
786 mse
[0] = 0x80; /* Algorithm reference. */
788 mse
[2] = 2; /* RSA, card does pkcs#1 v1.5 padding, no ASN.1 check. */
789 mse
[3] = 0x84; /* Private key reference. */
792 rc
= iso7816_manage_security_env (app
->slot
, 0x41, 0xB6,
795 /* Verify using PW1.CH. */
797 rc
= verify_pin (app
, 0, NULL
, pincb
, pincb_arg
);
798 /* Compute the signature. */
800 rc
= iso7816_compute_ds (app
->slot
, data
, datalen
, outdata
, outdatalen
);
806 /* Decrypt the data in INDATA and return the allocated result in OUTDATA.
807 If a PIN is required the PINCB will be used to ask for the PIN; it
808 should return the PIN in an allocated buffer and put it into PIN. */
810 do_decipher (app_t app
, const char *keyidstr
,
811 gpg_error_t (*pincb
)(void*, const char *, char **),
813 const void *indata
, size_t indatalen
,
814 unsigned char **outdata
, size_t *outdatalen
)
821 if (!keyidstr
|| !*keyidstr
|| !indatalen
)
822 return gpg_error (GPG_ERR_INV_VALUE
);
824 /* Check that the provided ID is valid. This is not really needed
825 but we do it to to enforce correct usage by the caller. */
826 if (!strncmp (keyidstr
, "NKS-NKS3.", 9) )
828 else if (!strncmp (keyidstr
, "NKS-DF01.", 9) )
830 else if (!strncmp (keyidstr
, "NKS-SIGG.", 9) )
833 return gpg_error (GPG_ERR_INV_ID
);
836 rc
= switch_application (app
, is_sigg
);
840 if (!hexdigitp (keyidstr
) || !hexdigitp (keyidstr
+1)
841 || !hexdigitp (keyidstr
+2) || !hexdigitp (keyidstr
+3)
843 return gpg_error (GPG_ERR_INV_ID
);
844 fid
= xtoi_4 (keyidstr
);
845 for (i
=0; filelist
[i
].fid
; i
++)
846 if (filelist
[i
].iskeypair
&& filelist
[i
].fid
== fid
)
848 if (!filelist
[i
].fid
)
849 return gpg_error (GPG_ERR_NOT_FOUND
);
850 if (!filelist
[i
].isenckey
)
851 return gpg_error (GPG_ERR_INV_ID
);
852 kid
= filelist
[i
].kid
;
854 if (app
->app_local
->nks_version
> 2)
856 unsigned char mse
[6];
857 mse
[0] = 0x80; /* Algorithm reference. */
859 mse
[2] = 0x0a; /* RSA no padding. (0x1A is pkcs#1.5 padding.) */
860 mse
[3] = 0x84; /* Private key reference. */
863 rc
= iso7816_manage_security_env (app
->slot
, 0x41, 0xB8,
868 static const unsigned char mse
[] =
870 0x80, 1, 0x10, /* Select algorithm RSA. */
871 0x84, 1, 0x81 /* Select local secret key 1 for decryption. */
873 rc
= iso7816_manage_security_env (app
->slot
, 0xC1, 0xB8,
879 rc
= verify_pin (app
, 0, NULL
, pincb
, pincb_arg
);
881 /* Note that we need to use extended length APDUs for TCOS 3 cards.
882 Command chaining does not work. */
884 rc
= iso7816_decipher (app
->slot
, app
->app_local
->nks_version
> 2? 1:0,
885 indata
, indatalen
, 0x81,
886 outdata
, outdatalen
);
892 /* Parse a password ID string. Returns NULL on error or a string
893 suitable as passpahrse prompt on success. On success stores the
894 reference value for the password at R_PWID and a flag indicating
895 that the SigG application is to be used at R_SIGG. If NEW_MODE is
896 true, the returned description is suitable for a new Password.
897 Supported values for PWIDSTR are:
899 PW1.CH - Global password 1
900 PW2.CH - Global password 2
901 PW1.CH.SIG - SigG password 1
902 PW2.CH.SIG - SigG password 2
905 parse_pwidstr (const char *pwidstr
, int new_mode
, int *r_sigg
, int *r_pwid
)
911 else if (!strcmp (pwidstr
, "PW1.CH"))
915 /* TRANSLATORS: Do not translate the "|*|" prefixes but keep
916 them verbatim at the start of the string. */
918 ? _("|N|Please enter a new PIN for the standard keys.")
919 : _("||Please enter the PIN for the standard keys."));
921 else if (!strcmp (pwidstr
, "PW2.CH"))
925 ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
926 "for the standard keys.")
927 : _("|P|Please enter the PIN Unblocking Code (PUK) "
928 "for the standard keys."));
930 else if (!strcmp (pwidstr
, "PW1.CH.SIG"))
935 ? _("|N|Please enter a new PIN for the key to create "
936 "qualified signatures.")
937 : _("||Please enter the PIN for the key to create "
938 "qualified signatures."));
940 else if (!strcmp (pwidstr
, "PW2.CH.SIG"))
942 *r_pwid
= 0x83; /* Yes, that is 83 and not 82. */
945 ? _("|NP|Please enter a new PIN Unblocking Code (PUK) "
946 "for the key to create qualified signatures.")
947 : _("|P|Please enter the PIN Unblocking Code (PUK) "
948 "for the key to create qualified signatures."));
957 /* Handle the PASSWD command. See parse_pwidstr() for allowed values
960 do_change_pin (app_t app
, ctrl_t ctrl
, const char *pwidstr
,
962 gpg_error_t (*pincb
)(void*, const char *, char **),
973 iso7816_pininfo_t pininfo
;
977 /* The minimum length is enforced by TCOS, the maximum length is
978 just a reasonable value. */
979 memset (&pininfo
, 0, sizeof pininfo
);
983 newdesc
= parse_pwidstr (pwidstr
, 1, &is_sigg
, &pwid
);
985 return gpg_error (GPG_ERR_INV_ID
);
987 err
= switch_application (app
, is_sigg
);
991 if ((flags
& APP_CHANGE_FLAG_NULLPIN
))
993 /* With the nullpin flag, we do not verify the PIN - it would
994 fail if the Nullpin is still set. */
995 oldpin
= xtrycalloc (1, 6);
998 err
= gpg_error_from_syserror ();
1008 if ((flags
& APP_CHANGE_FLAG_RESET
))
1010 /* Reset mode: Ask for the alternate PIN. */
1011 const char *altpwidstr
;
1013 if (!strcmp (pwidstr
, "PW1.CH"))
1014 altpwidstr
= "PW2.CH";
1015 else if (!strcmp (pwidstr
, "PW2.CH"))
1016 altpwidstr
= "PW1.CH";
1017 else if (!strcmp (pwidstr
, "PW1.CH.SIG"))
1018 altpwidstr
= "PW2.CH.SIG";
1019 else if (!strcmp (pwidstr
, "PW2.CH.SIG"))
1020 altpwidstr
= "PW1.CH.SIG";
1023 err
= gpg_error (GPG_ERR_BUG
);
1026 desc
= parse_pwidstr (altpwidstr
, 0, &dummy1
, &dummy2
);
1030 /* Regular change mode: Ask for the old PIN. */
1031 desc
= parse_pwidstr (pwidstr
, 0, &dummy1
, &dummy2
);
1033 err
= pincb (pincb_arg
, desc
, &oldpin
);
1036 log_error ("error getting old PIN: %s\n", gpg_strerror (err
));
1039 oldpinlen
= strlen (oldpin
);
1040 err
= basic_pin_checks (oldpin
, pininfo
.minlen
, pininfo
.maxlen
);
1045 err
= pincb (pincb_arg
, newdesc
, &newpin
);
1048 log_error (_("error getting new PIN: %s\n"), gpg_strerror (err
));
1051 newpinlen
= strlen (newpin
);
1053 err
= basic_pin_checks (newpin
, pininfo
.minlen
, pininfo
.maxlen
);
1057 if ((flags
& APP_CHANGE_FLAG_RESET
))
1060 size_t datalen
= oldpinlen
+ newpinlen
;
1062 data
= xtrymalloc (datalen
);
1065 err
= gpg_error_from_syserror ();
1068 memcpy (data
, oldpin
, oldpinlen
);
1069 memcpy (data
+oldpinlen
, newpin
, newpinlen
);
1070 err
= iso7816_reset_retry_counter_with_rc (app
->slot
, pwid
,
1072 wipememory (data
, datalen
);
1076 err
= iso7816_change_reference_data (app
->slot
, pwid
,
1086 /* Perform a simple verify operation. KEYIDSTR should be NULL or empty. */
1088 do_check_pin (app_t app
, const char *pwidstr
,
1089 gpg_error_t (*pincb
)(void*, const char *, char **),
1097 desc
= parse_pwidstr (pwidstr
, 0, &is_sigg
, &pwid
);
1099 return gpg_error (GPG_ERR_INV_ID
);
1101 err
= switch_application (app
, is_sigg
);
1105 return verify_pin (app
, pwid
, desc
, pincb
, pincb_arg
);
1109 /* Return the version of the NKS application. */
1111 get_nks_version (int slot
)
1113 unsigned char *result
= NULL
;
1117 if (iso7816_apdu_direct (slot
, "\x80\xaa\x06\x00\x00", 5, 0,
1118 &result
, &resultlen
))
1119 return 2; /* NKS 2 does not support this command. */
1121 /* Example value: 04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00
1122 vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx
1123 vendor (Philips) -+ | | | | | | |
1124 chip type -----------+ | | | | | |
1125 chip id ----------------+ | | | | |
1126 card type (3 - tcos 3) -------------------+ | | | |
1127 OS version of card type ---------------------+ | | |
1128 OS release of card type ------------------------+ | |
1129 OS vendor internal version ------------------------+ |
1130 RFU -----------------------------------------------------------+
1133 type
= 0; /* Invalid data returned. */
1142 /* If ENABLE_SIGG is true switch to the SigG application if not yet
1143 active. If false switch to the NKS application if not yet active.
1144 Returns 0 on success. */
1146 switch_application (app_t app
, int enable_sigg
)
1150 if ((app
->app_local
->sigg_active
&& enable_sigg
)
1151 || (!app
->app_local
->sigg_active
&& !enable_sigg
) )
1152 return 0; /* Already switched. */
1154 log_info ("app-nks: switching to %s\n", enable_sigg
? "SigG":"NKS");
1156 err
= iso7816_select_application (app
->slot
, aid_sigg
, sizeof aid_sigg
, 0);
1158 err
= iso7816_select_application (app
->slot
, aid_nks
, sizeof aid_nks
, 0);
1161 app
->app_local
->sigg_active
= enable_sigg
;
1163 log_error ("app-nks: error switching to %s: %s\n",
1164 enable_sigg
? "SigG":"NKS", gpg_strerror (err
));
1170 /* Select the NKS application. */
1172 app_select_nks (app_t app
)
1174 int slot
= app
->slot
;
1177 rc
= iso7816_select_application (slot
, aid_nks
, sizeof aid_nks
, 0);
1180 app
->apptype
= "NKS";
1182 app
->app_local
= xtrycalloc (1, sizeof *app
->app_local
);
1183 if (!app
->app_local
)
1185 rc
= gpg_error (gpg_err_code_from_errno (errno
));
1189 app
->app_local
->nks_version
= get_nks_version (slot
);
1191 log_info ("Detected NKS version: %d\n", app
->app_local
->nks_version
);
1193 app
->fnc
.deinit
= do_deinit
;
1194 app
->fnc
.learn_status
= do_learn_status
;
1195 app
->fnc
.readcert
= do_readcert
;
1196 app
->fnc
.getattr
= do_getattr
;
1197 app
->fnc
.setattr
= NULL
;
1198 app
->fnc
.genkey
= NULL
;
1199 app
->fnc
.sign
= do_sign
;
1200 app
->fnc
.auth
= NULL
;
1201 app
->fnc
.decipher
= do_decipher
;
1202 app
->fnc
.change_pin
= do_change_pin
;
1203 app
->fnc
.check_pin
= do_check_pin
;