Release 0.1.

This commit is contained in:
NIIBE Yutaka 2010-09-09 17:50:34 +09:00
parent 975157c9d8
commit 338b4eac03
11 changed files with 248 additions and 103 deletions

View File

@ -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

View File

@ -1,3 +1,30 @@
2010-09-10 NIIBE Yutaka <gniibe@fsij.org>
* 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 <kkojima@rr.iij4u.or.jp>
* 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 <gniibe@fsij.org>
* gnuk.svg: New file.
2010-09-06 NIIBE Yutaka <gniibe@fsij.org>

12
NEWS
View File

@ -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

43
README
View File

@ -1,22 +1,31 @@
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
===================

View File

@ -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);

View File

@ -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

View File

@ -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)));

View File

@ -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);
}

View File

@ -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--;

View File

@ -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 = {

View File

@ -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"