diff --git a/AUTHORS b/AUTHORS index 4337719..9f7fdc0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,7 +6,9 @@ Kaz Kojima: boards/STM32_PRIMER2/mcuconf.h boards/STM32_PRIMER2/hw_config.c -NIIBE Yutaka: wrote +NIIBE Yutaka: + Founder of the project + Wrote src/ac.c src/main.c src/usb_lld.h diff --git a/ChangeLog b/ChangeLog index c44fae1..135b419 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2010-09-10 NIIBE Yutaka + + * src/usb_desc.c (gnukStringSerial): Change the value so that + libccid doesn't get confused. + + * src/openpgp.c (gpg_change_keystring): Support key for decryption + as well. + (cmd_read_binary): Use openpgpcard_aid. + (cmd_pso): call ac_reset_pso_other. + + * src/openpgp-do.c (openpgpcard_aid): Renamed from aid, and exported. + (do_ds_count_initial_value): New const variable. + (num_prv_keys): New variable. + (gpg_do_write_prvkey): Remove contents of keystring only if + ++num_prv_keys == NUM_ALL_PRV_KEYS. + (gpg_do_chks_prvkey): Call flash_do_release. + (gpg_do_table_init): Initialize with do_ds_count_initial_value. + Initialize num_prv_keys. + (gpg_do_write_simple): Support removing DO. + (gpg_do_increment_digital_signature_counter): Call flash_do_release. + + * src/gnuk.h (NUM_ALL_PRV_KEYS): New definition. + (OPENPGP_CARD_INITIAL_PW1): New definition. + (enum kind_of_key): Rename. + + * src/ac.c (ac_reset_pso_cds): New function. + 2010-09-09 Kaz Kojima * boards/STM32_PRIMER2/{board.c,board.h,board.mk,hw_config.c,mcuconf.h}: @@ -48,6 +75,8 @@ (mpi_write_string, mpi_read_file, mpi_read_file): #if-out to avoid stdio of libc. +2010-09-07 NIIBE Yutaka + * gnuk.svg: New file. 2010-09-06 NIIBE Yutaka diff --git a/NEWS b/NEWS index 0f78dcc..8c60254 100644 --- a/NEWS +++ b/NEWS @@ -2,18 +2,22 @@ Gnuk NEWS - User visible changes * Major changes in Gnuk 0.1 - Released 2010-09-XX, by NIIBE Yutaka + Released 2010-09-10, by NIIBE Yutaka + +** Enabled force_chv1 (in the pw_status_bytes), so that the decipher works. + +** Support both of key for digital signing and key for decryption. + +** Decipher is supported. ** New board support "STM32 Primer2" is added by Kaz Kojima. -** Now, LED behavior is meaningful. "ON" during execution. +** LED behavior is meaningful now. "ON" during execution. ** Fixed bcdCCID revision number. ** Logo. -** Decipher is supported. - * Major changes in Gnuk 0.0 diff --git a/README b/README index 52f5b57..79fd165 100644 --- a/README +++ b/README @@ -1,22 +1,31 @@ -Gnuk - software for GPG USB Token +Gnuk - software for GPG USB Token - Version 0.0 - 2010-09-06 + Version 0.1 + 2010-09-10 Niibe Yutaka Free Software Initiative of Japan -What's Gnuk -=========== +What's Gnuk? +============ Gnuk is software implementation of a USB token for GNU privacy guard. Gnuk supports OpenPGP card protocol version 2, and it runs on STM32 processor. +Please look at the graphics of "gnuk.svg" for the software name. + +I wish that Gnuk will be a developer's soother who uses GnuPG. I have +been nervous of storing secret key(s) on usual secondary storage. +While I want to work at different places, but it is not the choice for +me to bring a card reader all the time. With Gnuk, this issue will be +solved by a USB token which is small enough. + Release notes ============= -This is initial release of Gnuk, and it is experimental. +This is second release of Gnuk. While it works somehow, it is still +experimental. Tested features are: @@ -26,17 +35,19 @@ Tested features are: * Password handling (PW1, RC, PW3) - * Key import for signature only. + * Key import for both of key for digital signing and key for + decryption. * PSO: Digital Signature - -It is known not-working: - - * Multiple key import - * PSO: Decipher +It is known not-working well: + + * Key import multiple times + + * Changing value of password status bytes (0x00C4). + Targets ======= @@ -195,6 +206,16 @@ Inside GDB, we can connect OpenOCD by: (gdb) target remote localhost:3333 +You can see output of PCSCD: + + # /etc/init.d/pcscd stop + # LIBCCID_ifdLogLevel=7 /usr/sbin/pcscd --debug --foreground + + +You can observe the traffic of USB using "usbmon". See the file: +linux/Documentation/usb/usbmon.txt + + Development history =================== diff --git a/src/ac.c b/src/ac.c index b6c4224..3222c7d 100644 --- a/src/ac.c +++ b/src/ac.c @@ -22,6 +22,18 @@ ac_check_status (uint8_t ac_flag) return (ac_flag & auth_status)? 1 : 0; } +void +ac_reset_pso_cds (void) +{ + auth_status &= ~AC_PSO_CDS_AUTHORIZED; +} + +void +ac_reset_pso_other (void) +{ + auth_status &= ~AC_PSO_OTHER_AUTHORIZED; +} + int verify_pso_cds (const uint8_t *pw, int pw_len) { @@ -40,7 +52,7 @@ verify_pso_cds (const uint8_t *pw, int pw_len) keystring[0] = pw_len; sha1 (pw, pw_len, keystring+1); memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES); - if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNATURE, 1, keystring+1)) < 0) + if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, 1, keystring+1)) < 0) { pwsb[PW_STATUS_PW1]--; gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); @@ -56,12 +68,6 @@ verify_pso_cds (const uint8_t *pw, int pw_len) return 1; } -void -ac_reset_pso_cds (void) -{ - auth_status &= ~AC_PSO_CDS_AUTHORIZED; -} - int verify_pso_other (const uint8_t *pw, int pw_len) { @@ -79,7 +85,7 @@ verify_pso_other (const uint8_t *pw, int pw_len) keystring[0] = pw_len; sha1 (pw, pw_len, keystring+1); memcpy (pwsb, pw_status_bytes, SIZE_PW_STATUS_BYTES); - if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPT, 1, keystring+1)) < 0) + if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, 1, keystring+1)) < 0) { pwsb[PW_STATUS_PW1]--; gpg_do_write_simple (NR_DO_PW_STATUS, pwsb, SIZE_PW_STATUS_BYTES); diff --git a/src/config.h b/src/config.h index d088159..3dd0958 100644 --- a/src/config.h +++ b/src/config.h @@ -2,9 +2,6 @@ #define ENABLE_VIRTUAL_COM_PORT 1 #endif -/* Packet size of USB Bulk transfer for full speed */ -#define GNUK_MAX_PACKET_SIZE 64 - #if 0 /* FSIJ */ #define MANUFACTURER_IN_AID 0xf5, 0x17 diff --git a/src/gnuk.h b/src/gnuk.h index 0c84a7c..c519152 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -58,7 +58,7 @@ extern int verify_admin (const uint8_t *pw, int pw_len); extern int verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known); extern void ac_reset_pso_cds (void); - +extern void ac_reset_pso_other (void); extern void write_res_apdu (const uint8_t *p, int len, @@ -72,8 +72,8 @@ extern void gpg_do_public_key (uint8_t kk_byte); enum kind_of_key { - GPG_KEY_FOR_SIGNATURE, - GPG_KEY_FOR_DECRYPT, + GPG_KEY_FOR_SIGNING, + GPG_KEY_FOR_DECRYPTION, GPG_KEY_FOR_AUTHENTICATION, }; @@ -199,3 +199,9 @@ extern uint32_t hardclock (void); extern void gpg_do_reset_pw_counter (uint8_t which); extern void set_led (int); + +#define NUM_ALL_PRV_KEYS 2 /* SIG and DEC *//* we don't support AUT yet */ + +#define OPENPGP_CARD_INITIAL_PW1 "123456" + +const uint8_t openpgpcard_aid[17] __attribute__ ((aligned (1))); diff --git a/src/openpgp-do.c b/src/openpgp-do.c index e0100c1..370f9e0 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -39,7 +39,7 @@ */ /* AID */ -static const uint8_t aid[] __attribute__ ((aligned (1))) = { +const uint8_t openpgpcard_aid[17] __attribute__ ((aligned (1))) = { 16, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01, 0x02, 0x00, /* Version 2.0 */ @@ -87,10 +87,14 @@ static const uint8_t algorithm_attr[] __attribute__ ((aligned (1))) = { 0x00 /* 0: p&q , 3: CRT with N (not yet supported) */ }; -static const uint8_t do_pw_status_bytes_template[] = -{ +static const uint8_t do_ds_count_initial_value[] __attribute__ ((aligned (1))) = { + 3, + 0, 0, 0 +}; + +static const uint8_t do_pw_status_bytes_template[] __attribute__ ((aligned (1))) = { 7, - 1, /* PW1 valid for several PSO:CDS commands */ + 0, /* PW1 is valid for single PSO:CDS command */ 127, 127, 127, /* max length of PW1, RC, and PW3 */ 3, 0, 3 /* Error counter of PW1, RC, and PW3 */ }; @@ -483,9 +487,9 @@ get_do_ptr_nr_for_kk (enum kind_of_key kk) { switch (kk) { - case GPG_KEY_FOR_SIGNATURE: + case GPG_KEY_FOR_SIGNING: return NR_DO_PRVKEY_SIG; - case GPG_KEY_FOR_DECRYPT: + case GPG_KEY_FOR_DECRYPTION: return NR_DO_PRVKEY_DEC; case GPG_KEY_FOR_AUTHENTICATION: return NR_DO_PRVKEY_AUT; @@ -521,7 +525,7 @@ gpg_do_load_prvkey (enum kind_of_key kk, int who, const uint8_t *keystring) DEBUG_INFO ("gpg_do_load_prvkey failed.\r\n"); return -1; } - /* XXX: more sanity check */ + /* more sanity check??? */ return 1; } @@ -538,6 +542,8 @@ calc_check32 (const uint8_t *p, int len) return check; } +static int8_t num_prv_keys; + int gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, const uint8_t *keystring) @@ -549,8 +555,9 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, struct prvkey_data *pd; uint8_t *key_addr; const uint8_t *dek; - const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1); - const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC); + const uint8_t *do_data = do_ptr[nr]; + const uint8_t *ks_pw1; + const uint8_t *ks_rc; #if 0 assert (key_len == KEY_CONTENT_LEN); @@ -587,19 +594,42 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, kd.random = get_random (); memcpy (kd.magic, GNUK_MAGIC, KEY_MAGIC_LEN); - DEBUG_INFO ("enc..."); + if (do_data) /* We have old prvkey */ + { + /* Write new prvkey resetting PW1 and RC */ + /* Note: if you have other prvkey(s), it becomes bogus */ + memcpy (pd, do_data+1, sizeof (struct prvkey_data)); + decrypt (keystring_md_pw3, pd->dek_encrypted_3, DATA_ENCRYPTION_KEY_SIZE); + dek = pd->dek_encrypted_3; + memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE); + memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE); + flash_do_release (do_data); + gpg_do_write_simple (NR_DO_KEYSTRING_PW1, NULL, 0); + gpg_do_write_simple (NR_DO_KEYSTRING_RC, NULL, 0); + flash_key_release (pd->key_addr); + flash_do_release (do_data); + ks_pw1 = NULL; + ks_rc = NULL; + } + else + { + dek = random_bytes_get (); /* 16-byte random bytes */ + memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE); + memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE); + memcpy (pd->dek_encrypted_3, dek, DATA_ENCRYPTION_KEY_SIZE); + ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1); + ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC); + } - dek = random_bytes_get (); /* 16-byte random bytes */ encrypt (dek, (uint8_t *)&kd, sizeof (struct key_data)); - DEBUG_INFO ("done\r\n"); - r = flash_key_write (key_addr, kd.data, modulus); modulus_free (modulus); if (r < 0) { - random_bytes_free (dek); + if (do_data == NULL) + random_bytes_free (dek); free (pd); return r; } @@ -609,49 +639,49 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len, ac_reset_pso_cds (); if (ks_pw1) - { - uint8_t ks_pw1_len = ks_pw1[0]; - - memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE); - encrypt (ks_pw1+1, pd->dek_encrypted_1, DATA_ENCRYPTION_KEY_SIZE); - /* Only its length */ - gpg_do_write_simple (NR_DO_KEYSTRING_PW1, &ks_pw1_len, 1); - } + encrypt (ks_pw1+1, pd->dek_encrypted_1, DATA_ENCRYPTION_KEY_SIZE); else { uint8_t ks123_pw1[KEYSTRING_SIZE_PW1]; - ks123_pw1[0] = 6; - sha1 ((uint8_t *)"123456", 6, ks123_pw1+1); - memcpy (pd->dek_encrypted_1, dek, DATA_ENCRYPTION_KEY_SIZE); + ks123_pw1[0] = strlen (OPENPGP_CARD_INITIAL_PW1); + sha1 ((uint8_t *)OPENPGP_CARD_INITIAL_PW1, 6, ks123_pw1+1); encrypt (ks123_pw1+1, pd->dek_encrypted_1, DATA_ENCRYPTION_KEY_SIZE); - /* Only but its length */ - gpg_do_write_simple (NR_DO_KEYSTRING_PW1, ks123_pw1, 1); } if (ks_rc) - { - uint8_t ks_rc_len = ks_rc[0]; - - memcpy (pd->dek_encrypted_2, dek, DATA_ENCRYPTION_KEY_SIZE); - encrypt (ks_rc+1, pd->dek_encrypted_2, DATA_ENCRYPTION_KEY_SIZE); - /* Only its length */ - gpg_do_write_simple (NR_DO_KEYSTRING_RC, &ks_rc_len, 1); - } + encrypt (ks_rc+1, pd->dek_encrypted_2, DATA_ENCRYPTION_KEY_SIZE); else memset (pd->dek_encrypted_2, 0, DATA_ENCRYPTION_KEY_SIZE); - memcpy (pd->dek_encrypted_3, dek, DATA_ENCRYPTION_KEY_SIZE); encrypt (keystring, pd->dek_encrypted_3, DATA_ENCRYPTION_KEY_SIZE); p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data)); do_ptr[nr] = p; - random_bytes_free (dek); + if (do_data == NULL) + random_bytes_free (dek); free (pd); if (p == NULL) return -1; + if (do_data == NULL + && ++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered. */ + { + /* Remove contents of keystrings from DO, but length */ + if (ks_pw1) + { + uint8_t ks_pw1_len = ks_pw1[0]; + gpg_do_write_simple (NR_DO_KEYSTRING_PW1, &ks_pw1_len, 1); + } + + if (ks_rc) + { + uint8_t ks_rc_len = ks_rc[0]; + gpg_do_write_simple (NR_DO_KEYSTRING_RC, &ks_rc_len, 1); + } + } + return 0; } @@ -685,6 +715,7 @@ gpg_do_chks_prvkey (enum kind_of_key kk, p = flash_do_write (nr, (const uint8_t *)pd, sizeof (struct prvkey_data)); do_ptr[nr] = p; + flash_do_release (do_data); free (pd); if (p == NULL) return -1; @@ -710,9 +741,9 @@ proc_key_import (const uint8_t *data, int len) DEBUG_BINARY (data, len); if (data[4] == 0xb6) - kk = GPG_KEY_FOR_SIGNATURE; + kk = GPG_KEY_FOR_SIGNING; else if (data[4] == 0xb8) - kk = GPG_KEY_FOR_DECRYPT; + kk = GPG_KEY_FOR_DECRYPTION; else /* 0xa4 */ kk = GPG_KEY_FOR_AUTHENTICATION; @@ -721,15 +752,23 @@ proc_key_import (const uint8_t *data, int len) uint8_t nr = get_do_ptr_nr_for_kk (kk); const uint8_t *do_data = do_ptr[nr]; + /* Delete the key */ if (do_data) { uint8_t *key_addr = *(uint8_t **)&do_data[1]; - flash_do_release (do_data); flash_key_release (key_addr); + flash_do_release (do_data); + } + do_ptr[nr] = NULL; + + if (--num_prv_keys == 0) + { + /* Delete PW1 and RC if any */ + gpg_do_write_simple (NR_DO_KEYSTRING_PW1, NULL, 0); + gpg_do_write_simple (NR_DO_KEYSTRING_RC, NULL, 0); } - do_ptr[nr] = NULL; GPG_SUCCESS (); return; } @@ -801,11 +840,11 @@ gpg_do_table[] = { { GPG_DO_PW_STATUS, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_pw_status }, /* Fixed data */ - { GPG_DO_AID, DO_FIXED, AC_ALWAYS, AC_NEVER, aid }, + { GPG_DO_AID, DO_FIXED, AC_ALWAYS, AC_NEVER, openpgpcard_aid }, { GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities }, { GPG_DO_ALG_SIG, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, { GPG_DO_ALG_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, - { GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, NULL }, + { GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, /* Compound data: Read access only */ { GPG_DO_CH_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ch_data }, { GPG_DO_APP_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_app_data }, @@ -829,6 +868,7 @@ gpg_do_table_init (void) const uint8_t *p, *p_start; int len; + do_ptr[NR_DO_DS_COUNT] = do_ds_count_initial_value; do_ptr[NR_DO_PW_STATUS] = do_pw_status_bytes_template; p_start = flash_do_pool (); @@ -863,6 +903,13 @@ gpg_do_table_init (void) flash_set_do_pool_last (p); + num_prv_keys = 0; + if (do_ptr[NR_DO_PRVKEY_SIG] != NULL) + num_prv_keys++; + if (do_ptr[NR_DO_PRVKEY_DEC] != NULL) + num_prv_keys++; + if (do_ptr[NR_DO_PRVKEY_AUT] != NULL) + num_prv_keys++; return 0; } @@ -1171,11 +1218,19 @@ gpg_do_write_simple (uint8_t nr, const uint8_t *data, int size) if (*do_data_p) flash_do_release (*do_data_p); - *do_data_p = flash_do_write (nr, data, size); - if (*do_data_p) - GPG_SUCCESS (); + if (data != NULL) + { + *do_data_p = flash_do_write (nr, data, size); + if (*do_data_p) + GPG_SUCCESS (); + else + GPG_MEMORY_FAILURE(); + } else - GPG_MEMORY_FAILURE(); + { + *do_data_p = NULL; + GPG_SUCCESS (); + } } void @@ -1196,6 +1251,7 @@ gpg_do_increment_digital_signature_counter (void) count_data[1] = (count >> 8) & 0xff; count_data[2] = count & 0xff; + flash_do_release (do_data); do_ptr[NR_DO_DS_COUNT] = flash_do_write (NR_DO_DS_COUNT, count_data, SIZE_DIGITAL_SIGNATURE_COUNTER); } diff --git a/src/openpgp.c b/src/openpgp.c index 711327b..1fba13d 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -60,11 +60,6 @@ select_file_TOP_result[] __attribute__ ((aligned (1))) = { 0x00, 0x00 /* PIN status: OK, PIN blocked?: No */ }; -static const uint8_t -read_binary_result[] __attribute__ ((aligned (1))) = { - 0x5a, 0x4, 0x01, 0x02, 0x03, 0x04 -}; - void write_res_apdu (const uint8_t *p, int len, uint8_t sw1, uint8_t sw2) { @@ -129,17 +124,37 @@ int gpg_change_keystring (int who_old, const uint8_t *old_ks, int who_new, const uint8_t *new_ks) { - int r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNATURE, who_old, old_ks); + int r; + int prv_keys_exist = 0; - if (r <= 0) + r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks); + if (r < 0) return r; - r = gpg_do_chks_prvkey (GPG_KEY_FOR_SIGNATURE, who_old, old_ks, + if (r > 0) + prv_keys_exist++; + + r = gpg_do_chks_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks, who_new, new_ks); if (r < 0) return -2; - return r; + r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks); + if (r < 0) + return r; + + if (r > 0) + prv_keys_exist++; + + r = gpg_do_chks_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks, + who_new, new_ks); + if (r < 0) + return -2; + + if (prv_keys_exist) + return 1; + else + return 0; } static void @@ -171,21 +186,16 @@ cmd_change_password (void) if (pk == NULL) { - if (len < 6) + if (len < (int)strlen (OPENPGP_CARD_INITIAL_PW1)) { DEBUG_INFO ("permission denied.\r\n"); GPG_SECURITY_FAILURE (); return; } - /* pk==NULL implies we have no prvkey */ - pw_len = 6; + pw_len = strlen (OPENPGP_CARD_INITIAL_PW1); newpw = pw + pw_len; newpw_len = len - pw_len; - - sha1 (newpw, newpw_len, new_ks); - new_ks0[0] = newpw_len; - goto no_prvkey; } else { @@ -235,18 +245,17 @@ cmd_change_password (void) } else if (r == 0 && who == 1) /* no prvkey */ { - no_prvkey: gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1); ac_reset_pso_cds (); 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) { gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1); ac_reset_pso_cds (); gpg_do_reset_pw_counter (PW_STATUS_PW1); - DEBUG_INFO ("Removed content of DO_KEYSTRING_PW1\r\n"); + DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n"); } else /* r >= 0 && who == 3 */ { @@ -435,9 +444,15 @@ cmd_read_binary (void) if (cmd_APDU[3] >= 6) GPG_BAD_P0_P1 (); else - /* Tag 5a, serial number */ - write_res_apdu (read_binary_result, - sizeof (read_binary_result), 0x90, 0x00); + { + int len = openpgpcard_aid[0]; + + res_APDU[0] = 0x5a; + memcpy (res_APDU+1, openpgpcard_aid, len); + res_APDU[len+1] = 0x90; + res_APDU[len+2] = 0x00; + res_APDU_size = len + 3; + } } else GPG_NO_RECORD(); @@ -545,7 +560,10 @@ cmd_pso (void) r = rsa_sign (&cmd_APDU[data_start], res_APDU, len); if (r < 0) - GPG_ERROR (); + { + ac_reset_pso_cds (); + GPG_ERROR (); + } else { /* Success */ const uint8_t *pw_status_bytes = gpg_do_read_simple (NR_DO_PW_STATUS); @@ -572,6 +590,8 @@ cmd_pso (void) DEBUG_SHORT (len); + ac_reset_pso_other (); + /* Skip padding 0x00 */ data_start++; len--; diff --git a/src/usb_desc.c b/src/usb_desc.c index ca76579..932bc27 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -193,9 +193,10 @@ static const uint8_t gnukStringProduct[] = { }; static const uint8_t gnukStringSerial[] = { - 8, /* bLength */ + 8*2+2, /* bLength */ USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */ - '2', 0, '.', 0, '0', 0 + '2', 0, '0', 0, '1', 0, '0', 0, + '0', 0, '9', 0, '1', 0, '0', 0 }; const ONE_DESCRIPTOR Device_Descriptor = { diff --git a/src/usb_prop.c b/src/usb_prop.c index b1f5fe0..e488fac 100644 --- a/src/usb_prop.c +++ b/src/usb_prop.c @@ -21,6 +21,9 @@ * */ +/* Packet size of USB Bulk transfer for full speed */ +#define GNUK_MAX_PACKET_SIZE 64 + #include "config.h" #include "usb_lib.h" #include "usb_conf.h"