diff options
| -rw-r--r-- | doc/gpgme.texi | 15 | ||||
| -rw-r--r-- | src/engine-gpg.c | 8 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 33 | ||||
| -rw-r--r-- | src/export.c | 35 | ||||
| -rw-r--r-- | src/gpgme-tool.c | 8 | ||||
| -rw-r--r-- | src/gpgme.h.in | 3 | ||||
| -rw-r--r-- | tests/run-export.c | 41 | 
7 files changed, 123 insertions, 20 deletions
| diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 010b914d..20e1912b 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -3700,6 +3700,21 @@ keys it removes all signatures except for the latest self-signatures.  For X.509 keys it has no effect. +@item GPGME_EXPORT_MODE_SECRET +Instead of exporting the public key, the secret key is exported.  This +may not be combined with @code{GPGME_EXPORT_MODE_EXTERN}.  For X.509 +the export format is PKCS#8. + +@item GPGME_EXPORT_MODE_RAW +If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509 +key the export format will be changed to PKCS#1.  This flag may not be +used with OpenPGP. + +@item GPGME_EXPORT_MODE_PKCS12 +If this flag is used with @code{GPGME_EXPORT_MODE_SECRET} for an X.509 +key the export format will be changed to PKCS#12 which also includes +the certificate.  This flag may not be used with OpenPGP. +  @end table diff --git a/src/engine-gpg.c b/src/engine-gpg.c index d1385926..ffae2fe4 100644 --- a/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -1793,7 +1793,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,    gpgme_error_t err = 0;    if ((mode & ~(GPGME_EXPORT_MODE_EXTERN -                |GPGME_EXPORT_MODE_MINIMAL))) +                |GPGME_EXPORT_MODE_MINIMAL +                |GPGME_EXPORT_MODE_SECRET)))      return gpg_error (GPG_ERR_NOT_SUPPORTED);    if ((mode & GPGME_EXPORT_MODE_MINIMAL)) @@ -1807,7 +1808,10 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,      }    else      { -      err = add_arg (gpg, "--export"); +      if ((mode & GPGME_EXPORT_MODE_SECRET)) +        err = add_arg (gpg, "--export-secret-keys"); +      else +        err = add_arg (gpg, "--export");        if (!err && use_armor)          err = add_arg (gpg, "--armor");        if (!err) diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c index 37711574..24d3b2a8 100644 --- a/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -1289,17 +1289,23 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,    if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); -  if (mode) -    return gpg_error (GPG_ERR_NOT_SUPPORTED); -    if (!pattern)      pattern = ""; -  cmd = malloc (7 + strlen (pattern) + 1); +  cmd = malloc (7 + 9 + 9 + strlen (pattern) + 1);    if (!cmd)      return gpg_error_from_syserror (); +    strcpy (cmd, "EXPORT "); -  strcpy (&cmd[7], pattern); +  if ((mode & GPGME_EXPORT_MODE_SECRET)) +    { +      strcat (cmd, "--secret "); +      if ((mode & GPGME_EXPORT_MODE_RAW)) +        strcat (cmd, "--raw "); +      else if ((mode & GPGME_EXPORT_MODE_PKCS12)) +        strcat (cmd, "--pkcs12 "); +    } +  strcat (cmd, pattern);    gpgsm->output_cb.data = keydata;    err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor" @@ -1323,16 +1329,13 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,    engine_gpgsm_t gpgsm = engine;    gpgme_error_t err = 0;    char *line; -  /* Length is "EXPORT " + p + '\0'.  */ -  int length = 7 + 1; +  /* Length is "EXPORT " + "--secret " + "--pkcs12 " + p + '\0'.  */ +  int length = 7 + 9 + 9 + 1;    char *linep;    if (!gpgsm)      return gpg_error (GPG_ERR_INV_VALUE); -  if (mode) -    return gpg_error (GPG_ERR_NOT_SUPPORTED); -    if (pattern && *pattern)      {        const char **pat = pattern; @@ -1357,7 +1360,15 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,      return gpg_error_from_syserror ();    strcpy (line, "EXPORT "); -  linep = &line[7]; +  if ((mode & GPGME_EXPORT_MODE_SECRET)) +    { +      strcat (line, "--secret "); +      if ((mode & GPGME_EXPORT_MODE_RAW)) +        strcat (line, "--raw "); +      else if ((mode & GPGME_EXPORT_MODE_PKCS12)) +        strcat (line, "--pkcs12 "); +    } +  linep = &line[strlen (line)];    if (pattern && *pattern)      { diff --git a/src/export.c b/src/export.c index 8930aa68..a29fbde8 100644 --- a/src/export.c +++ b/src/export.c @@ -120,9 +120,24 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,    op_data_t opd;    if ((mode & ~(GPGME_EXPORT_MODE_EXTERN -                |GPGME_EXPORT_MODE_MINIMAL))) +                |GPGME_EXPORT_MODE_MINIMAL +                |GPGME_EXPORT_MODE_SECRET +                |GPGME_EXPORT_MODE_RAW +                |GPGME_EXPORT_MODE_PKCS12)))      return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */ +  if ((mode & GPGME_EXPORT_MODE_SECRET)) +    { +      if ((mode & GPGME_EXPORT_MODE_EXTERN)) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Combination not allowed. */ +      if ((mode & GPGME_EXPORT_MODE_RAW) +          && (mode & GPGME_EXPORT_MODE_PKCS12)) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Combination not allowed. */ + +      if (ctx->protocol != GPGME_PROTOCOL_CMS +          && (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12))) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Only supported for X.509.  */ +    }    if ((mode & GPGME_EXPORT_MODE_EXTERN))      { @@ -199,9 +214,25 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],    op_data_t opd;    if ((mode & ~(GPGME_EXPORT_MODE_EXTERN -                |GPGME_EXPORT_MODE_MINIMAL))) +                |GPGME_EXPORT_MODE_MINIMAL +                |GPGME_EXPORT_MODE_SECRET +                |GPGME_EXPORT_MODE_RAW +                |GPGME_EXPORT_MODE_PKCS12)))      return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE.  */ +  if ((mode & GPGME_EXPORT_MODE_SECRET)) +    { +      if ((mode & GPGME_EXPORT_MODE_EXTERN)) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Combination not allowed. */ +      if ((mode & GPGME_EXPORT_MODE_RAW) +          && (mode & GPGME_EXPORT_MODE_PKCS12)) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Combination not allowed. */ + +      if (ctx->protocol != GPGME_PROTOCOL_CMS +          && (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12))) +        return gpg_error (GPG_ERR_INV_FLAG);  /* Only supported for X.509.  */ +    } +    if ((mode & GPGME_EXPORT_MODE_EXTERN))      {        if (keydata) diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c index 94d11248..e5e57073 100644 --- a/src/gpgme-tool.c +++ b/src/gpgme-tool.c @@ -3054,7 +3054,7 @@ cmd_import (assuan_context_t ctx, char *line)  static const char hlp_export[] = -  "EXPORT [--extern] [--minimal] [<pattern>]\n" +  "EXPORT [--extern] [--minimal] [--secret [--pkcs12] [--raw]] [<pattern>]\n"    "\n"    "Export the keys described by PATTERN.  Write the\n"    "the output to the object set by the last OUTPUT command."; @@ -3082,6 +3082,12 @@ cmd_export (assuan_context_t ctx, char *line)      mode |= GPGME_EXPORT_MODE_EXTERN;    if (has_option (line, "--minimal"))      mode |= GPGME_EXPORT_MODE_MINIMAL; +  if (has_option (line, "--secret")) +    mode |= GPGME_EXPORT_MODE_SECRET; +  if (has_option (line, "--raw")) +    mode |= GPGME_EXPORT_MODE_RAW; +  if (has_option (line, "--pkcs12")) +    mode |= GPGME_EXPORT_MODE_PKCS12;    line = skip_options (line); diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 8255e637..76055708 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -392,6 +392,9 @@ gpgme_pinentry_mode_t;  /* The available export mode flags.  */  #define GPGME_EXPORT_MODE_EXTERN                2  #define GPGME_EXPORT_MODE_MINIMAL               4 +#define GPGME_EXPORT_MODE_SECRET               16 +#define GPGME_EXPORT_MODE_RAW                  32 +#define GPGME_EXPORT_MODE_PKCS12               64  typedef unsigned int gpgme_export_mode_t; diff --git a/tests/run-export.c b/tests/run-export.c index 43332087..b133f130 100644 --- a/tests/run-export.c +++ b/tests/run-export.c @@ -43,7 +43,12 @@ show_usage (int ex)    fputs ("usage: " PGM " [options] USERIDS\n\n"           "Options:\n"           "  --verbose        run in verbose mode\n" +         "  --openpgp        use OpenPGP protocol (default)\n" +         "  --cms            use X.509 protocol\n"           "  --extern         send keys to the keyserver (TAKE CARE!)\n" +         "  --secret         export secret keys instead of public keys\n" +         "  --raw            use PKCS#1 as secret key format\n" +         "  --pkcs12         use PKCS#12 as secret key format\n"           , stderr);    exit (ex);  } @@ -59,6 +64,7 @@ main (int argc, char **argv)    gpgme_key_t keyarray[100];    int keyidx = 0;    gpgme_data_t out; +  gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;    gpgme_export_mode_t mode = 0;    if (argc) @@ -79,9 +85,34 @@ main (int argc, char **argv)            verbose = 1;            argc--; argv++;          } +      else if (!strcmp (*argv, "--openpgp")) +        { +          protocol = GPGME_PROTOCOL_OpenPGP; +          argc--; argv++; +        } +      else if (!strcmp (*argv, "--cms")) +        { +          protocol = GPGME_PROTOCOL_CMS; +          argc--; argv++; +        }        else if (!strcmp (*argv, "--extern"))          { -          mode |= GPGME_KEYLIST_MODE_EXTERN; +          mode |= GPGME_EXPORT_MODE_EXTERN; +          argc--; argv++; +        } +      else if (!strcmp (*argv, "--secret")) +        { +          mode |= GPGME_EXPORT_MODE_SECRET; +          argc--; argv++; +        } +      else if (!strcmp (*argv, "--raw")) +        { +          mode |= GPGME_EXPORT_MODE_RAW; +          argc--; argv++; +        } +      else if (!strcmp (*argv, "--pkcs12")) +        { +          mode |= GPGME_EXPORT_MODE_PKCS12;            argc--; argv++;          }        else if (!strncmp (*argv, "--", 2)) @@ -92,11 +123,11 @@ main (int argc, char **argv)    if (!argc)      show_usage (1); -  init_gpgme (GPGME_PROTOCOL_OpenPGP); +  init_gpgme (protocol);    err = gpgme_new (&ctx);    fail_if_err (err); -  gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); +  gpgme_set_protocol (ctx, protocol);    /* Lookup the keys.  */    err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0); @@ -131,8 +162,10 @@ main (int argc, char **argv)      }    /* Now for the actual export.  */ -  if ((mode & GPGME_KEYLIST_MODE_EXTERN)) +  if ((mode & GPGME_EXPORT_MODE_EXTERN))      printf ("sending keys to keyserver\n"); +  if ((mode & GPGME_EXPORT_MODE_SECRET)) +    printf ("exporting secret keys!\n");    err = gpgme_data_new (&out);    fail_if_err (err); | 
