diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2015-12-04 06:02:48 +0100 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2015-12-04 06:02:48 +0100 |
commit | f747adfa21551e083bc947540c64c94a96dcc059 (patch) | |
tree | 93987559ba44ce2a292e73bf04d65ee3a20fa4ae /scd/app-openpgp.c | |
parent | scd: Another fix for Curve25519 prefix handling. (diff) | |
download | gnupg2-f747adfa21551e083bc947540c64c94a96dcc059.tar.xz gnupg2-f747adfa21551e083bc947540c64c94a96dcc059.zip |
scd: More fix for Curve25519 prefix handling.
* scd/app-openpgp.c (do_decipher): Handle trancated cipher text.
Also fix xfree bug introduced.
--
In old format with no prefix, cipher text can be trancated when it
is parsed as MPI. Recover the value adding back zeros.
Fixes-commit: 11b2691eddc42e91651e4f95dd2731255a3e9211
Diffstat (limited to 'scd/app-openpgp.c')
-rw-r--r-- | scd/app-openpgp.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index f8e14603d..d204740a0 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -4175,14 +4175,25 @@ do_decipher (app_t app, const char *keyidstr, } else if (app->app_local->keyattr[1].key_type == KEY_TYPE_ECC) { - if (app->app_local->keyattr[1].ecc.flags - && (indatalen%2)) - { /* - * Skip the prefix. It may be 0x40 (in new format), or MPI - * head of 0x00 (in old format). - */ - indata = (const char *)indata + 1; - indatalen--; + int old_format_len = 0; + + if (app->app_local->keyattr[1].ecc.flags) + { + if (indatalen > 32 + 1) + { /* + * Skip the prefix. It may be 0x40 (in new format), or MPI + * head of 0x00 (in old format). + */ + indata = (const char *)indata + 1; + indatalen--; + } + else if (indatalen < 32) + { /* + * Old format trancated by MPI handling. + */ + old_format_len = indatalen; + indatalen = 32; + } } fixuplen = 7; @@ -4198,7 +4209,16 @@ do_decipher (app_t app, const char *keyidstr, fixbuf[4] = (char)(indatalen+2); fixbuf[5] = '\x86'; fixbuf[6] = (char)indatalen; - memcpy (fixbuf+fixuplen, indata, indatalen); + if (old_format_len) + { + memset (fixbuf+fixuplen, 0, 32 - old_format_len); + memcpy (fixbuf+fixuplen + 32 - old_format_len, + indata, old_format_len); + } + else + { + memcpy (fixbuf+fixuplen, indata, indatalen); + } indata = fixbuf; indatalen = fixuplen + indatalen; @@ -4230,12 +4250,12 @@ do_decipher (app_t app, const char *keyidstr, fixbuf = xtrymalloc (*outdatalen + 1); if (!fixbuf) { - xfree (outdata); + xfree (*outdata); return gpg_error_from_syserror (); } fixbuf[0] = 0x40; memcpy (fixbuf+1, *outdata, *outdatalen); - xfree (outdata); + xfree (*outdata); *outdata = fixbuf; *outdatalen = *outdatalen + 1; } |