mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Make decryption with the OpenPGP card work.
* scd/app-common.h (APP_DECIPHER_INFO_NOPAD): New. * scd/app-openpgp.c (do_decipher): Add arg R_INFO. * scd/app-nks.c (do_decipher): Add arg R_INFO as a dummy. * scd/app.c (app_decipher): Add arg R_INFO. * scd/command.c (cmd_pkdecrypt): Print status line "PADDING". * agent/call-scd.c (padding_info_cb): New. (agent_card_pkdecrypt): Add arg R_PADDING. * agent/divert-scd.c (divert_pkdecrypt): Ditto. * agent/pkdecrypt.c (agent_pkdecrypt): Ditto. * agent/command.c (cmd_pkdecrypt): Print status line "PADDING". * g10/call-agent.c (padding_info_cb): New. (agent_pkdecrypt): Add arg R_PADDING. * g10/pubkey-enc.c (get_it): Use padding info. -- Decryption using a card never worked in gpg 2.1 because the information whether the pkcs#1 padding needs to be removed was not available. Gpg < 2.1 too this info from the secret sub key but that has gone in 2.1. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
04e2c83f18
commit
780ba32336
2
NEWS
2
NEWS
@ -22,6 +22,8 @@ Noteworthy changes in version 2.1.0-betaN (unreleased)
|
|||||||
|
|
||||||
* Support installation as portable application under Windows.
|
* Support installation as portable application under Windows.
|
||||||
|
|
||||||
|
* Fixed GPG to decrypt using an OpenPGP card.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.1.0beta3 (2011-12-20)
|
Noteworthy changes in version 2.1.0beta3 (2011-12-20)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
@ -370,7 +370,7 @@ int agent_pksign (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
/*-- pkdecrypt.c --*/
|
/*-- pkdecrypt.c --*/
|
||||||
int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
int agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
||||||
const unsigned char *ciphertext, size_t ciphertextlen,
|
const unsigned char *ciphertext, size_t ciphertextlen,
|
||||||
membuf_t *outbuf);
|
membuf_t *outbuf, int *r_padding);
|
||||||
|
|
||||||
/*-- genkey.c --*/
|
/*-- genkey.c --*/
|
||||||
int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
|
int check_passphrase_constraints (ctrl_t ctrl, const char *pw, int silent);
|
||||||
@ -425,7 +425,7 @@ int divert_pksign (ctrl_t ctrl,
|
|||||||
int divert_pkdecrypt (ctrl_t ctrl,
|
int divert_pkdecrypt (ctrl_t ctrl,
|
||||||
const unsigned char *cipher,
|
const unsigned char *cipher,
|
||||||
const unsigned char *shadow_info,
|
const unsigned char *shadow_info,
|
||||||
char **r_buf, size_t *r_len);
|
char **r_buf, size_t *r_len, int *r_padding);
|
||||||
int divert_generic_cmd (ctrl_t ctrl,
|
int divert_generic_cmd (ctrl_t ctrl,
|
||||||
const char *cmdline, void *assuan_context);
|
const char *cmdline, void *assuan_context);
|
||||||
int divert_writekey (ctrl_t ctrl, int force, const char *serialno,
|
int divert_writekey (ctrl_t ctrl, int force, const char *serialno,
|
||||||
@ -459,7 +459,7 @@ int agent_card_pkdecrypt (ctrl_t ctrl,
|
|||||||
int (*getpin_cb)(void *, const char *, char*,size_t),
|
int (*getpin_cb)(void *, const char *, char*,size_t),
|
||||||
void *getpin_cb_arg,
|
void *getpin_cb_arg,
|
||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
char **r_buf, size_t *r_buflen);
|
char **r_buf, size_t *r_buflen, int *r_padding);
|
||||||
int agent_card_readcert (ctrl_t ctrl,
|
int agent_card_readcert (ctrl_t ctrl,
|
||||||
const char *id, char **r_buf, size_t *r_buflen);
|
const char *id, char **r_buf, size_t *r_buflen);
|
||||||
int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf);
|
int agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* call-scd.c - fork of the scdaemon to do SC operations
|
/* call-scd.c - fork of the scdaemon to do SC operations
|
||||||
* Copyright (C) 2001, 2002, 2005, 2007, 2010,
|
* Copyright (C) 2001, 2002, 2005, 2007, 2010,
|
||||||
* 2011 Free Software Foundation, Inc.
|
* 2011 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2013 Werner Koch
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -874,14 +875,36 @@ agent_card_pksign (ctrl_t ctrl,
|
|||||||
return unlock_scd (ctrl, 0);
|
return unlock_scd (ctrl, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decipher INDATA using the current card. Note that the returned value is */
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether there is any padding info from scdaemon. */
|
||||||
|
static gpg_error_t
|
||||||
|
padding_info_cb (void *opaque, const char *line)
|
||||||
|
{
|
||||||
|
int *r_padding = opaque;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if ((s=has_leading_keyword (line, "PADDING")))
|
||||||
|
{
|
||||||
|
*r_padding = atoi (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Decipher INDATA using the current card. Note that the returned
|
||||||
|
value is not an s-expression but the raw data as returned by
|
||||||
|
scdaemon. The padding information is stored at R_PADDING with -1
|
||||||
|
for not known. */
|
||||||
int
|
int
|
||||||
agent_card_pkdecrypt (ctrl_t ctrl,
|
agent_card_pkdecrypt (ctrl_t ctrl,
|
||||||
const char *keyid,
|
const char *keyid,
|
||||||
int (*getpin_cb)(void *, const char *, char*, size_t),
|
int (*getpin_cb)(void *, const char *, char*, size_t),
|
||||||
void *getpin_cb_arg,
|
void *getpin_cb_arg,
|
||||||
const unsigned char *indata, size_t indatalen,
|
const unsigned char *indata, size_t indatalen,
|
||||||
char **r_buf, size_t *r_buflen)
|
char **r_buf, size_t *r_buflen, int *r_padding)
|
||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i;
|
||||||
char *p, line[ASSUAN_LINELENGTH];
|
char *p, line[ASSUAN_LINELENGTH];
|
||||||
@ -890,6 +913,7 @@ agent_card_pkdecrypt (ctrl_t ctrl,
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
|
*r_padding = -1; /* Unknown. */
|
||||||
rc = start_scd (ctrl);
|
rc = start_scd (ctrl);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -923,7 +947,7 @@ agent_card_pkdecrypt (ctrl_t ctrl,
|
|||||||
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
rc = assuan_transact (ctrl->scd_local->ctx, line,
|
||||||
membuf_data_cb, &data,
|
membuf_data_cb, &data,
|
||||||
inq_needpin, &inqparm,
|
inq_needpin, &inqparm,
|
||||||
NULL, NULL);
|
padding_info_cb, r_padding);
|
||||||
if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
|
if (inqparm.any_inq_seen && (gpg_err_code(rc) == GPG_ERR_CANCELED ||
|
||||||
gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
|
gpg_err_code(rc) == GPG_ERR_ASS_CANCELED))
|
||||||
rc = cancel_inquire (ctrl, rc);
|
rc = cancel_inquire (ctrl, rc);
|
||||||
|
@ -865,6 +865,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
unsigned char *value;
|
unsigned char *value;
|
||||||
size_t valuelen;
|
size_t valuelen;
|
||||||
membuf_t outbuf;
|
membuf_t outbuf;
|
||||||
|
int padding;
|
||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
@ -879,12 +880,19 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
init_membuf (&outbuf, 512);
|
init_membuf (&outbuf, 512);
|
||||||
|
|
||||||
rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
|
rc = agent_pkdecrypt (ctrl, ctrl->server_local->keydesc,
|
||||||
value, valuelen, &outbuf);
|
value, valuelen, &outbuf, &padding);
|
||||||
xfree (value);
|
xfree (value);
|
||||||
if (rc)
|
if (rc)
|
||||||
clear_outbuf (&outbuf);
|
clear_outbuf (&outbuf);
|
||||||
else
|
else
|
||||||
rc = write_and_clear_outbuf (ctx, &outbuf);
|
{
|
||||||
|
if (padding != -1)
|
||||||
|
rc = print_assuan_status (ctx, "PADDING", "%d", padding);
|
||||||
|
else
|
||||||
|
rc = 0;
|
||||||
|
if (!rc)
|
||||||
|
rc = write_and_clear_outbuf (ctx, &outbuf);
|
||||||
|
}
|
||||||
xfree (ctrl->server_local->keydesc);
|
xfree (ctrl->server_local->keydesc);
|
||||||
ctrl->server_local->keydesc = NULL;
|
ctrl->server_local->keydesc = NULL;
|
||||||
return leave_cmd (ctx, rc);
|
return leave_cmd (ctx, rc);
|
||||||
|
@ -383,12 +383,13 @@ divert_pksign (ctrl_t ctrl,
|
|||||||
|
|
||||||
/* Decrypt the the value given asn an S-expression in CIPHER using the
|
/* Decrypt the the value given asn an S-expression in CIPHER using the
|
||||||
key identified by SHADOW_INFO and return the plaintext in an
|
key identified by SHADOW_INFO and return the plaintext in an
|
||||||
allocated buffer in R_BUF. */
|
allocated buffer in R_BUF. The padding information is stored at
|
||||||
|
R_PADDING with -1 for not known. */
|
||||||
int
|
int
|
||||||
divert_pkdecrypt (ctrl_t ctrl,
|
divert_pkdecrypt (ctrl_t ctrl,
|
||||||
const unsigned char *cipher,
|
const unsigned char *cipher,
|
||||||
const unsigned char *shadow_info,
|
const unsigned char *shadow_info,
|
||||||
char **r_buf, size_t *r_len)
|
char **r_buf, size_t *r_len, int *r_padding)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
char *kid;
|
char *kid;
|
||||||
@ -399,6 +400,8 @@ divert_pkdecrypt (ctrl_t ctrl,
|
|||||||
char *plaintext;
|
char *plaintext;
|
||||||
size_t plaintextlen;
|
size_t plaintextlen;
|
||||||
|
|
||||||
|
*r_padding = -1;
|
||||||
|
|
||||||
s = cipher;
|
s = cipher;
|
||||||
if (*s != '(')
|
if (*s != '(')
|
||||||
return gpg_error (GPG_ERR_INV_SEXP);
|
return gpg_error (GPG_ERR_INV_SEXP);
|
||||||
@ -436,7 +439,7 @@ divert_pkdecrypt (ctrl_t ctrl,
|
|||||||
|
|
||||||
rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
|
rc = agent_card_pkdecrypt (ctrl, kid, getpin_cb, ctrl,
|
||||||
ciphertext, ciphertextlen,
|
ciphertext, ciphertextlen,
|
||||||
&plaintext, &plaintextlen);
|
&plaintext, &plaintextlen, r_padding);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
*r_buf = plaintext;
|
*r_buf = plaintext;
|
||||||
|
@ -32,11 +32,12 @@
|
|||||||
|
|
||||||
/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp.
|
/* DECRYPT the stuff in ciphertext which is expected to be a S-Exp.
|
||||||
Try to get the key from CTRL and write the decoded stuff back to
|
Try to get the key from CTRL and write the decoded stuff back to
|
||||||
OUTFP. */
|
OUTFP. The padding information is stored at R_PADDING with -1
|
||||||
|
for not known. */
|
||||||
int
|
int
|
||||||
agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
||||||
const unsigned char *ciphertext, size_t ciphertextlen,
|
const unsigned char *ciphertext, size_t ciphertextlen,
|
||||||
membuf_t *outbuf)
|
membuf_t *outbuf, int *r_padding)
|
||||||
{
|
{
|
||||||
gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
|
gcry_sexp_t s_skey = NULL, s_cipher = NULL, s_plain = NULL;
|
||||||
unsigned char *shadow_info = NULL;
|
unsigned char *shadow_info = NULL;
|
||||||
@ -44,6 +45,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
|||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
*r_padding = -1;
|
||||||
|
|
||||||
if (!ctrl->have_keygrip)
|
if (!ctrl->have_keygrip)
|
||||||
{
|
{
|
||||||
log_error ("speculative decryption not yet supported\n");
|
log_error ("speculative decryption not yet supported\n");
|
||||||
@ -85,7 +88,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info, &buf, &len );
|
rc = divert_pkdecrypt (ctrl, ciphertext, shadow_info,
|
||||||
|
&buf, &len, r_padding);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
|
log_error ("smartcard decryption failed: %s\n", gpg_strerror (rc));
|
||||||
|
@ -897,10 +897,15 @@ Here is an example session:
|
|||||||
C: D (b 3F444677CA)))
|
C: D (b 3F444677CA)))
|
||||||
C: END
|
C: END
|
||||||
S: # session key follows
|
S: # session key follows
|
||||||
|
S: S PADDING 0
|
||||||
S: D (value 1234567890ABCDEF0)
|
S: D (value 1234567890ABCDEF0)
|
||||||
S: OK descryption successful
|
S: OK descryption successful
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
The “PADDING” status line is only send if gpg-agent can tell what kind
|
||||||
|
of padding is used. As of now only the value 0 is used to indicate
|
||||||
|
that the padding has been removed.
|
||||||
|
|
||||||
|
|
||||||
@node Agent PKSIGN
|
@node Agent PKSIGN
|
||||||
@subsection Signing a Hash
|
@subsection Signing a Hash
|
||||||
|
@ -600,6 +600,10 @@ using the command
|
|||||||
|
|
||||||
where @var{keyid} is the hexified ID of the key to be used.
|
where @var{keyid} is the hexified ID of the key to be used.
|
||||||
|
|
||||||
|
If the card is ware of the apdding format a status line with padding
|
||||||
|
information is send before the plaintext data. The key for this
|
||||||
|
status line is @code{PADDING} with the only defined value being 0 and
|
||||||
|
meaning padding has been removed.
|
||||||
|
|
||||||
@node Scdaemon GETATTR
|
@node Scdaemon GETATTR
|
||||||
@subsection Read an attribute's value.
|
@subsection Read an attribute's value.
|
||||||
|
@ -1816,17 +1816,34 @@ inq_ciphertext_cb (void *opaque, const char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check whether there is any padding info from the agent. */
|
||||||
|
static gpg_error_t
|
||||||
|
padding_info_cb (void *opaque, const char *line)
|
||||||
|
{
|
||||||
|
int *r_padding = opaque;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if ((s=has_leading_keyword (line, "PADDING")))
|
||||||
|
{
|
||||||
|
*r_padding = atoi (s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Call the agent to do a decrypt operation using the key identified
|
/* Call the agent to do a decrypt operation using the key identified
|
||||||
by the hex string KEYGRIP and the input data S_CIPHERTEXT. On the
|
by the hex string KEYGRIP and the input data S_CIPHERTEXT. On the
|
||||||
success the decoded value is stored verbatim at R_BUF and its
|
success the decoded value is stored verbatim at R_BUF and its
|
||||||
length at R_BUF; the callers needs to release it. KEYID, MAINKEYID
|
length at R_BUF; the callers needs to release it. KEYID, MAINKEYID
|
||||||
and PUBKEY_ALGO are used to construct additional promots or status
|
and PUBKEY_ALGO are used to construct additional promots or status
|
||||||
messages. */
|
messages. The padding information is stored at R_PADDING with -1
|
||||||
|
for not known. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
||||||
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
|
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
|
||||||
gcry_sexp_t s_ciphertext,
|
gcry_sexp_t s_ciphertext,
|
||||||
unsigned char **r_buf, size_t *r_buflen)
|
unsigned char **r_buf, size_t *r_buflen, int *r_padding)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
@ -1841,9 +1858,12 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
dfltparm.keyinfo.mainkeyid = mainkeyid;
|
dfltparm.keyinfo.mainkeyid = mainkeyid;
|
||||||
dfltparm.keyinfo.pubkey_algo = pubkey_algo;
|
dfltparm.keyinfo.pubkey_algo = pubkey_algo;
|
||||||
|
|
||||||
if (!keygrip || strlen(keygrip) != 40 || !s_ciphertext || !r_buf || !r_buflen)
|
if (!keygrip || strlen(keygrip) != 40
|
||||||
|
|| !s_ciphertext || !r_buf || !r_buflen || !r_padding)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
*r_buf = NULL;
|
*r_buf = NULL;
|
||||||
|
*r_padding = -1;
|
||||||
|
|
||||||
err = start_agent (ctrl, 0);
|
err = start_agent (ctrl, 0);
|
||||||
if (err)
|
if (err)
|
||||||
@ -1881,7 +1901,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
|||||||
return err;
|
return err;
|
||||||
err = assuan_transact (agent_ctx, "PKDECRYPT",
|
err = assuan_transact (agent_ctx, "PKDECRYPT",
|
||||||
membuf_data_cb, &data,
|
membuf_data_cb, &data,
|
||||||
inq_ciphertext_cb, &parm, NULL, NULL);
|
inq_ciphertext_cb, &parm,
|
||||||
|
padding_info_cb, r_padding);
|
||||||
xfree (parm.ciphertext);
|
xfree (parm.ciphertext);
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -168,7 +168,8 @@ gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce,
|
|||||||
gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
|
||||||
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
|
u32 *keyid, u32 *mainkeyid, int pubkey_algo,
|
||||||
gcry_sexp_t s_ciphertext,
|
gcry_sexp_t s_ciphertext,
|
||||||
unsigned char **r_buf, size_t *r_buflen);
|
unsigned char **r_buf, size_t *r_buflen,
|
||||||
|
int *r_padding);
|
||||||
|
|
||||||
/* Retrieve a key encryption key. */
|
/* Retrieve a key encryption key. */
|
||||||
gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
|
gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport,
|
||||||
|
@ -146,7 +146,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
|
|||||||
unsigned int n;
|
unsigned int n;
|
||||||
size_t nframe;
|
size_t nframe;
|
||||||
u16 csum, csum2;
|
u16 csum, csum2;
|
||||||
int card = 0;
|
int padding;
|
||||||
gcry_sexp_t s_data;
|
gcry_sexp_t s_data;
|
||||||
char *desc;
|
char *desc;
|
||||||
char *keygrip;
|
char *keygrip;
|
||||||
@ -203,7 +203,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
|
|||||||
desc = gpg_format_keydesc (sk, 0, 1);
|
desc = gpg_format_keydesc (sk, 0, 1);
|
||||||
err = agent_pkdecrypt (NULL, keygrip,
|
err = agent_pkdecrypt (NULL, keygrip,
|
||||||
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
|
desc, sk->keyid, sk->main_keyid, sk->pubkey_algo,
|
||||||
s_data, &frame, &nframe);
|
s_data, &frame, &nframe, &padding);
|
||||||
xfree (desc);
|
xfree (desc);
|
||||||
gcry_sexp_release (s_data);
|
gcry_sexp_release (s_data);
|
||||||
if (err)
|
if (err)
|
||||||
@ -270,7 +270,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!card)
|
if (padding)
|
||||||
{
|
{
|
||||||
if (n + 7 > nframe)
|
if (n + 7 > nframe)
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,9 @@
|
|||||||
#define APP_CHANGE_FLAG_RESET 1
|
#define APP_CHANGE_FLAG_RESET 1
|
||||||
#define APP_CHANGE_FLAG_NULLPIN 2
|
#define APP_CHANGE_FLAG_NULLPIN 2
|
||||||
|
|
||||||
|
/* Bit flags set by the decipher function into R_INFO. */
|
||||||
|
#define APP_DECIPHER_INFO_NOPAD 1 /* Padding has been removed. */
|
||||||
|
|
||||||
|
|
||||||
struct app_local_s; /* Defined by all app-*.c. */
|
struct app_local_s; /* Defined by all app-*.c. */
|
||||||
|
|
||||||
@ -93,10 +96,11 @@ struct app_ctx_s {
|
|||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen);
|
unsigned char **outdata, size_t *outdatalen);
|
||||||
gpg_error_t (*decipher) (app_t app, const char *keyidstr,
|
gpg_error_t (*decipher) (app_t app, const char *keyidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen);
|
unsigned char **outdata, size_t *outdatalen,
|
||||||
|
unsigned int *r_info);
|
||||||
gpg_error_t (*writecert) (app_t app, ctrl_t ctrl,
|
gpg_error_t (*writecert) (app_t app, ctrl_t ctrl,
|
||||||
const char *certid,
|
const char *certid,
|
||||||
gpg_error_t (*pincb)(void*,const char *,char **),
|
gpg_error_t (*pincb)(void*,const char *,char **),
|
||||||
@ -168,15 +172,16 @@ gpg_error_t app_sign (app_t app, const char *keyidstr, int hashalgo,
|
|||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen );
|
unsigned char **outdata, size_t *outdatalen );
|
||||||
gpg_error_t app_auth (app_t app, const char *keyidstr,
|
gpg_error_t app_auth (app_t app, const char *keyidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen);
|
unsigned char **outdata, size_t *outdatalen);
|
||||||
gpg_error_t app_decipher (app_t app, const char *keyidstr,
|
gpg_error_t app_decipher (app_t app, const char *keyidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen );
|
unsigned char **outdata, size_t *outdatalen,
|
||||||
|
unsigned int *r_info);
|
||||||
gpg_error_t app_writecert (app_t app, ctrl_t ctrl,
|
gpg_error_t app_writecert (app_t app, ctrl_t ctrl,
|
||||||
const char *certidstr,
|
const char *certidstr,
|
||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
|
@ -985,13 +985,16 @@ do_decipher (app_t app, const char *keyidstr,
|
|||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen )
|
unsigned char **outdata, size_t *outdatalen,
|
||||||
|
unsigned int *r_info)
|
||||||
{
|
{
|
||||||
int rc, i;
|
int rc, i;
|
||||||
int is_sigg = 0;
|
int is_sigg = 0;
|
||||||
int fid;
|
int fid;
|
||||||
int kid;
|
int kid;
|
||||||
|
|
||||||
|
(void)r_info;
|
||||||
|
|
||||||
if (!keyidstr || !*keyidstr || !indatalen)
|
if (!keyidstr || !*keyidstr || !indatalen)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
|
|
||||||
|
@ -3598,7 +3598,8 @@ do_decipher (app_t app, const char *keyidstr,
|
|||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen )
|
unsigned char **outdata, size_t *outdatalen,
|
||||||
|
unsigned int *r_info)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
|
unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
|
||||||
@ -3727,6 +3728,8 @@ do_decipher (app_t app, const char *keyidstr,
|
|||||||
&& app->card_version == 0x0200)
|
&& app->card_version == 0x0200)
|
||||||
log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)"
|
log_info ("NOTE: Cards with manufacturer id 5 and s/n <= 346 (0x15a)"
|
||||||
" do not work with encryption keys > 2048 bits\n");
|
" do not work with encryption keys > 2048 bits\n");
|
||||||
|
|
||||||
|
*r_info |= APP_DECIPHER_INFO_NOPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -801,10 +801,13 @@ app_decipher (app_t app, const char *keyidstr,
|
|||||||
gpg_error_t (*pincb)(void*, const char *, char **),
|
gpg_error_t (*pincb)(void*, const char *, char **),
|
||||||
void *pincb_arg,
|
void *pincb_arg,
|
||||||
const void *indata, size_t indatalen,
|
const void *indata, size_t indatalen,
|
||||||
unsigned char **outdata, size_t *outdatalen )
|
unsigned char **outdata, size_t *outdatalen,
|
||||||
|
unsigned int *r_info)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
|
|
||||||
|
*r_info = 0;
|
||||||
|
|
||||||
if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
|
if (!app || !indata || !indatalen || !outdata || !outdatalen || !pincb)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
return gpg_error (GPG_ERR_INV_VALUE);
|
||||||
if (!app->ref_count)
|
if (!app->ref_count)
|
||||||
@ -817,7 +820,8 @@ app_decipher (app_t app, const char *keyidstr,
|
|||||||
err = app->fnc.decipher (app, keyidstr,
|
err = app->fnc.decipher (app, keyidstr,
|
||||||
pincb, pincb_arg,
|
pincb, pincb_arg,
|
||||||
indata, indatalen,
|
indata, indatalen,
|
||||||
outdata, outdatalen);
|
outdata, outdatalen,
|
||||||
|
r_info);
|
||||||
unlock_reader (app->slot);
|
unlock_reader (app->slot);
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info ("operation decipher result: %s\n", gpg_strerror (err));
|
log_info ("operation decipher result: %s\n", gpg_strerror (err));
|
||||||
|
@ -1089,6 +1089,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
unsigned char *outdata;
|
unsigned char *outdata;
|
||||||
size_t outdatalen;
|
size_t outdatalen;
|
||||||
char *keyidstr;
|
char *keyidstr;
|
||||||
|
unsigned int infoflags;
|
||||||
|
|
||||||
if ( IS_LOCKED (ctrl) )
|
if ( IS_LOCKED (ctrl) )
|
||||||
return gpg_error (GPG_ERR_LOCKED);
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
@ -1103,7 +1104,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
keyidstr,
|
keyidstr,
|
||||||
pin_cb, ctx,
|
pin_cb, ctx,
|
||||||
ctrl->in_data.value, ctrl->in_data.valuelen,
|
ctrl->in_data.value, ctrl->in_data.valuelen,
|
||||||
&outdata, &outdatalen);
|
&outdata, &outdatalen, &infoflags);
|
||||||
|
|
||||||
xfree (keyidstr);
|
xfree (keyidstr);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -1112,6 +1113,13 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* If the card driver told us that there is no padding, send a
|
||||||
|
status line. If there is a padding it is assumed that the
|
||||||
|
caller knows what padding is used. It would have been better
|
||||||
|
to always send that information but for backward
|
||||||
|
compatibility we can't do that. */
|
||||||
|
if ((infoflags & APP_DECIPHER_INFO_NOPAD))
|
||||||
|
send_status_direct (ctrl, "PADDING", "0");
|
||||||
rc = assuan_send_data (ctx, outdata, outdatalen);
|
rc = assuan_send_data (ctx, outdata, outdatalen);
|
||||||
xfree (outdata);
|
xfree (outdata);
|
||||||
if (rc)
|
if (rc)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user