/* minip12.c - A minimal pkcs-12 implementation.
* Copyright (C) 2002, 2003, 2004, 2006, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2014 Werner Koch
*
* This file is part of GnuPG.
*
-- two bytes in INPUT.
Create a new buffer with the content of that octet string. INPUT
- is the orginal buffer with a length as stored at LENGTH. Returns
+ is the original buffer with a length as stored at LENGTH. Returns
NULL on error or a new malloced buffer with the length of this new
buffer stored at LENGTH and the number of bytes parsed from input
are added to the value stored at INPUT_CONSUMED. INPUT_CONSUMED is
}
*outptr = 0;
jnlib_iconv_close (cd);
- log_info ("decryption failed; trying charset `%s'\n",
+ log_info ("decryption failed; trying charset '%s'\n",
charsets[charsetidx]);
}
memcpy (plaintext, ciphertext, length);
unsigned char *plain = NULL;
int bad_pass = 0;
unsigned char *cram_buffer = NULL;
- size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
+ size_t consumed = 0; /* Number of bytes consumed from the original buffer. */
int is_3des = 0;
int is_pbes2 = 0;
gcry_mpi_t *result = NULL;
gcry_mpi_t *result = NULL;
int result_count, i;
unsigned char *cram_buffer = NULL;
- size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */
+ size_t consumed = 0; /* Number of bytes consumed from the original buffer. */
int is_pbes2 = 0;
where = "start";
}
}
}
+
+ MODE controls what is being generated:
+ 0 - As described above
+ 1 - Ditto but without the padding
+ 2 - Only the inner part (pkcs#1)
*/
static unsigned char *
-build_key_sequence (gcry_mpi_t *kparms, size_t *r_length)
+build_key_sequence (gcry_mpi_t *kparms, int mode, size_t *r_length)
{
int rc, i;
size_t needed, n;
size_t plainlen;
size_t outseqlen, oidseqlen, octstrlen, inseqlen;
- needed = 3; /* The version(?) integer of value 0. */
+ needed = 3; /* The version integer with value 0. */
for (i=0; kparms[i]; i++)
{
n = 0;
if (!n)
return NULL;
needed += n;
- /* Encapsulate all into an octet string. */
- octstrlen = needed;
- n = compute_tag_length (needed);
- if (!n)
- return NULL;
- needed += n;
- /* Prepend the object identifier sequence. */
- oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
- needed += 2 + oidseqlen;
- /* The version number. */
- needed += 3;
- /* And finally put the whole thing into a sequence. */
- outseqlen = needed;
- n = compute_tag_length (needed);
- if (!n)
- return NULL;
- needed += n;
+
+ if (mode != 2)
+ {
+ /* Encapsulate all into an octet string. */
+ octstrlen = needed;
+ n = compute_tag_length (needed);
+ if (!n)
+ return NULL;
+ needed += n;
+ /* Prepend the object identifier sequence. */
+ oidseqlen = 2 + DIM (oid_rsaEncryption) + 2;
+ needed += 2 + oidseqlen;
+ /* The version number. */
+ needed += 3;
+ /* And finally put the whole thing into a sequence. */
+ outseqlen = needed;
+ n = compute_tag_length (needed);
+ if (!n)
+ return NULL;
+ needed += n;
+ }
/* allocate 8 extra bytes for padding */
plain = gcry_malloc_secure (needed+8);
/* And now fill the plaintext buffer. */
p = plain;
- p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
- /* Store version. */
- *p++ = TAG_INTEGER;
- *p++ = 1;
- *p++ = 0;
- /* Store object identifier sequence. */
- p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
- p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
- memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
- p += DIM (oid_rsaEncryption);
- *p++ = TAG_NULL;
- *p++ = 0;
- /* Start with the octet string. */
- p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
+ if (mode != 2)
+ {
+ p = store_tag_length (p, TAG_SEQUENCE, outseqlen);
+ /* Store version. */
+ *p++ = TAG_INTEGER;
+ *p++ = 1;
+ *p++ = 0;
+ /* Store object identifier sequence. */
+ p = store_tag_length (p, TAG_SEQUENCE, oidseqlen);
+ p = store_tag_length (p, TAG_OBJECT_ID, DIM (oid_rsaEncryption));
+ memcpy (p, oid_rsaEncryption, DIM (oid_rsaEncryption));
+ p += DIM (oid_rsaEncryption);
+ *p++ = TAG_NULL;
+ *p++ = 0;
+ /* Start with the octet string. */
+ p = store_tag_length (p, TAG_OCTET_STRING, octstrlen);
+ }
+
p = store_tag_length (p, TAG_SEQUENCE, inseqlen);
/* Store the key parameters. */
*p++ = TAG_INTEGER;
plainlen = p - plain;
assert (needed == plainlen);
- /* Append some pad characters; we already allocated extra space. */
- n = 8 - plainlen % 8;
- for (i=0; i < n; i++, plainlen++)
- *p++ = n;
+
+ if (!mode)
+ {
+ /* Append some pad characters; we already allocated extra space. */
+ n = 8 - plainlen % 8;
+ for (i=0; i < n; i++, plainlen++)
+ *p++ = n;
+ }
*r_length = plainlen;
return plain;
if (cd == (jnlib_iconv_t)(-1))
{
log_error ("can't convert passphrase to"
- " requested charset `%s': %s\n",
+ " requested charset '%s': %s\n",
charset, strerror (errno));
- gcry_free (pwbuf);
goto failure;
}
&outptr, &outbytes) == (size_t)-1)
{
log_error ("error converting passphrase to"
- " requested charset `%s': %s\n",
+ " requested charset '%s': %s\n",
charset, strerror (errno));
- gcry_free (pwbuf);
jnlib_iconv_close (cd);
goto failure;
}
if (kparms)
{
/* Encode the key. */
- buffer = build_key_sequence (kparms, &buflen);
+ buffer = build_key_sequence (kparms, 0, &buflen);
if (!buffer)
goto failure;
failure:
if (pwbuf)
{
+ /* Note that wipememory is not really needed due to the use of
+ gcry_malloc_secure. */
wipememory (pwbuf, pwbufsize);
gcry_free (pwbuf);
}
}
+/* This is actually not a pkcs#12 function but one which creates an
+ unencrypted a pkcs#1 private key. */
+unsigned char *
+p12_raw_build (gcry_mpi_t *kparms, int rawmode, size_t *r_length)
+{
+ unsigned char *buffer;
+ size_t buflen;
+
+ assert (rawmode == 1 || rawmode == 2);
+ buffer = build_key_sequence (kparms, rawmode, &buflen);
+ if (!buffer)
+ return NULL;
+
+ *r_length = buflen;
+ return buffer;
+}
+
+
#ifdef TEST
static void
fp = fopen (argv[1], "rb");
if (!fp)
{
- fprintf (stderr, "can't open `%s': %s\n", argv[1], strerror (errno));
+ fprintf (stderr, "can't open '%s': %s\n", argv[1], strerror (errno));
return 1;
}
if (fstat (fileno(fp), &st))
{
- fprintf (stderr, "can't stat `%s': %s\n", argv[1], strerror (errno));
+ fprintf (stderr, "can't stat '%s': %s\n", argv[1], strerror (errno));
return 1;
}
buf = gcry_malloc (buflen+1);
if (!buf || fread (buf, buflen, 1, fp) != 1)
{
- fprintf (stderr, "error reading `%s': %s\n", argv[1], strerror (errno));
+ fprintf (stderr, "error reading '%s': %s\n", argv[1], strerror (errno));
return 1;
}
fclose (fp);