mirror of
https://salsa.debian.org/gnuk-team/gnuk/gnuk.git
synced 2024-09-20 02:40:08 +00:00
Release 0.1.
This commit is contained in:
parent
975157c9d8
commit
338b4eac03
4
AUTHORS
4
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
|
||||
|
29
ChangeLog
29
ChangeLog
@ -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
12
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
|
||||
|
||||
|
45
README
45
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
|
||||
===================
|
||||
|
22
src/ac.c
22
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);
|
||||
|
@ -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
|
||||
|
12
src/gnuk.h
12
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)));
|
||||
|
150
src/openpgp-do.c
150
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);
|
||||
}
|
||||
|
@ -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--;
|
||||
|
@ -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 = {
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user