agent: Compute correct MPI length header for protected ECC keys.
authorWerner Koch <wk@gnupg.org>
Thu, 19 Mar 2015 17:01:58 +0000 (18:01 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 19 Mar 2015 17:01:58 +0000 (18:01 +0100)
* agent/cvt-openpgp.c (apply_protection): Strip leading zeroes from
opaque MPIs to comply with the OpenPGP spec.
--

This patch is the protected private key counterpart to commit ab17f7b.
Thanks to andy_s for describing the problem.

GnuPG-bug-id: 1853
Signed-off-by: Werner Koch <wk@gnupg.org>
agent/cvt-openpgp.c

index cadc871..b00f032 100644 (file)
@@ -1107,14 +1107,33 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey,
     {
       if (gcry_mpi_get_flag (array[i], GCRYMPI_FLAG_OPAQUE))
         {
-          const void *s;
+          const unsigned char *s;
           unsigned int n;
 
           s = gcry_mpi_get_opaque (array[i], &n);
+          if (!s)
+            {
+              s = "";
+              n = 0;
+            }
+          /* Strip leading zero bits.  */
+          for (; n >= 8 && !*s; s++, n -= 8)
+            ;
+          if (n >= 8 && !(*s & 0x80))
+            if (--n >= 7 && !(*s & 0x40))
+              if (--n >= 6 && !(*s & 0x20))
+                if (--n >= 5 && !(*s & 0x10))
+                  if (--n >= 4 && !(*s & 0x08))
+                    if (--n >= 3 && !(*s & 0x04))
+                      if (--n >= 2 && !(*s & 0x02))
+                        if (--n >= 1 && !(*s & 0x01))
+                          --n;
+
           nbits[j] = n;
           n = (n+7)/8;
           narr[j] = n;
-          bufarr[j] = gcry_is_secure (s)? xtrymalloc_secure (n):xtrymalloc (n);
+          bufarr[j] = (gcry_is_secure (s)? xtrymalloc_secure (n?n:1)
+                       /* */             : xtrymalloc (n?n:1));
           if (!bufarr[j])
             {
               err = gpg_error_from_syserror ();