/* keybox-blob.c - KBX Blob handling
- * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
byte version number of this blob type (1)
u16 Blob flags
bit 0 = contains secret key material
+ bit 1 = ephemeral blob (e.g. used while quering external resources)
u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
- u32 ant its length
+ u32 and its length
u16 number of keys (at least 1!) [X509: always 1]
u16 size of additional key information
n times:
bit 0 =
byte validity
byte reserved
- [For X509, the first user ID is the ISsuer, the second the subject
+ [For X509, the first user ID is the Issuer, the second the Subject
and the others are subjectAltNames]
u16 number of signatures
u16 size of signature information (4)
#include <string.h>
#include <errno.h>
#include <assert.h>
+#include <time.h>
+
+#include "keybox-defs.h"
#include <gcrypt.h>
#ifdef KEYBOX_WITH_OPENPGP
#include <ksba.h>
#endif
-#include "keybox-defs.h"
/* special values of the signature status */
struct keyboxblob {
byte *blob;
size_t bloblen;
+ off_t fileoffset;
/* stuff used only by keybox_create_blob */
- unsigned char *serial;
+ unsigned char *serialbuf;
+ const unsigned char *serial;
size_t seriallen;
int nkeys;
struct keyboxblob_key *keys;
\f
-/* A simple implemnation of a dynamic buffer. Use init_membuf() to
+/* A simple implemention of a dynamic buffer. Use init_membuf() to
create a buffer, put_membuf to append bytes and get_membuf to
release and return the buffer. Allocation errors are detected but
only returned at the final get_membuf(), this helps not to clutter
/* Write the raw certificate out */
static int
-x509_create_blob_cert (KEYBOXBLOB blob, KsbaCert cert)
+x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
{
struct membuf *a = blob->buf;
const unsigned char *image;
image = ksba_cert_get_image (cert, &length);
if (!image)
- return KEYBOX_General_Error;
+ return gpg_error (GPG_ERR_GENERAL);
put_membuf (a, image, length);
add_fixup (blob, 12, a->len - kbstart);
static int
-create_blob_header (KEYBOXBLOB blob, int blobtype)
+create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
{
struct membuf *a = blob->buf;
int i;
put32 ( a, 0 ); /* blob length, needs fixup */
put8 ( a, blobtype);
put8 ( a, 1 ); /* blob type version */
- put16 ( a, 0 ); /* blob flags */
+ put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
put32 ( a, 0 ); /* offset to the raw data, needs fixup */
put32 ( a, 0 ); /* length of the raw data, needs fixup */
put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
if (blob->serial)
- put_membuf (a, blob->serial+4, blob->seriallen);
+ put_membuf (a, blob->serial, blob->seriallen);
put16 ( a, blob->nuids );
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
/* get the memory area */
p = get_membuf (a, &n);
if (!p)
- return KEYBOX_Out_Of_Core;
+ return gpg_error (GPG_ERR_ENOMEM);
assert (n >= 20);
/* fixup the length */
/* do the fixups */
if (blob->fixup_out_of_core)
- return KEYBOX_Out_Of_Core;
+ return gpg_error (GPG_ERR_ENOMEM);
{
struct fixup_list *fl;
pp = xtrymalloc (n);
if ( !pp )
- return KEYBOX_Out_Of_Core;
+ return gpg_error (gpg_err_code_from_errno (errno));
memcpy (pp , p, n);
blob->blob = pp;
blob->bloblen = n;
#ifdef KEYBOX_WITH_OPENPGP
int
-_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
+_keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral)
{
int rc = 0;
KBNODE node;
*r_blob = NULL;
blob = xtrycalloc (1, sizeof *blob);
- if( !blob )
- return KEYBOX_Out_Of_Core;
+ if (!blob)
+ return gpg_error (gpg_err_code_from_errno (errno));
/* fixme: Do some sanity checks on the keyblock */
blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
if (!blob->keys || !blob->uids || !blob->sigs)
{
- rc = KEYBOX_Out_Of_Core;
+ rc = gpg_error (GPG_ERR_ENOMEM);
goto leave;
}
init_membuf (&blob->bufbuf, 1024);
blob->buf = &blob->bufbuf;
- rc = create_blob_header (blob, BLOBTYPE_OPENPGP);
+ rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral);
if (rc)
goto leave;
rc = pgp_create_blob_keyblock (blob, keyblock);
/* Note: We should move calculation of the digest into libksba and
remove that parameter */
int
-_keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
- unsigned char *sha1_digest)
+_keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
+ unsigned char *sha1_digest, int as_ephemeral)
{
int i, rc = 0;
KEYBOXBLOB blob;
*r_blob = NULL;
blob = xtrycalloc (1, sizeof *blob);
if( !blob )
- return KEYBOX_Out_Of_Core;
+ return gpg_error (gpg_err_code_from_errno (errno));
p = ksba_cert_get_serial (cert);
if (p)
{
- size_t n = (p[0] << 24) | (p[1] << 16) | (p[2] <<8) | p[3];
- blob->seriallen = n;
+ size_t n, len;
+ n = gcry_sexp_canon_len (p, 0, NULL, NULL);
+ if (n < 2)
+ {
+ xfree (p);
+ return gpg_error (GPG_ERR_GENERAL);
+ }
+ blob->serialbuf = p;
+ p++; n--; /* skip '(' */
+ for (len=0; n && *p && *p != ':' && digitp (p); n--, p++)
+ len = len*10 + atoi_1 (p);
+ if (*p != ':')
+ {
+ xfree (blob->serialbuf);
+ blob->serialbuf = NULL;
+ return gpg_error (GPG_ERR_GENERAL);
+ }
+ p++;
blob->serial = p;
+ blob->seriallen = len;
}
blob->nkeys = 1;
names = xtrymalloc (max_names * sizeof *names);
if (!names)
{
- rc = KEYBOX_Out_Of_Core;
+ rc = gpg_error (gpg_err_code_from_errno (errno));
goto leave;
}
p = ksba_cert_get_issuer (cert, 0);
if (!p)
{
- rc = KEYBOX_Missing_Value;
+ rc = gpg_error (GPG_ERR_MISSING_VALUE);
goto leave;
}
names[blob->nuids++] = p;
tmp = xtryrealloc (names, max_names * sizeof *names);
if (!tmp)
{
- rc = KEYBOX_Out_Of_Core;
+ rc = gpg_error (gpg_err_code_from_errno (errno));
goto leave;
}
}
blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
if (!blob->keys || !blob->uids || !blob->sigs)
{
- rc = KEYBOX_Out_Of_Core;
+ rc = gpg_error (GPG_ERR_ENOMEM);
goto leave;
}
init_membuf (&blob->bufbuf, 1024);
blob->buf = &blob->bufbuf;
/* write out what we already have */
- rc = create_blob_header (blob, BLOBTYPE_X509);
+ rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
if (rc)
goto leave;
rc = x509_create_blob_cert (blob, cert);
\f
int
-_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
+_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off)
{
KEYBOXBLOB blob;
*r_blob = NULL;
blob = xtrycalloc (1, sizeof *blob);
if (!blob)
- return KEYBOX_Out_Of_Core;
+ return gpg_error (gpg_err_code_from_errno (errno));
blob->blob = image;
blob->bloblen = imagelen;
+ blob->fileoffset = off;
*r_blob = blob;
return 0;
}
return;
/* hmmm: release membuf here?*/
xfree (blob->keys );
- xfree (blob->serial);
+ xfree (blob->serialbuf);
for (i=0; i < blob->nuids; i++)
xfree (blob->uids[i].name);
xfree (blob->uids );
const char *
_keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
{
- *n = blob->bloblen;
- return blob->blob;
+ *n = blob->bloblen;
+ return blob->blob;
+}
+
+off_t
+_keybox_get_blob_fileoffset (KEYBOXBLOB blob)
+{
+ return blob->fileoffset;
}
+