Map public key algos returned by gpg to gpgme values.
authorWerner Koch <wk@gnupg.org>
Thu, 8 May 2014 12:03:14 +0000 (14:03 +0200)
committerWerner Koch <wk@gnupg.org>
Thu, 8 May 2014 12:11:58 +0000 (14:11 +0200)
* src/conversion.c (_gpgme_map_pk_algo): New.
* src/decrypt.c (parse_enc_to): Add arg PROTOCOL and map pubkey algo.
(_gpgme_decrypt_status_handler): Map pubkey algo.
* src/keylist.c (keylist_colon_handler): Map pubkey algo.
* src/sign.c (parse_sig_created): Add arg PROTOCOL and map pubkey
algo.
* src/verify.c (parse_new_sig): Ditto.
(parse_valid_sig): Ditto.

* src/gpgme.h.in (GPGME_PK_ECC): New.
(GPGME_MD_SHA224): New.
* src/gpgme.c (gpgme_pubkey_algo_name): Add GPGME_PK_ECC case.
(gpgme_hash_algo_name): Add GPGME_MD_SHA224.
--

This affects only the not yet released ECC code of GnuPG 2.1.

NEWS
doc/gpgme.texi
src/conversion.c
src/decrypt.c
src/gpgme.c
src/gpgme.h.in
src/keylist.c
src/sign.c
src/util.h
src/verify.c

diff --git a/NEWS b/NEWS
index 5fb4808..b9d2f35 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,7 +12,7 @@ Noteworthy changes in version 1.5.0 (unreleased)
  * Add feature to use the gpgme I/O subsystem to run arbitrary
    commands.
 
- * Add flag to force encryption without the default comprtession step.
+ * Add flag to force encryption without the default compression step.
 
  * Interface changes relative to the 1.4.3 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -23,6 +23,8 @@ Noteworthy changes in version 1.5.0 (unreleased)
  GPGME_SPAWN_DETACHED           NEW.
  GPGME_SPAWN_ALLOW_SET_FG       NEW.
  GPGME_ENCRYPT_NO_COMPRESS      NEW.
+ GPGME_PK_ECC                   NEW.
+ GPGME_MD_SHA224                NEW.
 
 
 Noteworthy changes in version 1.4.3 (2013-08-12)
index eaf1fcb..9a67c3b 100644 (file)
@@ -1135,16 +1135,16 @@ This value indicates ElGamal.
 @item GPGME_PK_ELG_E
 This value also indicates ElGamal and is used specifically in GnuPG.
 
-@item GPGME_PK_ELG_E
-This value also indicates ElGamal and is used specifically in GnuPG.
+@item GPGME_PK_ECC
+This value is a generic indicator for ellipic curve algorithms.
 
 @item GPGME_PK_ECDSA
 This value indicates ECDSA, the Elliptic Curve Digital Signature
-Algorithm as defined by FIPS 186-2.
+Algorithm as defined by FIPS 186-2 and RFC-6637.
 
 @item GPGME_PK_ECDH
-This value indicates ECDH, the Eliptic Curve Diffie-Hellmann encryption
-algorithm as defined by the ECC in OpenPGP draft.
+This value indicates ECDH, the Eliptic Curve Diffie-Hellmann
+encryption algorithm as defined by RFC-6637.
 
 @end table
 @end deftp
@@ -1185,6 +1185,7 @@ that are supported by @acronym{GPGME}.  Possible values are:
 @item GPGME_MD_SHA256
 @item GPGME_MD_SHA384
 @item GPGME_MD_SHA512
+@item GPGME_MD_SHA224
 @item GPGME_MD_MD4
 @item GPGME_MD_CRC32
 @item GPGME_MD_CRC32_RFC1510
index b47d6de..d04a6be 100644 (file)
@@ -412,3 +412,24 @@ _gpgme_parse_timestamp (const char *timestamp, char **endp)
   else
     return (time_t)strtoul (timestamp, endp, 10);
 }
+
+
+/* The GPG backend uses OpenPGP algorithm numbers which we need to map
+   to our algorithm numbers.  This function MUST not change ERRNO. */
+int
+_gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)
+{
+  if (protocol == GPGME_PROTOCOL_OPENPGP)
+    {
+      switch (algo)
+        {
+        case 1: case 2: case 3: case 16: case 17: break;
+        case 18: algo = GPGME_PK_ECDH; break;
+        case 19: algo = GPGME_PK_ECDSA; break;
+        case 20: break;
+        default: algo = 0; break; /* Unknown.  */
+        }
+    }
+
+  return algo;
+}
index 63787c7..4742060 100644 (file)
@@ -119,7 +119,7 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx)
 
 \f
 static gpgme_error_t
-parse_enc_to (char *args, gpgme_recipient_t *recp)
+parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
 {
   gpgme_recipient_t rec;
   char *tail;
@@ -155,7 +155,7 @@ parse_enc_to (char *args, gpgme_recipient_t *recp)
   if (*args)
     {
       gpg_err_set_errno (0);
-      rec->pubkey_algo = strtol (args, &tail, 0);
+      rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
       if (errno || args == tail || *tail != ' ')
        {
          /* The crypto backend does not behave.  */
@@ -261,7 +261,7 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
       break;
 
     case GPGME_STATUS_ENC_TO:
-      err = parse_enc_to (args, opd->last_recipient_p);
+      err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
       if (err)
        return err;
 
index 24b04fc..a3768ef 100644 (file)
@@ -948,6 +948,9 @@ gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
     case GPGME_PK_DSA:
       return "DSA";
 
+    case GPGME_PK_ECC:
+      return "ECC";
+
     case GPGME_PK_ELG:
       return "ELG";
 
@@ -995,6 +998,9 @@ gpgme_hash_algo_name (gpgme_hash_algo_t algo)
     case GPGME_MD_SHA512:
       return "SHA512";
 
+    case GPGME_MD_SHA224:
+      return "SHA224";
+
     case GPGME_MD_MD4:
       return "MD4";
 
index efc58ea..d58c114 100644 (file)
@@ -227,7 +227,7 @@ typedef enum
 gpgme_data_type_t;
 
 \f
-/* Public key algorithms from libgcrypt.  */
+/* Public key algorithms.  */
 typedef enum
   {
     GPGME_PK_RSA   = 1,
@@ -235,6 +235,7 @@ typedef enum
     GPGME_PK_RSA_S = 3,
     GPGME_PK_ELG_E = 16,
     GPGME_PK_DSA   = 17,
+    GPGME_PK_ECC   = 18,
     GPGME_PK_ELG   = 20,
     GPGME_PK_ECDSA = 301,
     GPGME_PK_ECDH  = 302
@@ -242,7 +243,7 @@ typedef enum
 gpgme_pubkey_algo_t;
 
 
-/* Hash algorithms from libgcrypt.  */
+/* Hash algorithms (the values match those from libgcrypt).  */
 typedef enum
   {
     GPGME_MD_NONE          = 0,
@@ -255,6 +256,7 @@ typedef enum
     GPGME_MD_SHA256        = 8,
     GPGME_MD_SHA384        = 9,
     GPGME_MD_SHA512        = 10,
+    GPGME_MD_SHA224        = 11,
     GPGME_MD_MD4           = 301,
     GPGME_MD_CRC32        = 302,
     GPGME_MD_CRC32_RFC1510 = 303,
index 465b472..a361333 100644 (file)
@@ -537,7 +537,7 @@ keylist_colon_handler (void *priv, char *line)
        {
          int i = atoi (field[3]);
          if (i >= 1 && i < 128)
-           subkey->pubkey_algo = i;
+           subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
        }
 
       /* Field 5 has the long keyid.  Allow short key IDs for the
@@ -614,7 +614,7 @@ keylist_colon_handler (void *priv, char *line)
        {
          int i = atoi (field[3]);
          if (i >= 1 && i < 128)
-           subkey->pubkey_algo = i;
+           subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
        }
 
       /* Field 5 has the long keyid.  */
@@ -728,7 +728,7 @@ keylist_colon_handler (void *priv, char *line)
        {
          int i = atoi (field[3]);
          if (i >= 1 && i < 128)
-           keysig->pubkey_algo = i;
+           keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
        }
 
       /* Field 5 has the long keyid.  */
index e910799..c55441d 100644 (file)
@@ -142,7 +142,8 @@ gpgme_op_sign_result (gpgme_ctx_t ctx)
 
 \f
 static gpgme_error_t
-parse_sig_created (char *args, gpgme_new_signature_t *sigp)
+parse_sig_created (char *args, gpgme_new_signature_t *sigp,
+                   gpgme_protocol_t protocol)
 {
   gpgme_new_signature_t sig;
   char *tail;
@@ -180,7 +181,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp)
     }
 
   gpg_err_set_errno (0);
-  sig->pubkey_algo = strtol (args, &tail, 0);
+  sig->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
   if (errno || args == tail || *tail != ' ')
     {
       /* The crypto backend does not behave.  */
@@ -263,7 +264,7 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
     {
     case GPGME_STATUS_SIG_CREATED:
       opd->sig_created_seen = 1;
-      err = parse_sig_created (args, opd->last_sig_p);
+      err = parse_sig_created (args, opd->last_sig_p, ctx->protocol);
       if (err)
        return err;
 
index 4b46ea0..365f1d8 100644 (file)
@@ -135,6 +135,8 @@ time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
 
 gpgme_error_t _gpgme_map_gnupg_error (char *err);
 
+int _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol);
+
 \f
 /* Retrieve the environment variable NAME and return a copy of it in a
    malloc()'ed buffer in *VALUE.  If the environment variable is not
index c32241a..37b2bd4 100644 (file)
@@ -264,7 +264,8 @@ prepare_new_sig (op_data_t opd)
 }
 
 static gpgme_error_t
-parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
+parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args,
+               gpgme_protocol_t protocol)
 {
   gpgme_signature_t sig;
   char *end = strchr (args, ' ');
@@ -318,7 +319,7 @@ parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
       if (!end)
        goto parse_err_sig_fail;
       gpg_err_set_errno (0);
-      sig->pubkey_algo = strtol (end, &tail, 0);
+      sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0), protocol);
       if (errno || end == tail || *tail != ' ')
        goto parse_err_sig_fail;
       end = tail;
@@ -393,7 +394,7 @@ parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
 
 
 static gpgme_error_t
-parse_valid_sig (gpgme_signature_t sig, char *args)
+parse_valid_sig (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
 {
   char *end = strchr (args, ' ');
   if (end)
@@ -443,7 +444,8 @@ parse_valid_sig (gpgme_signature_t sig, char *args)
            {
              /* Parse the pubkey algo.  */
              gpg_err_set_errno (0);
-             sig->pubkey_algo = strtol (end, &tail, 0);
+             sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0),
+                                                     protocol);
              if (errno || end == tail || *tail != ' ')
                return trace_gpg_error (GPG_ERR_INV_ENGINE);
              end = tail;
@@ -703,11 +705,11 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
       if (sig && !opd->did_prepare_new_sig)
        calc_sig_summary (sig);
       opd->only_newsig_seen = 0;
-      return parse_new_sig (opd, code, args);
+      return parse_new_sig (opd, code, args, ctx->protocol);
 
     case GPGME_STATUS_VALIDSIG:
       opd->only_newsig_seen = 0;
-      return sig ? parse_valid_sig (sig, args)
+      return sig ? parse_valid_sig (sig, args, ctx->protocol)
        : trace_gpg_error (GPG_ERR_INV_ENGINE);
 
     case GPGME_STATUS_NODATA: