Implement "INTERNAL AUTHENTICATE" command.
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -10,6 +10,7 @@ NIIBE Yutaka:
|
|||||||
Founder of the project.
|
Founder of the project.
|
||||||
Wrote:
|
Wrote:
|
||||||
gnuk.svg
|
gnuk.svg
|
||||||
|
src/configure
|
||||||
src/ac.c
|
src/ac.c
|
||||||
src/main.c
|
src/main.c
|
||||||
src/usb_lld.h
|
src/usb_lld.h
|
||||||
|
|||||||
23
ChangeLog
23
ChangeLog
@@ -1,3 +1,26 @@
|
|||||||
|
2010-10-16 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
Implement "INTERNAL AUTHENTICATE" command.
|
||||||
|
|
||||||
|
* src/gnuk.h (BY_USER, BY_RESETCODE, BY_ADMIN): New defines.
|
||||||
|
(NUM_ALL_PRV_KEYS): Now it's 3 (was: 2).
|
||||||
|
|
||||||
|
* src/openpgp.c (INS_INTERNAL_AUTHENTICATE): New define.
|
||||||
|
(cmd_internal_authenticate): New function.
|
||||||
|
(cmds): Added INS_INTERNAL_AUTHENTICATE.
|
||||||
|
(cmd_change_password): Use BY_USER.
|
||||||
|
(cmd_reset_user_password): Use BY_USER, BY_RESETCODE, BY_ADMIN.
|
||||||
|
(cmd_pso): Load GPG_KEY_FOR_DECRYPTION here.
|
||||||
|
(cmd_pso): Removed adding status word into res_APDU...
|
||||||
|
* src/call-rsa.c (rsa_sign): and moved adding status word into
|
||||||
|
res_APDU here.
|
||||||
|
|
||||||
|
* src/ac.c (pw1_keystring): New variable.
|
||||||
|
(ac_reset_pso_other): Clear pw1_keystring.
|
||||||
|
(verify_pso_cds): Use BY_USER.
|
||||||
|
(verify_pso_other): Just check the length of password here, and
|
||||||
|
defer real check to cmd_pso or cmd_internal_authenticate.
|
||||||
|
|
||||||
2010-10-14 NIIBE Yutaka <gniibe@fsij.org>
|
2010-10-14 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
Adding 'configure' support.
|
Adding 'configure' support.
|
||||||
|
|||||||
44
src/ac.c
44
src/ac.c
@@ -28,9 +28,12 @@ ac_reset_pso_cds (void)
|
|||||||
auth_status &= ~AC_PSO_CDS_AUTHORIZED;
|
auth_status &= ~AC_PSO_CDS_AUTHORIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t pw1_keystring[KEYSTRING_SIZE_PW1];
|
||||||
|
|
||||||
void
|
void
|
||||||
ac_reset_pso_other (void)
|
ac_reset_pso_other (void)
|
||||||
{
|
{
|
||||||
|
memset (pw1_keystring, 0, KEYSTRING_SIZE_PW1);
|
||||||
auth_status &= ~AC_PSO_OTHER_AUTHORIZED;
|
auth_status &= ~AC_PSO_OTHER_AUTHORIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
|
|||||||
keystring[0] = pw_len;
|
keystring[0] = pw_len;
|
||||||
sha1 (pw, pw_len, keystring+1);
|
sha1 (pw, pw_len, keystring+1);
|
||||||
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
||||||
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, 1, keystring+1)) < 0)
|
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring+1)) < 0)
|
||||||
{
|
{
|
||||||
pwsb[PW_STATUS_PW1]--;
|
pwsb[PW_STATUS_PW1]--;
|
||||||
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
@@ -71,34 +74,41 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
|
|||||||
int
|
int
|
||||||
verify_pso_other (const uint8_t *pw, int pw_len)
|
verify_pso_other (const uint8_t *pw, int pw_len)
|
||||||
{
|
{
|
||||||
int r;
|
|
||||||
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
||||||
uint8_t keystring[KEYSTRING_SIZE_PW1];
|
|
||||||
uint8_t pwsb[SIZE_PW_STATUS_BYTES];
|
uint8_t pwsb[SIZE_PW_STATUS_BYTES];
|
||||||
|
const uint8_t *ks_pw1;
|
||||||
|
|
||||||
|
DEBUG_INFO ("verify_pso_other\r\n");
|
||||||
|
|
||||||
if (pw_status_bytes == NULL
|
if (pw_status_bytes == NULL
|
||||||
|| pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */
|
|| pw_status_bytes[PW_STATUS_PW1] == 0) /* locked */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
DEBUG_INFO ("verify_pso_other\r\n");
|
|
||||||
|
|
||||||
keystring[0] = pw_len;
|
|
||||||
sha1 (pw, pw_len, keystring+1);
|
|
||||||
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
||||||
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, 1, keystring+1)) < 0)
|
|
||||||
|
/*
|
||||||
|
* We check only the length of password string now.
|
||||||
|
* Real check is defered to decrypt/authenticate routines.
|
||||||
|
*/
|
||||||
|
ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||||
|
if ((ks_pw1 == NULL && pw_len == strlen (OPENPGP_CARD_INITIAL_PW1))
|
||||||
|
|| (ks_pw1 != NULL && pw_len == ks_pw1[0]))
|
||||||
|
{ /* No problem */
|
||||||
|
/*
|
||||||
|
* We don't reset pwsb[PW_STATUS_PW1] here.
|
||||||
|
* Because password may be wrong.
|
||||||
|
*/
|
||||||
|
pw1_keystring[0] = pw_len;
|
||||||
|
sha1 (pw, pw_len, pw1_keystring+1);
|
||||||
|
auth_status |= AC_PSO_OTHER_AUTHORIZED;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
pwsb[PW_STATUS_PW1]--;
|
pwsb[PW_STATUS_PW1]--;
|
||||||
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
return r;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (pwsb[PW_STATUS_PW1] != 3)
|
|
||||||
{
|
|
||||||
pwsb[PW_STATUS_PW1] = 3;
|
|
||||||
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
auth_status |= AC_PSO_OTHER_AUTHORIZED;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include "polarssl/config.h"
|
#include "polarssl/config.h"
|
||||||
#include "polarssl/rsa.h"
|
#include "polarssl/rsa.h"
|
||||||
|
|
||||||
|
#define RSA_SIGNATURE_LENGTH 256 /* 256 byte == 2048-bit */
|
||||||
|
|
||||||
static rsa_context rsa_ctx;
|
static rsa_context rsa_ctx;
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -76,6 +78,9 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
res_APDU[RSA_SIGNATURE_LENGTH] = 0x90;
|
||||||
|
res_APDU[RSA_SIGNATURE_LENGTH+1] = 0x00;
|
||||||
|
res_APDU_size = RSA_SIGNATURE_LENGTH + 2;
|
||||||
DEBUG_INFO ("done.\r\n");
|
DEBUG_INFO ("done.\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -165,7 +170,6 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len)
|
|||||||
res_APDU[output_len] = 0x90;
|
res_APDU[output_len] = 0x90;
|
||||||
res_APDU[output_len+1] = 0x00;
|
res_APDU[output_len+1] = 0x00;
|
||||||
res_APDU_size = output_len + 2;
|
res_APDU_size = output_len + 2;
|
||||||
|
|
||||||
DEBUG_INFO ("done.\r\n");
|
DEBUG_INFO ("done.\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
21
src/gnuk.h
21
src/gnuk.h
@@ -104,12 +104,23 @@ struct key_data {
|
|||||||
#define DATA_ENCRYPTION_KEY_SIZE 16
|
#define DATA_ENCRYPTION_KEY_SIZE 16
|
||||||
struct prvkey_data {
|
struct prvkey_data {
|
||||||
const uint8_t *key_addr;
|
const uint8_t *key_addr;
|
||||||
|
/*
|
||||||
|
* CRM: [C]heck, [R]andom, and [M]agic in struct key_data
|
||||||
|
*
|
||||||
|
*/
|
||||||
uint8_t crm_encrypted[ADDITIONAL_DATA_SIZE];
|
uint8_t crm_encrypted[ADDITIONAL_DATA_SIZE];
|
||||||
uint8_t dek_encrypted_1[DATA_ENCRYPTION_KEY_SIZE];
|
/*
|
||||||
uint8_t dek_encrypted_2[DATA_ENCRYPTION_KEY_SIZE];
|
* DEK: Data Encryption Key
|
||||||
uint8_t dek_encrypted_3[DATA_ENCRYPTION_KEY_SIZE];
|
*/
|
||||||
|
uint8_t dek_encrypted_1[DATA_ENCRYPTION_KEY_SIZE]; /* For user */
|
||||||
|
uint8_t dek_encrypted_2[DATA_ENCRYPTION_KEY_SIZE]; /* For resetcode */
|
||||||
|
uint8_t dek_encrypted_3[DATA_ENCRYPTION_KEY_SIZE]; /* For admin */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BY_USER 1
|
||||||
|
#define BY_RESETCODE 2
|
||||||
|
#define BY_ADMIN 3
|
||||||
|
|
||||||
extern int flash_key_write (uint8_t *key_addr, const uint8_t *key_data, const uint8_t *modulus);
|
extern int flash_key_write (uint8_t *key_addr, const uint8_t *key_data, const uint8_t *modulus);
|
||||||
|
|
||||||
#define KEYSTRING_PASSLEN_SIZE 1
|
#define KEYSTRING_PASSLEN_SIZE 1
|
||||||
@@ -204,7 +215,9 @@ extern void gpg_do_reset_pw_counter (uint8_t which);
|
|||||||
|
|
||||||
extern void set_led (int);
|
extern void set_led (int);
|
||||||
|
|
||||||
#define NUM_ALL_PRV_KEYS 2 /* SIG and DEC *//* we don't support AUT yet */
|
#define NUM_ALL_PRV_KEYS 3 /* SIG, DEC and AUT */
|
||||||
|
|
||||||
|
extern uint8_t pw1_keystring[KEYSTRING_SIZE_PW1];
|
||||||
|
|
||||||
#define OPENPGP_CARD_INITIAL_PW1 "123456"
|
#define OPENPGP_CARD_INITIAL_PW1 "123456"
|
||||||
|
|
||||||
|
|||||||
107
src/openpgp.c
107
src/openpgp.c
@@ -29,13 +29,12 @@
|
|||||||
#include "polarssl/config.h"
|
#include "polarssl/config.h"
|
||||||
#include "polarssl/sha1.h"
|
#include "polarssl/sha1.h"
|
||||||
|
|
||||||
#define RSA_SIGNATURE_LENGTH 256 /* 256 byte == 2048-bit */
|
|
||||||
|
|
||||||
#define INS_VERIFY 0x20
|
#define INS_VERIFY 0x20
|
||||||
#define INS_CHANGE_REFERENCE_DATA 0x24
|
#define INS_CHANGE_REFERENCE_DATA 0x24
|
||||||
#define INS_PSO 0x2a
|
#define INS_PSO 0x2a
|
||||||
#define INS_RESET_RETRY_COUNTER 0x2c
|
#define INS_RESET_RETRY_COUNTER 0x2c
|
||||||
#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
|
#define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
|
||||||
|
#define INS_INTERNAL_AUTHENTICATE 0x88
|
||||||
#define INS_SELECT_FILE 0xa4
|
#define INS_SELECT_FILE 0xa4
|
||||||
#define INS_READ_BINARY 0xb0
|
#define INS_READ_BINARY 0xb0
|
||||||
#define INS_GET_DATA 0xca
|
#define INS_GET_DATA 0xca
|
||||||
@@ -180,7 +179,7 @@ cmd_change_password (void)
|
|||||||
pw += 2;
|
pw += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (who == 1) /* PW1 */
|
if (who == BY_USER) /* PW1 */
|
||||||
{
|
{
|
||||||
const uint8_t *pk = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
const uint8_t *pk = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
|
||||||
|
|
||||||
@@ -243,21 +242,21 @@ cmd_change_password (void)
|
|||||||
DEBUG_INFO ("security error.\r\n");
|
DEBUG_INFO ("security error.\r\n");
|
||||||
GPG_SECURITY_FAILURE ();
|
GPG_SECURITY_FAILURE ();
|
||||||
}
|
}
|
||||||
else if (r == 0 && who == 1) /* no prvkey */
|
else if (r == 0 && who == BY_USER) /* no prvkey */
|
||||||
{
|
{
|
||||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
|
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
|
||||||
ac_reset_pso_cds ();
|
ac_reset_pso_cds ();
|
||||||
gpg_do_reset_pw_counter (PW_STATUS_PW1);
|
gpg_do_reset_pw_counter (PW_STATUS_PW1);
|
||||||
DEBUG_INFO ("Changed DO_KEYSTRING_PW1.\r\n");
|
DEBUG_INFO ("Changed DO_KEYSTRING_PW1.\r\n");
|
||||||
}
|
}
|
||||||
else if (r > 0 && who == 1)
|
else if (r > 0 && who == BY_USER)
|
||||||
{
|
{
|
||||||
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1);
|
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1);
|
||||||
ac_reset_pso_cds ();
|
ac_reset_pso_cds ();
|
||||||
gpg_do_reset_pw_counter (PW_STATUS_PW1);
|
gpg_do_reset_pw_counter (PW_STATUS_PW1);
|
||||||
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
|
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
|
||||||
}
|
}
|
||||||
else /* r >= 0 && who == 3 */
|
else /* r >= 0 && who == BY_ADMIN */
|
||||||
{
|
{
|
||||||
DEBUG_INFO ("done.\r\n");
|
DEBUG_INFO ("done.\r\n");
|
||||||
gpg_do_reset_pw_counter (PW_STATUS_PW3);
|
gpg_do_reset_pw_counter (PW_STATUS_PW3);
|
||||||
@@ -313,7 +312,7 @@ cmd_reset_user_password (void)
|
|||||||
sha1 (pw, pw_len, old_ks);
|
sha1 (pw, pw_len, old_ks);
|
||||||
sha1 (newpw, newpw_len, new_ks);
|
sha1 (newpw, newpw_len, new_ks);
|
||||||
new_ks0[0] = newpw_len;
|
new_ks0[0] = newpw_len;
|
||||||
r = gpg_change_keystring (2, old_ks, 1, new_ks);
|
r = gpg_change_keystring (BY_RESETCODE, old_ks, BY_USER, new_ks);
|
||||||
if (r < -2)
|
if (r < -2)
|
||||||
{
|
{
|
||||||
DEBUG_INFO ("memory error.\r\n");
|
DEBUG_INFO ("memory error.\r\n");
|
||||||
@@ -362,7 +361,7 @@ cmd_reset_user_password (void)
|
|||||||
newpw = pw;
|
newpw = pw;
|
||||||
sha1 (newpw, newpw_len, new_ks);
|
sha1 (newpw, newpw_len, new_ks);
|
||||||
new_ks0[0] = newpw_len;
|
new_ks0[0] = newpw_len;
|
||||||
r = gpg_change_keystring (3, old_ks, 1, new_ks);
|
r = gpg_change_keystring (BY_ADMIN, old_ks, BY_USER, new_ks);
|
||||||
if (r < -2)
|
if (r < -2)
|
||||||
{
|
{
|
||||||
DEBUG_INFO ("memory error.\r\n");
|
DEBUG_INFO ("memory error.\r\n");
|
||||||
@@ -570,10 +569,6 @@ cmd_pso (void)
|
|||||||
{ /* Success */
|
{ /* Success */
|
||||||
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
||||||
|
|
||||||
res_APDU[RSA_SIGNATURE_LENGTH] = 0x90;
|
|
||||||
res_APDU[RSA_SIGNATURE_LENGTH+1] = 0x00;
|
|
||||||
res_APDU_size = RSA_SIGNATURE_LENGTH + 2;
|
|
||||||
|
|
||||||
if (pw_status_bytes[0] == 0)
|
if (pw_status_bytes[0] == 0)
|
||||||
ac_reset_pso_cds ();
|
ac_reset_pso_cds ();
|
||||||
|
|
||||||
@@ -583,14 +578,34 @@ cmd_pso (void)
|
|||||||
}
|
}
|
||||||
else if (cmd_APDU[2] == 0x80 && cmd_APDU[3] == 0x86)
|
else if (cmd_APDU[2] == 0x80 && cmd_APDU[3] == 0x86)
|
||||||
{
|
{
|
||||||
if (!ac_check_status (AC_PSO_OTHER_AUTHORIZED))
|
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
||||||
|
uint8_t pwsb[SIZE_PW_STATUS_BYTES];
|
||||||
|
|
||||||
|
DEBUG_SHORT (len);
|
||||||
|
|
||||||
|
if (pw_status_bytes == NULL
|
||||||
|
|| pw_status_bytes[PW_STATUS_PW1] == 0 /* locked */
|
||||||
|
|| !ac_check_status (AC_PSO_OTHER_AUTHORIZED))
|
||||||
{
|
{
|
||||||
DEBUG_INFO ("security error.");
|
DEBUG_INFO ("security error.");
|
||||||
GPG_SECURITY_FAILURE ();
|
GPG_SECURITY_FAILURE ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_SHORT (len);
|
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
||||||
|
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, BY_USER,
|
||||||
|
pw1_keystring + 1)) < 0)
|
||||||
|
{
|
||||||
|
pwsb[PW_STATUS_PW1]--;
|
||||||
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
|
GPG_SECURITY_FAILURE ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (pwsb[PW_STATUS_PW1] != 3) /* Failure in the past? */
|
||||||
|
{ /* Reset counter as it's success now */
|
||||||
|
pwsb[PW_STATUS_PW1] = 3;
|
||||||
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
ac_reset_pso_other ();
|
ac_reset_pso_other ();
|
||||||
|
|
||||||
@@ -613,6 +628,69 @@ cmd_pso (void)
|
|||||||
DEBUG_INFO ("PSO done.\r\n");
|
DEBUG_INFO ("PSO done.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_internal_authenticate (void)
|
||||||
|
{
|
||||||
|
int len = cmd_APDU[4];
|
||||||
|
int data_start = 5;
|
||||||
|
int r;
|
||||||
|
const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS);
|
||||||
|
uint8_t pwsb[SIZE_PW_STATUS_BYTES];
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
{
|
||||||
|
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
|
||||||
|
data_start = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
|
||||||
|
|
||||||
|
if (cmd_APDU[2] == 0x00 && cmd_APDU[3] == 0x00)
|
||||||
|
{
|
||||||
|
DEBUG_SHORT (len);
|
||||||
|
|
||||||
|
if (pw_status_bytes == NULL
|
||||||
|
|| pw_status_bytes[PW_STATUS_PW1] == 0 /* locked */
|
||||||
|
|| !ac_check_status (AC_PSO_OTHER_AUTHORIZED))
|
||||||
|
{
|
||||||
|
DEBUG_INFO ("security error.");
|
||||||
|
GPG_SECURITY_FAILURE ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES);
|
||||||
|
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, BY_USER,
|
||||||
|
pw1_keystring + 1)) < 0)
|
||||||
|
{
|
||||||
|
pwsb[PW_STATUS_PW1]--;
|
||||||
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
|
GPG_SECURITY_FAILURE ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (pwsb[PW_STATUS_PW1] != 3) /* Failure in the past? */
|
||||||
|
{ /* Reset counter as it's success now */
|
||||||
|
pwsb[PW_STATUS_PW1] = 3;
|
||||||
|
gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
ac_reset_pso_other ();
|
||||||
|
|
||||||
|
r = rsa_sign (&cmd_APDU[data_start], res_APDU, len);
|
||||||
|
if (r < 0)
|
||||||
|
GPG_ERROR ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_INFO (" - ??");
|
||||||
|
DEBUG_BYTE (cmd_APDU[2]);
|
||||||
|
DEBUG_INFO (" - ??");
|
||||||
|
DEBUG_BYTE (cmd_APDU[3]);
|
||||||
|
GPG_ERROR ();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct command
|
struct command
|
||||||
{
|
{
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
@@ -625,6 +703,7 @@ const struct command cmds[] = {
|
|||||||
{ INS_PSO, cmd_pso },
|
{ INS_PSO, cmd_pso },
|
||||||
{ INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
|
{ INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
|
||||||
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
|
{ INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
|
||||||
|
{ INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
|
||||||
{ INS_SELECT_FILE, cmd_select_file },
|
{ INS_SELECT_FILE, cmd_select_file },
|
||||||
{ INS_READ_BINARY, cmd_read_binary },
|
{ INS_READ_BINARY, cmd_read_binary },
|
||||||
{ INS_GET_DATA, cmd_get_data },
|
{ INS_GET_DATA, cmd_get_data },
|
||||||
|
|||||||
Reference in New Issue
Block a user