agent: Add some extra robustness to extract_private_key
authorWerner Koch <wk@gnupg.org>
Tue, 27 Jan 2015 09:22:47 +0000 (10:22 +0100)
committerWerner Koch <wk@gnupg.org>
Wed, 28 Jan 2015 08:12:36 +0000 (09:12 +0100)
* agent/cvt-openpgp.c (extract_private_key): Add arg "arraysize".
Make sure that R_FLAGS and R_CURVE are set to NULL.
--

Given that extract_private_key is not file local it is good to have some
extra asserts to protect against future wrong use.

Signed-off-by: Werner Koch <wk@gnupg.org>
agent/agent.h
agent/cvt-openpgp.c
agent/findkey.c

index 0560835..4536242 100644 (file)
@@ -501,7 +501,8 @@ int agent_handle_learn (ctrl_t ctrl, int send, void *assuan_context);
 gpg_error_t
 extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
                      const char **r_algoname, int *r_npkey, int *r_nskey,
-                     const char **r_format, gcry_mpi_t *mpi_array,
+                     const char **r_format,
+                     gcry_mpi_t *mpi_array, int arraysize,
                      gcry_sexp_t *r_curve, gcry_sexp_t *r_flags);
 
 #endif /*AGENT_H*/
index dff6b7c..8cf0023 100644 (file)
@@ -1187,13 +1187,15 @@ apply_protection (gcry_mpi_t *array, int npkey, int nskey,
  * R_NSKEY is pointer to number of private key data.
  * R_ELEMS is static string which is no need to free by caller.
  * ARRAY contains public and private key data.
+ * ARRAYSIZE is the allocated size of the array for cross-checking.
  * R_CURVE is pointer to S-Expression of the curve (can be NULL).
  * R_FLAGS is pointer to S-Expression of the flags (can be NULL).
  */
 gpg_error_t
 extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
                      const char **r_algoname, int *r_npkey, int *r_nskey,
-                     const char **r_elems, gcry_mpi_t *array,
+                     const char **r_elems,
+                     gcry_mpi_t *array, int arraysize,
                      gcry_sexp_t *r_curve, gcry_sexp_t *r_flags)
 {
   gpg_error_t err;
@@ -1204,6 +1206,9 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
   gcry_sexp_t curve = NULL;
   gcry_sexp_t flags = NULL;
 
+  *r_curve = NULL;
+  *r_flags = NULL;
+
   if (!req_private_key_data)
     {
       list = gcry_sexp_find_token (s_key, "shadowed-private-key", 0 );
@@ -1231,6 +1236,9 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
       return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */
     }
 
+  if (arraysize < 7)
+    BUG ();
+
   /* Map NAME to a name as used by Libgcrypt.  We do not use the
      Libgcrypt function here because we need a lowercase name and
      require special treatment for some algorithms.  */
@@ -1375,7 +1383,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
     array[i] = NULL;
 
   err = extract_private_key (s_key, 1, &algoname, &npkey, &nskey, NULL,
-                             array, &curve, &flags);
+                             array, DIM (array), &curve, &flags);
   if (err)
     return err;
 
index 064f7d2..156102b 100644 (file)
@@ -1005,7 +1005,7 @@ agent_public_key_from_file (ctrl_t ctrl,
     array[i] = NULL;
 
   err = extract_private_key (s_skey, 0, &algoname, &npkey, NULL, &elems,
-                             array, &curve, &flags);
+                             array, DIM (array), &curve, &flags);
   if (err)
     {
       gcry_sexp_release (s_skey);