aboutsummaryrefslogtreecommitdiffstats
path: root/agent/minip12.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agent/minip12.c71
1 files changed, 65 insertions, 6 deletions
diff --git a/agent/minip12.c b/agent/minip12.c
index d6029f7b0..6958e5e1d 100644
--- a/agent/minip12.c
+++ b/agent/minip12.c
@@ -28,11 +28,11 @@
#include <assert.h>
#include <gcrypt.h>
#include <iconv.h>
+#include <errno.h>
#ifdef TEST
#include <sys/stat.h>
#include <unistd.h>
-#include <errno.h>
#endif
#include "../jnlib/logging.h"
@@ -518,6 +518,10 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length,
"ISO-8859-8",
"ISO-8859-9",
"KOI8-R",
+ "IBM437",
+ "IBM850",
+ "EUC-JP",
+ "BIG5",
NULL
};
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
- PW. Create a PKCS structure from it and return it as well as the
- length in R_LENGTH; return NULL in case of an error. */
+/* Expect the RSA key parameters in KPARMS and a password in PW.
+ Create a PKCS structure from it and return it as well as the length
+ in R_LENGTH; return NULL in case of an error. If CHARSET is not
+ NULL, re-encode PW to that character set. */
unsigned char *
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;
char salt[8];
struct buffer_s seqlist[3];
int seqlistidx = 0;
unsigned char sha1hash[20];
char keyidstr[8+1];
+ char *pwbuf = NULL;
+ size_t pwbufsize = 0;
n = buflen = 0; /* (avoid compiler warning). */
memset (sha1hash, 0, 20);
*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)
{
/* 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);
failure:
+ if (pwbuf)
+ {
+ wipememory (pwbuf, pwbufsize);
+ gcry_free (pwbuf);
+ }
for ( ; seqlistidx; seqlistidx--)
gcry_free (seqlist[seqlistidx].buffer);