diff options
author | Werner Koch <[email protected]> | 2009-03-20 19:04:47 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2009-03-20 19:04:47 +0000 |
commit | 36d681d98ecc224d2241b401278952b10fd8064a (patch) | |
tree | da08eb4babff8e479ee14e441b8592af70ae85bb /scd | |
parent | Add missing file. (diff) | |
download | gnupg-36d681d98ecc224d2241b401278952b10fd8064a.tar.gz gnupg-36d681d98ecc224d2241b401278952b10fd8064a.zip |
Fix keygrip computation for TCOS 3 cards.
Emit PROGRESS status lines during --learn-card.
Diffstat (limited to 'scd')
-rw-r--r-- | scd/ChangeLog | 4 | ||||
-rw-r--r-- | scd/app-nks.c | 50 |
2 files changed, 50 insertions, 4 deletions
diff --git a/scd/ChangeLog b/scd/ChangeLog index 28fd31e17..70972c2aa 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,7 @@ +2009-03-20 Werner Koch <[email protected]> + + * app-nks.c (keygripstr_from_pk_file): Fix for TCOS 3 cards. + 2009-03-18 Werner Koch <[email protected]> * apdu.c (open_pcsc_reader_wrapped): Use close_all_fds. diff --git a/scd/app-nks.c b/scd/app-nks.c index 9af39184f..3113d343c 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -124,7 +124,8 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr) size_t buflen[2]; gcry_sexp_t sexp; int i; - + int offset[2] = { 0, 0 }; + err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); if (err) return err; @@ -137,7 +138,7 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr) xfree (buffer[0]); return err; } - + if (app->app_local->nks_version < 3) { /* Old versions of NKS store the values in a TLV encoded format. @@ -152,14 +153,55 @@ keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr) err = gpg_error (GPG_ERR_TOO_SHORT); else if (buffer[i][1] != buflen[i]-2 ) err = gpg_error (GPG_ERR_INV_OBJ); + else + offset[i] = 2; + } + } + else + { + /* Remove leading zeroes to get a correct keygrip. Take care of + negative numbers. We should also fix it the same way in + libgcrypt but we can't yet rely on it yet. */ + for (i=0; i < 2; i++) + { + while (buflen[i]-offset[i] > 1 + && !buffer[i][offset[i]] + && !(buffer[i][offset[i]+1] & 0x80)) + offset[i]++; + } + } + + /* Check whether negative values are not prefixed with a zero and + fix that. */ + for (i=0; i < 2; i++) + { + if ((buflen[i]-offset[i]) && (buffer[i][offset[i]] & 0x80)) + { + unsigned char *newbuf; + size_t newlen; + + newlen = 1 + buflen[i] - offset[i]; + newbuf = xtrymalloc (newlen); + if (!newlen) + { + xfree (buffer[0]); + xfree (buffer[1]); + return gpg_error_from_syserror (); + } + newbuf[0] = 0; + memcpy (newbuf+1, buffer[i]+offset[i], buflen[i] - offset[i]); + xfree (buffer[i]); + buffer[i] = newbuf; + buflen[i] = newlen; + offset[i] = 0; } } if (!err) err = gcry_sexp_build (&sexp, NULL, "(public-key (rsa (n %b) (e %b)))", - (int)buflen[0]-2, buffer[0]+2, - (int)buflen[1]-2, buffer[1]+2); + (int)buflen[0]-offset[0], buffer[0]+offset[0], + (int)buflen[1]-offset[1], buffer[1]+offset[1]); xfree (buffer[0]); xfree (buffer[1]); |