mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-22 14:57:02 +01:00
* ccid-driver.c (ccid_transceive): Add T=1 chaining for sending.
* sign.c (do_sign) [!ENABLE_CARD_SUPPORT]: Return an error for card keys. * cardglue.c (agent_scd_pkdecrypt): Implemented. * pubkey-enc.c (get_it) [ENABLE_CARD_SUPPORT]: Divert decryption to card
This commit is contained in:
parent
72c648c035
commit
f633ef17dc
@ -1,3 +1,14 @@
|
|||||||
|
2003-10-09 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* ccid-driver.c (ccid_transceive): Add T=1 chaining for sending.
|
||||||
|
|
||||||
|
* sign.c (do_sign) [!ENABLE_CARD_SUPPORT]: Return an error for
|
||||||
|
card keys.
|
||||||
|
|
||||||
|
* cardglue.c (agent_scd_pkdecrypt): Implemented.
|
||||||
|
* pubkey-enc.c (get_it) [ENABLE_CARD_SUPPORT]: Divert decryption
|
||||||
|
to card
|
||||||
|
|
||||||
2003-10-08 Werner Koch <wk@gnupg.org>
|
2003-10-08 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* cardglue.c (pin_cb): Detect whether an admin or regular PIN is
|
* cardglue.c (pin_cb): Detect whether an admin or regular PIN is
|
||||||
|
@ -631,10 +631,21 @@ agent_scd_pksign (const char *serialno, int hashalgo,
|
|||||||
int
|
int
|
||||||
agent_scd_pkdecrypt (const char *serialno,
|
agent_scd_pkdecrypt (const char *serialno,
|
||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
char **r_buf, size_t *r_buflen)
|
unsigned char **r_buf, size_t *r_buflen)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
APP app;
|
||||||
|
|
||||||
|
*r_buf = NULL;
|
||||||
|
*r_buflen = 0;
|
||||||
|
app = current_app? current_app : open_card ();
|
||||||
|
if (!app)
|
||||||
return gpg_error (GPG_ERR_CARD);
|
return gpg_error (GPG_ERR_CARD);
|
||||||
|
|
||||||
|
return app->fnc.decipher (app, serialno,
|
||||||
|
pin_cb, NULL,
|
||||||
|
indata, indatalen,
|
||||||
|
r_buf, r_buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
||||||
|
@ -151,7 +151,7 @@ int agent_scd_pksign (const char *keyid, int hashalgo,
|
|||||||
/* Send a PKDECRYPT command to the SCdaemon. */
|
/* Send a PKDECRYPT command to the SCdaemon. */
|
||||||
int agent_scd_pkdecrypt (const char *serialno,
|
int agent_scd_pkdecrypt (const char *serialno,
|
||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
char **r_buf, size_t *r_buflen);
|
unsigned char **r_buf, size_t *r_buflen);
|
||||||
|
|
||||||
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
/* Change the PIN of an OpenPGP card or reset the retry counter. */
|
||||||
int agent_scd_change_pin (int chvno);
|
int agent_scd_change_pin (int chvno);
|
||||||
|
@ -132,6 +132,11 @@
|
|||||||
#endif /* This source not used by scdaemon. */
|
#endif /* This source not used by scdaemon. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Define to print information pertaining the T=1 protocol. */
|
||||||
|
#undef DEBUG_T1 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RDR_to_PC_NotifySlotChange= 0x50,
|
RDR_to_PC_NotifySlotChange= 0x50,
|
||||||
RDR_to_PC_HardwareError = 0x51,
|
RDR_to_PC_HardwareError = 0x51,
|
||||||
@ -566,7 +571,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGOUT_3 ("status: %02X error: %02X clock-status: %02X\n"
|
DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n"
|
||||||
" data:", buffer[7], buffer[8], buffer[9] );
|
" data:", buffer[7], buffer[8], buffer[9] );
|
||||||
for (i=10; i < msglen; i++)
|
for (i=10; i < msglen; i++)
|
||||||
DEBUGOUT_CONT_1 (" %02X", buffer[i]);
|
DEBUGOUT_CONT_1 (" %02X", buffer[i]);
|
||||||
@ -753,33 +758,52 @@ ccid_get_atr (ccid_driver_t handle,
|
|||||||
|
|
||||||
int
|
int
|
||||||
ccid_transceive (ccid_driver_t handle,
|
ccid_transceive (ccid_driver_t handle,
|
||||||
const unsigned char *apdu, size_t apdulen,
|
const unsigned char *apdu_buf, size_t apdu_buflen,
|
||||||
unsigned char *resp, size_t maxresplen, size_t *nresp)
|
unsigned char *resp, size_t maxresplen, size_t *nresp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned char send_buffer[10+258], recv_buffer[10+258];
|
unsigned char send_buffer[10+258], recv_buffer[10+258];
|
||||||
|
const unsigned char *apdu;
|
||||||
|
size_t apdulen;
|
||||||
unsigned char *msg, *tpdu, *p;
|
unsigned char *msg, *tpdu, *p;
|
||||||
size_t msglen, tpdulen, n;
|
size_t msglen, tpdulen, n;
|
||||||
unsigned char seqno;
|
unsigned char seqno;
|
||||||
int i;
|
int i;
|
||||||
unsigned char crc;
|
unsigned char crc;
|
||||||
size_t dummy_nresp;
|
size_t dummy_nresp;
|
||||||
|
int next_chunk = 1;
|
||||||
int sending = 1;
|
int sending = 1;
|
||||||
|
|
||||||
if (!nresp)
|
if (!nresp)
|
||||||
nresp = &dummy_nresp;
|
nresp = &dummy_nresp;
|
||||||
|
|
||||||
*nresp = 0;
|
*nresp = 0;
|
||||||
|
|
||||||
|
tpdulen = 0; /* Avoid compiler warning about no initialization. */
|
||||||
|
msg = send_buffer;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (next_chunk)
|
||||||
|
{
|
||||||
|
next_chunk = 0;
|
||||||
|
|
||||||
|
apdu = apdu_buf;
|
||||||
|
apdulen = apdu_buflen;
|
||||||
|
assert (apdulen);
|
||||||
|
|
||||||
/* Construct an I-Block. */
|
/* Construct an I-Block. */
|
||||||
if (apdulen > 254)
|
if (apdulen > 254)
|
||||||
return -1; /* Invalid length. */
|
return -1; /* Invalid length. */
|
||||||
|
|
||||||
msg = send_buffer;
|
|
||||||
|
|
||||||
tpdu = msg+10;
|
tpdu = msg+10;
|
||||||
tpdu[0] = ((1 << 4) | 0); /* NAD: DAD=1, SAD=0 */
|
tpdu[0] = ((1 << 4) | 0); /* NAD: DAD=1, SAD=0 */
|
||||||
tpdu[1] = ((handle->t1_ns & 1) << 6); /* I-block */
|
tpdu[1] = ((handle->t1_ns & 1) << 6); /* I-block */
|
||||||
|
if (apdulen > 128 /* fixme: replace by ifsc */)
|
||||||
|
{
|
||||||
|
apdulen = 128;
|
||||||
|
apdu_buf += 128;
|
||||||
|
apdu_buflen -= 128;
|
||||||
|
tpdu[1] |= (1 << 5); /* Set more bit. */
|
||||||
|
}
|
||||||
tpdu[2] = apdulen;
|
tpdu[2] = apdulen;
|
||||||
memcpy (tpdu+3, apdu, apdulen);
|
memcpy (tpdu+3, apdu, apdulen);
|
||||||
crc = 0;
|
crc = 0;
|
||||||
@ -788,9 +812,8 @@ ccid_transceive (ccid_driver_t handle,
|
|||||||
tpdu[3+apdulen] = crc;
|
tpdu[3+apdulen] = crc;
|
||||||
|
|
||||||
tpdulen = apdulen + 4;
|
tpdulen = apdulen + 4;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
msg[0] = PC_to_RDR_XfrBlock;
|
msg[0] = PC_to_RDR_XfrBlock;
|
||||||
msg[5] = 0; /* slot */
|
msg[5] = 0; /* slot */
|
||||||
msg[6] = seqno = handle->seqno++;
|
msg[6] = seqno = handle->seqno++;
|
||||||
@ -805,10 +828,12 @@ ccid_transceive (ccid_driver_t handle,
|
|||||||
DEBUGOUT_CONT_1 (" %02X", msg[i]);
|
DEBUGOUT_CONT_1 (" %02X", msg[i]);
|
||||||
DEBUGOUT_LF ();
|
DEBUGOUT_LF ();
|
||||||
|
|
||||||
/* fprintf (stderr, "T1: put %c-block seq=%d\n", */
|
#ifdef DEBUG_T1
|
||||||
/* ((msg[11] & 0xc0) == 0x80)? 'R' : */
|
fprintf (stderr, "T1: put %c-block seq=%d\n",
|
||||||
/* (msg[11] & 0x80)? 'S' : 'I', */
|
((msg[11] & 0xc0) == 0x80)? 'R' :
|
||||||
/* ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40))); */
|
(msg[11] & 0x80)? 'S' : 'I',
|
||||||
|
((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)));
|
||||||
|
#endif
|
||||||
|
|
||||||
rc = bulk_out (handle, msg, msglen);
|
rc = bulk_out (handle, msg, msglen);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -829,12 +854,14 @@ ccid_transceive (ccid_driver_t handle,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fprintf (stderr, "T1: got %c-block seq=%d err=%d\n", */
|
#ifdef DEBUG_T1
|
||||||
/* ((msg[11] & 0xc0) == 0x80)? 'R' : */
|
fprintf (stderr, "T1: got %c-block seq=%d err=%d\n",
|
||||||
/* (msg[11] & 0x80)? 'S' : 'I', */
|
((msg[11] & 0xc0) == 0x80)? 'R' :
|
||||||
/* ((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)), */
|
(msg[11] & 0x80)? 'S' : 'I',
|
||||||
/* ((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0 */
|
((msg[11] & 0x80)? !!(msg[11]& 0x10) : !!(msg[11] & 0x40)),
|
||||||
/* ); */
|
((msg[11] & 0xc0) == 0x80)? (msg[11] & 0x0f) : 0
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(tpdu[1] & 0x80))
|
if (!(tpdu[1] & 0x80))
|
||||||
{ /* This is an I-block. */
|
{ /* This is an I-block. */
|
||||||
@ -899,9 +926,20 @@ ccid_transceive (ccid_driver_t handle,
|
|||||||
{ /* Error: repeat last block */
|
{ /* Error: repeat last block */
|
||||||
msg = send_buffer;
|
msg = send_buffer;
|
||||||
}
|
}
|
||||||
|
else if (sending && !!(tpdu[1] & 0x40) == handle->t1_ns)
|
||||||
|
{ /* Reponse does not match our sequence number. */
|
||||||
|
DEBUGOUT ("R-block with wrong seqno received on more bit\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (sending)
|
||||||
|
{ /* Send next chunk. */
|
||||||
|
msg = send_buffer;
|
||||||
|
next_chunk = 1;
|
||||||
|
handle->t1_ns ^= 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUGOUT ("unxpectec ACK R-block received\n");
|
DEBUGOUT ("unexpected ACK R-block received\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
#include "cardglue.h"
|
||||||
|
|
||||||
static int get_it( PKT_pubkey_enc *k,
|
static int get_it( PKT_pubkey_enc *k,
|
||||||
DEK *dek, PKT_secret_key *sk, u32 *keyid );
|
DEK *dek, PKT_secret_key *sk, u32 *keyid );
|
||||||
@ -138,11 +139,45 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
|||||||
unsigned n, nframe;
|
unsigned n, nframe;
|
||||||
u16 csum, csum2;
|
u16 csum, csum2;
|
||||||
|
|
||||||
|
int card = 0;
|
||||||
|
|
||||||
|
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
||||||
|
{ /* Note, that we only support RSA for now. */
|
||||||
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
|
unsigned char *rbuf;
|
||||||
|
size_t rbuflen;
|
||||||
|
char *snbuf;
|
||||||
|
unsigned char *indata = NULL;
|
||||||
|
unsigned int indatalen;
|
||||||
|
|
||||||
|
snbuf = serialno_and_fpr_from_sk (sk->protect.iv, sk->protect.ivlen, sk);
|
||||||
|
|
||||||
|
indata = mpi_get_buffer (enc->data[0], &indatalen, NULL);
|
||||||
|
if (!indata)
|
||||||
|
BUG ();
|
||||||
|
|
||||||
|
rc = agent_scd_pkdecrypt (snbuf, indata, indatalen, &rbuf, &rbuflen);
|
||||||
|
xfree (snbuf);
|
||||||
|
xfree (indata);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
frame = rbuf;
|
||||||
|
nframe = rbuflen;
|
||||||
|
card = 1;
|
||||||
|
#else
|
||||||
|
rc = G10ERR_UNSUPPORTED;
|
||||||
|
goto leave;
|
||||||
|
#endif /*!ENABLE_CARD_SUPPORT*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
|
rc = pubkey_decrypt(sk->pubkey_algo, &plain_dek, enc->data, sk->skey );
|
||||||
if( rc )
|
if( rc )
|
||||||
goto leave;
|
goto leave;
|
||||||
frame = mpi_get_buffer( plain_dek, &nframe, NULL );
|
frame = mpi_get_buffer( plain_dek, &nframe, NULL );
|
||||||
mpi_free( plain_dek ); plain_dek = NULL;
|
mpi_free( plain_dek ); plain_dek = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now get the DEK (data encryption key) from the frame
|
/* Now get the DEK (data encryption key) from the frame
|
||||||
*
|
*
|
||||||
@ -164,6 +199,8 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
|||||||
if( DBG_CIPHER )
|
if( DBG_CIPHER )
|
||||||
log_hexdump("DEK frame:", frame, nframe );
|
log_hexdump("DEK frame:", frame, nframe );
|
||||||
n=0;
|
n=0;
|
||||||
|
if (!card)
|
||||||
|
{
|
||||||
if( n + 7 > nframe )
|
if( n + 7 > nframe )
|
||||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||||
if( frame[n] == 1 && frame[nframe-1] == 2 ) {
|
if( frame[n] == 1 && frame[nframe-1] == 2 ) {
|
||||||
@ -176,6 +213,8 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid )
|
|||||||
for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
|
for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
|
||||||
;
|
;
|
||||||
n++; /* and the zero byte */
|
n++; /* and the zero byte */
|
||||||
|
}
|
||||||
|
|
||||||
if( n + 4 > nframe )
|
if( n + 4 > nframe )
|
||||||
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
{ rc = G10ERR_WRONG_SECKEY; goto leave; }
|
||||||
|
|
||||||
|
@ -306,9 +306,9 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
|||||||
sig->digest_algo = digest_algo;
|
sig->digest_algo = digest_algo;
|
||||||
sig->digest_start[0] = dp[0];
|
sig->digest_start[0] = dp[0];
|
||||||
sig->digest_start[1] = dp[1];
|
sig->digest_start[1] = dp[1];
|
||||||
#ifdef ENABLE_CARD_SUPPORT
|
|
||||||
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
if (sk->is_protected && sk->protect.s2k.mode == 1002)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_CARD_SUPPORT
|
||||||
unsigned char *rbuf;
|
unsigned char *rbuf;
|
||||||
size_t rbuflen;
|
size_t rbuflen;
|
||||||
char *snbuf;
|
char *snbuf;
|
||||||
@ -327,9 +327,11 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
|
|||||||
mpi_set_buffer (sig->data[0], rbuf, rbuflen, 0);
|
mpi_set_buffer (sig->data[0], rbuf, rbuflen, 0);
|
||||||
xfree (rbuf);
|
xfree (rbuf);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
return G10ERR_UNSUPPORTED;
|
||||||
|
#endif /* ENABLE_CARD_SUPPORT */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* ENABLE_CARD_SUPPORT */
|
|
||||||
{
|
{
|
||||||
frame = encode_md_value( sk->pubkey_algo, md,
|
frame = encode_md_value( sk->pubkey_algo, md,
|
||||||
digest_algo, mpi_get_nbits(sk->skey[0]), 0 );
|
digest_algo, mpi_get_nbits(sk->skey[0]), 0 );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user