gpg: Avoid NULL-deref in default key listing.
authorWerner Koch <wk@gnupg.org>
Mon, 2 Jun 2014 17:51:23 +0000 (19:51 +0200)
committerWerner Koch <wk@gnupg.org>
Mon, 2 Jun 2014 17:54:22 +0000 (19:54 +0200)
* g10/keyid.c (hash_public_key): Take care of NULL keys.
* g10/misc.c (pubkey_nbits): Ditto.
--

This problem was mainly due to our ECC code while checking for opaque
MPIs with the curve name.

g10/keyid.c
g10/misc.c

index 2883af1..9c94bd6 100644 (file)
@@ -167,7 +167,15 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
     {
       for (i=0; i < npkey; i++ )
         {
-          if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
+          if (!pk->pkey[i])
+            {
+              /* This case may only happen if the parsing of the MPI
+                 failed but the key was anyway created.  May happen
+                 during "gpg KEYFILE".  */
+              pp[i] = NULL;
+              nn[i] = 0;
+            }
+          else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
             {
               const void *p;
 
index 54ddad2..e219d76 100644 (file)
@@ -1628,46 +1628,54 @@ pubkey_get_nenc (pubkey_algo_t algo)
 unsigned int
 pubkey_nbits( int algo, gcry_mpi_t *key )
 {
-    int rc, nbits;
-    gcry_sexp_t sexp;
+  int rc, nbits;
+  gcry_sexp_t sexp;
 
-    if( algo == PUBKEY_ALGO_DSA ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
-                                 key[0], key[1], key[2], key[3] );
+  if (algo == PUBKEY_ALGO_DSA
+      && key[0] && key[1] && key[2] && key[3])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                            key[0], key[1], key[2], key[3] );
     }
-    else if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(elg(p%m)(g%m)(y%m)))",
-                                 key[0], key[1], key[2] );
+  else if ((algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E)
+           && key[0] && key[1] && key[2])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(elg(p%m)(g%m)(y%m)))",
+                            key[0], key[1], key[2] );
     }
-    else if( is_RSA (algo) ) {
-       rc = gcry_sexp_build ( &sexp, NULL,
-                             "(public-key(rsa(n%m)(e%m)))",
-                                 key[0], key[1] );
+  else if (is_RSA (algo)
+           && key[0] && key[1])
+    {
+      rc = gcry_sexp_build (&sexp, NULL,
+                            "(public-key(rsa(n%m)(e%m)))",
+                            key[0], key[1] );
     }
-    else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
-             || algo == PUBKEY_ALGO_EDDSA) {
-        char *curve = openpgp_oid_to_str (key[0]);
-        if (!curve)
-          rc = gpg_error_from_syserror ();
-        else
-          {
-            rc = gcry_sexp_build (&sexp, NULL,
-                                  "(public-key(ecc(curve%s)(q%m)))",
-                                 curve, key[1]);
-            xfree (curve);
-          }
+  else if ((algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH
+            || algo == PUBKEY_ALGO_EDDSA)
+           && key[0] && key[1])
+    {
+      char *curve = openpgp_oid_to_str (key[0]);
+      if (!curve)
+        rc = gpg_error_from_syserror ();
+      else
+        {
+          rc = gcry_sexp_build (&sexp, NULL,
+                                "(public-key(ecc(curve%s)(q%m)))",
+                                curve, key[1]);
+          xfree (curve);
+        }
     }
-    else
-       return 0;
+  else
+    return 0;
 
-    if ( rc )
-       BUG ();
+  if (rc)
+    BUG ();
 
-    nbits = gcry_pk_get_nbits( sexp );
-    gcry_sexp_release( sexp );
-    return nbits;
+  nbits = gcry_pk_get_nbits (sexp);
+  gcry_sexp_release (sexp);
+  return nbits;
 }