mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Merge branch 'STABLE-BRANCH-2-2' into master
This commit is contained in:
commit
d4dc4245bf
36 changed files with 516 additions and 135 deletions
132
g10/card-util.c
132
g10/card-util.c
|
@ -659,7 +659,7 @@ current_card_status (ctrl_t ctrl, estream_t fp,
|
|||
|
||||
/* Print all available information for specific card with SERIALNO.
|
||||
Print all available information for current card when SERIALNO is NULL.
|
||||
Or print llfor all cards when SERIALNO is "all". */
|
||||
Or print for all cards when SERIALNO is "all". */
|
||||
void
|
||||
card_status (ctrl_t ctrl, estream_t fp, const char *serialno)
|
||||
{
|
||||
|
@ -1797,6 +1797,7 @@ factory_reset (void)
|
|||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 e6 00 00
|
||||
scd apdu 00 44 00 00
|
||||
scd reset
|
||||
/echo Card has been reset to factory defaults
|
||||
|
||||
but tries to find out something about the card first.
|
||||
|
@ -1809,7 +1810,7 @@ factory_reset (void)
|
|||
else if (err)
|
||||
{
|
||||
log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!termstate)
|
||||
|
@ -1859,10 +1860,16 @@ factory_reset (void)
|
|||
command because there is no machinery in scdaemon to catch
|
||||
the verify command and ask for the PIN when the "APDU"
|
||||
command is used. */
|
||||
/* Here, the length of dummy wrong PIN is 32-byte, also
|
||||
supporting authentication with KDF DO. */
|
||||
for (i=0; i < 4; i++)
|
||||
send_apdu ("00200081084040404040404040", "VERIFY", 0xffff);
|
||||
send_apdu ("0020008120"
|
||||
"40404040404040404040404040404040"
|
||||
"40404040404040404040404040404040", "VERIFY", 0xffff);
|
||||
for (i=0; i < 4; i++)
|
||||
send_apdu ("00200083084040404040404040", "VERIFY", 0xffff);
|
||||
send_apdu ("0020008320"
|
||||
"40404040404040404040404040404040"
|
||||
"40404040404040404040404040404040", "VERIFY", 0xffff);
|
||||
|
||||
/* Send terminate datafile command. */
|
||||
err = send_apdu ("00e60000", "TERMINATE DF", 0x6985);
|
||||
|
@ -1878,8 +1885,16 @@ factory_reset (void)
|
|||
|
||||
/* Finally we reset the card reader once more. */
|
||||
err = send_apdu (NULL, "RESET", 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Then, connect the card again. */
|
||||
if (!err)
|
||||
{
|
||||
char *serialno0;
|
||||
|
||||
err = agent_scd_serialno (&serialno0, NULL);
|
||||
if (!err)
|
||||
xfree (serialno0);
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (answer);
|
||||
|
@ -1887,6 +1902,104 @@ factory_reset (void)
|
|||
}
|
||||
|
||||
|
||||
#define USER_PIN_DEFAULT "123456"
|
||||
#define ADMIN_PIN_DEFAULT "12345678"
|
||||
#define KDF_DATA_LENGTH 110
|
||||
|
||||
/* Generate KDF data. */
|
||||
static gpg_error_t
|
||||
gen_kdf_data (unsigned char *data)
|
||||
{
|
||||
const unsigned char h0[] = { 0x81, 0x01, 0x03,
|
||||
0x82, 0x01, 0x08,
|
||||
0x83, 0x04 };
|
||||
const unsigned char h1[] = { 0x84, 0x08 };
|
||||
const unsigned char h2[] = { 0x85, 0x08 };
|
||||
const unsigned char h3[] = { 0x86, 0x08 };
|
||||
const unsigned char h4[] = { 0x87, 0x20 };
|
||||
const unsigned char h5[] = { 0x88, 0x20 };
|
||||
unsigned char *p, *salt_user, *salt_admin;
|
||||
unsigned char s2k_char;
|
||||
unsigned int iterations;
|
||||
unsigned char count_4byte[4];
|
||||
gpg_error_t err = 0;
|
||||
|
||||
p = data;
|
||||
|
||||
s2k_char = encode_s2k_iterations (0);
|
||||
iterations = S2K_DECODE_COUNT (s2k_char);
|
||||
count_4byte[0] = (iterations >> 24) & 0xff;
|
||||
count_4byte[1] = (iterations >> 16) & 0xff;
|
||||
count_4byte[2] = (iterations >> 8) & 0xff;
|
||||
count_4byte[3] = (iterations & 0xff);
|
||||
|
||||
memcpy (p, h0, sizeof h0);
|
||||
p += sizeof h0;
|
||||
memcpy (p, count_4byte, sizeof count_4byte);
|
||||
p += sizeof count_4byte;
|
||||
memcpy (p, h1, sizeof h1);
|
||||
salt_user = (p += sizeof h1);
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h2, sizeof h2);
|
||||
p += sizeof h2;
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h3, sizeof h3);
|
||||
salt_admin = (p += sizeof h3);
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h4, sizeof h4);
|
||||
p += sizeof h4;
|
||||
err = gcry_kdf_derive (USER_PIN_DEFAULT, strlen (USER_PIN_DEFAULT),
|
||||
GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256,
|
||||
salt_user, 8, iterations, 32, p);
|
||||
p += 32;
|
||||
if (!err)
|
||||
{
|
||||
memcpy (p, h5, sizeof h5);
|
||||
p += sizeof h5;
|
||||
err = gcry_kdf_derive (ADMIN_PIN_DEFAULT, strlen (ADMIN_PIN_DEFAULT),
|
||||
GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256,
|
||||
salt_admin, 8, iterations, 32, p);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Setup KDF data object which is used for PIN authentication. */
|
||||
static void
|
||||
kdf_setup (void)
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
gpg_error_t err;
|
||||
unsigned char kdf_data[KDF_DATA_LENGTH];
|
||||
|
||||
memset (&info, 0, sizeof info);
|
||||
|
||||
err = agent_scd_getattr ("EXTCAP", &info);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error getting card info: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info.extcap.kdf)
|
||||
{
|
||||
log_error (_("This command is not supported by this card\n"));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!(err = gen_kdf_data (kdf_data))
|
||||
&& !(err = agent_scd_setattr ("KDF", kdf_data, KDF_DATA_LENGTH, NULL)))
|
||||
err = agent_scd_getattr ("KDF", &info);
|
||||
|
||||
if (err)
|
||||
log_error (_("error for setup KDF: %s\n"), gpg_strerror (err));
|
||||
|
||||
leave:
|
||||
agent_release_card_info (&info);
|
||||
}
|
||||
|
||||
/* Data used by the command parser. This needs to be outside of the
|
||||
function scope to allow readline based command completion. */
|
||||
|
@ -1896,7 +2009,7 @@ enum cmdids
|
|||
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
|
||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
||||
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET,
|
||||
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
|
@ -1930,6 +2043,7 @@ static struct
|
|||
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
||||
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
|
||||
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
||||
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
||||
/* Note, that we do not announce these command yet. */
|
||||
{ "privatedo", cmdPRIVATEDO, 0, NULL },
|
||||
{ "readcert", cmdREADCERT, 0, NULL },
|
||||
|
@ -2213,6 +2327,10 @@ card_edit (ctrl_t ctrl, strlist_t commands)
|
|||
factory_reset ();
|
||||
break;
|
||||
|
||||
case cmdKDFSETUP:
|
||||
kdf_setup ();
|
||||
break;
|
||||
|
||||
case cmdQUIT:
|
||||
goto leave;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue