mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
Allow setting of the passphrase encoding of pkcs#12 files.
New option --p12-charset.
This commit is contained in:
parent
083010a53d
commit
fd628ffda1
2
NEWS
2
NEWS
@ -5,7 +5,7 @@ Noteworthy changes in version 2.0.4
|
|||||||
without the funopen/fopencookie API.
|
without the funopen/fopencookie API.
|
||||||
|
|
||||||
* PKCS#12 import now tries several encodings in case the passphrase
|
* PKCS#12 import now tries several encodings in case the passphrase
|
||||||
was not utf-8 encoded.
|
was not utf-8 encoded. New option --p12-charset for gpgsm.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 2.0.3 (2007-03-08)
|
Noteworthy changes in version 2.0.3 (2007-03-08)
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2007-03-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* protect-tool.c: New option --p12-charset.
|
||||||
|
* minip12.c (p12_build): Implement it.
|
||||||
|
|
||||||
2007-03-19 Werner Koch <wk@g10code.com>
|
2007-03-19 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* minip12.c: Include iconv.h.
|
* minip12.c: Include iconv.h.
|
||||||
|
@ -28,11 +28,11 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <gcrypt.h>
|
#include <gcrypt.h>
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../jnlib/logging.h"
|
#include "../jnlib/logging.h"
|
||||||
@ -518,6 +518,10 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
|
|||||||
"ISO-8859-8",
|
"ISO-8859-8",
|
||||||
"ISO-8859-9",
|
"ISO-8859-9",
|
||||||
"KOI8-R",
|
"KOI8-R",
|
||||||
|
"IBM437",
|
||||||
|
"IBM850",
|
||||||
|
"EUC-JP",
|
||||||
|
"BIG5",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
int charsetidx = 0;
|
int charsetidx = 0;
|
||||||
@ -2139,25 +2143,75 @@ build_cert_sequence (unsigned char *buffer, size_t buflen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Expect the RSA key parameters in KPARMS and a password in
|
/* Expect the RSA key parameters in KPARMS and a password in PW.
|
||||||
PW. Create a PKCS structure from it and return it as well as the
|
Create a PKCS structure from it and return it as well as the length
|
||||||
length in R_LENGTH; return NULL in case of an error. */
|
in R_LENGTH; return NULL in case of an error. If CHARSET is not
|
||||||
|
NULL, re-encode PW to that character set. */
|
||||||
unsigned char *
|
unsigned char *
|
||||||
p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
|
p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
|
||||||
const char *pw, size_t *r_length)
|
const char *pw, const char *charset, size_t *r_length)
|
||||||
{
|
{
|
||||||
unsigned char *buffer;
|
unsigned char *buffer = NULL;
|
||||||
size_t n, buflen;
|
size_t n, buflen;
|
||||||
char salt[8];
|
char salt[8];
|
||||||
struct buffer_s seqlist[3];
|
struct buffer_s seqlist[3];
|
||||||
int seqlistidx = 0;
|
int seqlistidx = 0;
|
||||||
unsigned char sha1hash[20];
|
unsigned char sha1hash[20];
|
||||||
char keyidstr[8+1];
|
char keyidstr[8+1];
|
||||||
|
char *pwbuf = NULL;
|
||||||
|
size_t pwbufsize = 0;
|
||||||
|
|
||||||
n = buflen = 0; /* (avoid compiler warning). */
|
n = buflen = 0; /* (avoid compiler warning). */
|
||||||
memset (sha1hash, 0, 20);
|
memset (sha1hash, 0, 20);
|
||||||
*keyidstr = 0;
|
*keyidstr = 0;
|
||||||
|
|
||||||
|
if (charset && pw && *pw)
|
||||||
|
{
|
||||||
|
iconv_t cd;
|
||||||
|
const char *inptr;
|
||||||
|
char *outptr;
|
||||||
|
size_t inbytes, outbytes;
|
||||||
|
|
||||||
|
/* We assume that the converted passphrase is at max 2 times
|
||||||
|
longer than its utf-8 encoding. */
|
||||||
|
pwbufsize = strlen (pw)*2 + 1;
|
||||||
|
pwbuf = gcry_malloc_secure (pwbufsize);
|
||||||
|
if (!pwbuf)
|
||||||
|
{
|
||||||
|
log_error ("out of secure memory while converting passphrase\n");
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
cd = iconv_open (charset, "utf-8");
|
||||||
|
if (cd == (iconv_t)(-1))
|
||||||
|
{
|
||||||
|
log_error ("can't convert passphrase to"
|
||||||
|
" requested charset `%s': %s\n",
|
||||||
|
charset, strerror (errno));
|
||||||
|
gcry_free (pwbuf);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
inptr = pw;
|
||||||
|
inbytes = strlen (pw);
|
||||||
|
outptr = pwbuf;
|
||||||
|
outbytes = pwbufsize - 1;
|
||||||
|
if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
|
||||||
|
&outptr, &outbytes) == (size_t)-1)
|
||||||
|
{
|
||||||
|
log_error ("error converting passphrase to"
|
||||||
|
" requested charset `%s': %s\n",
|
||||||
|
charset, strerror (errno));
|
||||||
|
gcry_free (pwbuf);
|
||||||
|
iconv_close (cd);
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
*outptr = 0;
|
||||||
|
iconv_close (cd);
|
||||||
|
pw = pwbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cert && certlen)
|
if (cert && certlen)
|
||||||
{
|
{
|
||||||
/* Calculate the hash value we need for the bag attributes. */
|
/* Calculate the hash value we need for the bag attributes. */
|
||||||
@ -2219,6 +2273,11 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen,
|
|||||||
buffer = create_final (seqlist, pw, &buflen);
|
buffer = create_final (seqlist, pw, &buflen);
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
|
if (pwbuf)
|
||||||
|
{
|
||||||
|
wipememory (pwbuf, pwbufsize);
|
||||||
|
gcry_free (pwbuf);
|
||||||
|
}
|
||||||
for ( ; seqlistidx; seqlistidx--)
|
for ( ; seqlistidx; seqlistidx--)
|
||||||
gcry_free (seqlist[seqlistidx].buffer);
|
gcry_free (seqlist[seqlistidx].buffer);
|
||||||
|
|
||||||
|
@ -31,7 +31,8 @@ gcry_mpi_t *p12_parse (const unsigned char *buffer, size_t length,
|
|||||||
|
|
||||||
unsigned char *p12_build (gcry_mpi_t *kparms,
|
unsigned char *p12_build (gcry_mpi_t *kparms,
|
||||||
unsigned char *cert, size_t certlen,
|
unsigned char *cert, size_t certlen,
|
||||||
const char *pw, size_t *r_length);
|
const char *pw, const char *charset,
|
||||||
|
size_t *r_length);
|
||||||
|
|
||||||
|
|
||||||
#endif /*MINIP12_H*/
|
#endif /*MINIP12_H*/
|
||||||
|
@ -65,6 +65,7 @@ enum cmd_and_opt_values
|
|||||||
|
|
||||||
oP12Import,
|
oP12Import,
|
||||||
oP12Export,
|
oP12Export,
|
||||||
|
oP12Charset,
|
||||||
oStore,
|
oStore,
|
||||||
oForce,
|
oForce,
|
||||||
oHaveCert,
|
oHaveCert,
|
||||||
@ -96,6 +97,7 @@ static int opt_have_cert;
|
|||||||
static const char *opt_passphrase;
|
static const char *opt_passphrase;
|
||||||
static char *opt_prompt;
|
static char *opt_prompt;
|
||||||
static int opt_status_msg;
|
static int opt_status_msg;
|
||||||
|
static const char *opt_p12_charset;
|
||||||
|
|
||||||
static char *get_passphrase (int promptno, int opt_check);
|
static char *get_passphrase (int promptno, int opt_check);
|
||||||
static char *get_new_passphrase (int promptno);
|
static char *get_new_passphrase (int promptno);
|
||||||
@ -118,8 +120,10 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"},
|
{ oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"},
|
||||||
{ oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""},
|
{ oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""},
|
||||||
|
|
||||||
{ oP12Import, "p12-import", 256, "import a PKCS-12 encoded private key"},
|
{ oP12Import, "p12-import", 256, "import a pkcs#12 encoded private key"},
|
||||||
{ oP12Export, "p12-export", 256, "export a private key PKCS-12 encoded"},
|
{ oP12Export, "p12-export", 256, "export a private key pkcs#12 encoded"},
|
||||||
|
{ oP12Charset,"p12-charset", 2,
|
||||||
|
"|NAME|set charset for a new PKCS#12 passphrase to NAME" },
|
||||||
{ oHaveCert, "have-cert", 0, "certificate to export provided on STDIN"},
|
{ oHaveCert, "have-cert", 0, "certificate to export provided on STDIN"},
|
||||||
{ oStore, "store", 0, "store the created key in the appropriate place"},
|
{ oStore, "store", 0, "store the created key in the appropriate place"},
|
||||||
{ oForce, "force", 0, "force overwriting"},
|
{ oForce, "force", 0, "force overwriting"},
|
||||||
@ -127,6 +131,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oHomedir, "homedir", 2, "@" },
|
{ oHomedir, "homedir", 2, "@" },
|
||||||
{ oPrompt, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
|
{ oPrompt, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"},
|
||||||
{ oStatusMsg, "enable-status-msg", 0, "@"},
|
{ oStatusMsg, "enable-status-msg", 0, "@"},
|
||||||
|
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -987,7 +992,7 @@ export_p12_file (const char *fname)
|
|||||||
kparms[8] = NULL;
|
kparms[8] = NULL;
|
||||||
|
|
||||||
key = p12_build (kparms, cert, certlen,
|
key = p12_build (kparms, cert, certlen,
|
||||||
(pw=get_new_passphrase (3)), &keylen);
|
(pw=get_new_passphrase (3)), opt_p12_charset, &keylen);
|
||||||
release_passphrase (pw);
|
release_passphrase (pw);
|
||||||
xfree (cert);
|
xfree (cert);
|
||||||
for (i=0; i < 8; i++)
|
for (i=0; i < 8; i++)
|
||||||
@ -1101,6 +1106,7 @@ main (int argc, char **argv )
|
|||||||
case oShowKeygrip: cmd = oShowKeygrip; break;
|
case oShowKeygrip: cmd = oShowKeygrip; break;
|
||||||
case oP12Import: cmd = oP12Import; break;
|
case oP12Import: cmd = oP12Import; break;
|
||||||
case oP12Export: cmd = oP12Export; break;
|
case oP12Export: cmd = oP12Export; break;
|
||||||
|
case oP12Charset: opt_p12_charset = pargs.r.ret_str; break;
|
||||||
|
|
||||||
case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
|
case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
|
||||||
case oStore: opt_store = 1; break;
|
case oStore: opt_store = 1; break;
|
||||||
|
@ -233,11 +233,11 @@ a few informational lines are prepended before each block.
|
|||||||
|
|
||||||
@item --export-secret-key-p12 @var{key-id}
|
@item --export-secret-key-p12 @var{key-id}
|
||||||
@opindex export
|
@opindex export
|
||||||
Export the private key and the certificate identified by @var{key-id}
|
Export the private key and the certificate identified by @var{key-id} in
|
||||||
in a PKCS#12 format. When using along with the @code{--armor} option
|
a PKCS#12 format. When using along with the @code{--armor} option a few
|
||||||
a few informational lines are prepended to the output. Note, that the
|
informational lines are prepended to the output. Note, that the PKCS#12
|
||||||
PKCS#12 format is higly insecure and this command is only provided if
|
format is not very secure and this command is only provided if there is
|
||||||
there is no other way to exchange the private key.
|
no other way to exchange the private key. (@pxref{option --p12-charset})
|
||||||
|
|
||||||
@item --import [@var{files}]
|
@item --import [@var{files}]
|
||||||
@opindex import
|
@opindex import
|
||||||
@ -437,6 +437,19 @@ Assume the input data is plain base-64 encoded.
|
|||||||
@opindex assume-binary
|
@opindex assume-binary
|
||||||
Assume the input data is binary encoded.
|
Assume the input data is binary encoded.
|
||||||
|
|
||||||
|
@anchor{option --p12-charset}
|
||||||
|
@item --p12-charset @var{name}
|
||||||
|
@opindex p12-charset
|
||||||
|
@command{gpgsm} uses the UTF-8 encoding when encoding passphrases for
|
||||||
|
PKCS#12 files. This option may be used to force the passphrase to be
|
||||||
|
encoded in the specified encoding @var{name}. This is useful if the
|
||||||
|
application used to import the key uses a different encoding and thus
|
||||||
|
won't be able to import a file generated by @command{gpgsm}. Commonly
|
||||||
|
used values for @var{name} are @code{Latin1} and @code{CP850}. Note
|
||||||
|
that @command{gpgsm} itself automagically imports any file with a
|
||||||
|
passphrase encoded to the most commonly used encodings.
|
||||||
|
|
||||||
|
|
||||||
@item --local-user @var{user_id}
|
@item --local-user @var{user_id}
|
||||||
@item -u @var{user_id}
|
@item -u @var{user_id}
|
||||||
@opindex local-user
|
@opindex local-user
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2007-03-20 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpgsm.c: Add option --p12-charset.
|
||||||
|
* gpgsm.h (struct opt): Add p12_charset.
|
||||||
|
* export.c (popen_protect_tool): Use new option.
|
||||||
|
|
||||||
2007-03-19 Werner Koch <wk@g10code.com>
|
2007-03-19 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
Changes to let export and key listing use estream to help systems
|
Changes to let export and key listing use estream to help systems
|
||||||
|
11
sm/export.c
11
sm/export.c
@ -416,6 +416,12 @@ gpgsm_p12_export (ctrl_t ctrl, const char *name, FILE *fp)
|
|||||||
putc ('\n', fp);
|
putc ('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt.p12_charset)
|
||||||
|
{
|
||||||
|
fprintf (fp, "The passphrase is %s encoded.\n\n",
|
||||||
|
opt.p12_charset);
|
||||||
|
}
|
||||||
|
|
||||||
ctrl->pem_name = "PKCS12";
|
ctrl->pem_name = "PKCS12";
|
||||||
rc = gpgsm_create_writer (&b64writer, ctrl, fp, NULL, &writer);
|
rc = gpgsm_create_writer (&b64writer, ctrl, fp, NULL, &writer);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -567,6 +573,11 @@ popen_protect_tool (const char *pgmname,
|
|||||||
argv[i++] = "--prompt";
|
argv[i++] = "--prompt";
|
||||||
argv[i++] = prompt?prompt:"";
|
argv[i++] = prompt?prompt:"";
|
||||||
argv[i++] = "--enable-status-msg";
|
argv[i++] = "--enable-status-msg";
|
||||||
|
if (opt.p12_charset)
|
||||||
|
{
|
||||||
|
argv[i++] = "--p12-charset";
|
||||||
|
argv[i++] = opt.p12_charset;
|
||||||
|
}
|
||||||
argv[i++] = "--",
|
argv[i++] = "--",
|
||||||
argv[i++] = keygrip,
|
argv[i++] = keygrip,
|
||||||
argv[i] = NULL;
|
argv[i] = NULL;
|
||||||
|
11
sm/gpgsm.c
11
sm/gpgsm.c
@ -131,6 +131,7 @@ enum cmd_and_opt_values {
|
|||||||
|
|
||||||
oBase64,
|
oBase64,
|
||||||
oNoArmor,
|
oNoArmor,
|
||||||
|
oP12Charset,
|
||||||
|
|
||||||
oDisableCRLChecks,
|
oDisableCRLChecks,
|
||||||
oEnableCRLChecks,
|
oEnableCRLChecks,
|
||||||
@ -281,6 +282,8 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oArmor, "armour", 0, "@" },
|
{ oArmor, "armour", 0, "@" },
|
||||||
{ oBase64, "base64", 0, N_("create base-64 encoded output")},
|
{ oBase64, "base64", 0, N_("create base-64 encoded output")},
|
||||||
|
|
||||||
|
{ oP12Charset, "p12-charset", 2, "@" },
|
||||||
|
|
||||||
{ oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")},
|
{ oAssumeArmor, "assume-armor", 0, N_("assume input is in PEM format")},
|
||||||
{ oAssumeBase64, "assume-base64", 0,
|
{ oAssumeBase64, "assume-base64", 0,
|
||||||
N_("assume input is in base-64 format")},
|
N_("assume input is in base-64 format")},
|
||||||
@ -955,7 +958,7 @@ main ( int argc, char **argv)
|
|||||||
set_cmd (&cmd, pargs.r_opt);
|
set_cmd (&cmd, pargs.r_opt);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* output encoding selection */
|
/* Output encoding selection. */
|
||||||
case oArmor:
|
case oArmor:
|
||||||
ctrl.create_pem = 1;
|
ctrl.create_pem = 1;
|
||||||
break;
|
break;
|
||||||
@ -968,7 +971,11 @@ main ( int argc, char **argv)
|
|||||||
ctrl.create_base64 = 0;
|
ctrl.create_base64 = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Input encoding selection */
|
case oP12Charset:
|
||||||
|
opt.p12_charset = pargs.r.ret_str;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Input encoding selection. */
|
||||||
case oAssumeArmor:
|
case oAssumeArmor:
|
||||||
ctrl.autodetect_encoding = 0;
|
ctrl.autodetect_encoding = 0;
|
||||||
ctrl.is_pem = 1;
|
ctrl.is_pem = 1;
|
||||||
|
@ -74,6 +74,10 @@ struct
|
|||||||
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
int armor; /* force base64 armoring (see also ctrl.with_base64) */
|
||||||
int no_armor; /* don't try to figure out whether data is base64 armored*/
|
int no_armor; /* don't try to figure out whether data is base64 armored*/
|
||||||
|
|
||||||
|
const char *p12_charset; /* Use this charset for encoding the
|
||||||
|
pkcs#12 passphrase. */
|
||||||
|
|
||||||
|
|
||||||
const char *def_cipher_algoid; /* cipher algorithm to use if
|
const char *def_cipher_algoid; /* cipher algorithm to use if
|
||||||
nothing else is specified */
|
nothing else is specified */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user