Adjust for signed integer passed to OpenPGP card decrypt.

This commit is contained in:
Werner Koch 2011-08-08 10:44:03 +02:00
parent 663768f9af
commit 14e0b60efd
2 changed files with 26 additions and 8 deletions

View File

@ -1,3 +1,8 @@
2011-08-08 Werner Koch <wk@g10code.com>
* app-openpgp.c (do_decipher): Take care of accidentally passed
signed integer data with a leading 0.
2011-06-16 Werner Koch <wk@g10code.com> 2011-06-16 Werner Koch <wk@g10code.com>
* app-openpgp.c (send_key_data): Implemented chunked mode. * app-openpgp.c (send_key_data): Implemented chunked mode.

View File

@ -3367,17 +3367,19 @@ do_decipher (app_t app, const char *keyidstr,
rc = verify_chv2 (app, pincb, pincb_arg); rc = verify_chv2 (app, pincb, pincb_arg);
if (!rc) if (!rc)
{ {
size_t fixuplen; int fixuplen;
unsigned char *fixbuf = NULL; unsigned char *fixbuf = NULL;
int padind = 0; int padind = 0;
/* We might encounter a couple of leading zeroes in the /* We might encounter a couple of leading zeroes in the
cryptogram. Due to internal use of MPIs thease leading cryptogram. Due to internal use of MPIs these leading zeroes
zeroes are stripped. However the OpenPGP card expects are stripped. However the OpenPGP card expects exactly 128
exactly 128 bytes for the cryptogram (for a 1k key). Thus we bytes for the cryptogram (for a 1k key). Thus we need to fix
need to fix it up. We do this for up to 16 leading zero it up. We do this for up to 16 leading zero bytes; a
bytes; a cryptogram with more than this is with a very high cryptogram with more than this is with a very high
probability anyway broken. */ probability anyway broken. If a signed conversion was used
we may also encounter one leading zero followed by the correct
length. We fix that as well. */
if (indatalen >= (128-16) && indatalen < 128) /* 1024 bit key. */ if (indatalen >= (128-16) && indatalen < 128) /* 1024 bit key. */
fixuplen = 128 - indatalen; fixuplen = 128 - indatalen;
else if (indatalen >= (192-16) && indatalen < 192) /* 1536 bit key. */ else if (indatalen >= (192-16) && indatalen < 192) /* 1536 bit key. */
@ -3388,10 +3390,16 @@ do_decipher (app_t app, const char *keyidstr,
fixuplen = 384 - indatalen; fixuplen = 384 - indatalen;
else if (indatalen >= (512-16) && indatalen < 512) /* 4096 bit key. */ else if (indatalen >= (512-16) && indatalen < 512) /* 4096 bit key. */
fixuplen = 512 - indatalen; fixuplen = 512 - indatalen;
else if (!*(const char *)indata && (indatalen == 129
|| indatalen == 193
|| indatalen == 257
|| indatalen == 385
|| indatalen == 513))
fixuplen = -1;
else else
fixuplen = 0; fixuplen = 0;
if (fixuplen) if (fixuplen > 0)
{ {
/* While we have to prepend stuff anyway, we can also /* While we have to prepend stuff anyway, we can also
include the padding byte here so that iso1816_decipher include the padding byte here so that iso1816_decipher
@ -3408,6 +3416,11 @@ do_decipher (app_t app, const char *keyidstr,
indatalen = fixuplen + indatalen; indatalen = fixuplen + indatalen;
padind = -1; /* Already padded. */ padind = -1; /* Already padded. */
} }
else if (fixuplen < 0)
{
/* We use the extra leading zero as the padding byte. */
padind = -1;
}
if (app->app_local->cardcap.ext_lc_le && indatalen > 254 ) if (app->app_local->cardcap.ext_lc_le && indatalen > 254 )
{ {