1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

We have reached a state where we are able to import certs and

check the certification path.
This commit is contained in:
Werner Koch 2001-11-13 12:50:14 +00:00
parent 6dec3847d8
commit 90d060c199
25 changed files with 2486 additions and 731 deletions

View file

@ -39,25 +39,29 @@ The first record of a plain KBX file has a special format:
byte pgp_completes ditto.
byte pgp_cert_depth ditto.
The OpenPGP KBX Blob looks like this:
The OpenPGP and X.509 blob are verry similiar, things which are
X.509 specific are noted like [X.509: xxx]
u32 length of this blob (including these 4 bytes)
byte Blob type (2)
byte Blob type (2) [X509: 3]
byte version number of this blob type (1)
u16 Blob flags
bit 0 = contains secret key material
u32 offset to the OpenPGP keyblock
u32 length of the keyblock
u16 number of keys (at least 1!)
u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
u32 ant its length
u16 number of keys (at least 1!) [X509: always 1]
u16 size of additional key information
n times:
b20 The keys fingerprint
(fingerprints are always 20 bytes, MD5 left padded with zeroes)
u32 offset to the n-th key's keyID (a keyID is always 8 byte)
or 0 if not known which is the case opnly for X509.
u16 special key flags
bit 0 =
u16 reserved
u16 size of serialnumber(may be zero)
n u16 (see above) bytes of serial number
u16 number of user IDs
u16 size of additional user ID information
n times:
@ -67,6 +71,8 @@ The OpenPGP KBX Blob looks like this:
bit 0 =
byte validity
byte reserved
[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)
u32 expiration time of signature with some special values:
@ -75,8 +81,8 @@ The OpenPGP KBX Blob looks like this:
0x00000002 = bad signature
0x10000000 = valid and expires at some date in 1978.
0xffffffff = valid and does not expire
u8 assigned ownertrust
u8 all_validity
u8 assigned ownertrust [X509: no used]
u8 all_validity [X509: no used]
u16 reserved
u32 recheck_after
u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
@ -90,7 +96,9 @@ The OpenPGP KBX Blob looks like this:
maybe we put a signature here later.
b16 MD5 checksum (useful for KS syncronisation)
b16 MD5 checksum (useful for KS syncronisation), we might also want to use
a mac here.
b4 resevered
*/
@ -103,8 +111,17 @@ The OpenPGP KBX Blob looks like this:
#include <assert.h>
#include <gcrypt.h>
#ifdef KEYBOX_WITH_OPENPGP
/* include stuff to parse the packets */
#endif
#ifdef KEYBOX_WITH_X509
#include <ksba.h>
#endif
#include "keybox-defs.h"
/* special values of the signature status */
#define SF_NONE(a) ( !(a) )
#define SF_NOKEY(a) ((a) & (1<<0))
@ -125,16 +142,17 @@ struct membuf {
/* #endif */
struct keyboxblob_key {
char fpr[20];
u32 off_kid;
ulong off_kid_addr;
u16 flags;
char fpr[20];
u32 off_kid;
ulong off_kid_addr;
u16 flags;
};
struct keyboxblob_uid {
ulong off_addr;
u32 len;
u16 flags;
byte validity;
ulong off_addr;
char *name; /* used only with x509 */
u32 len;
u16 flags;
byte validity;
};
struct keyid_list {
@ -155,6 +173,8 @@ struct keyboxblob {
size_t bloblen;
/* stuff used only by keybox_create_blob */
unsigned char *serial;
size_t seriallen;
int nkeys;
struct keyboxblob_key *keys;
int nuids;
@ -162,9 +182,11 @@ struct keyboxblob {
int nsigs;
u32 *sigs;
struct fixup_list *fixups;
int fixup_out_of_core;
struct keyid_list *temp_kids;
struct membuf *buf; /* temporary store for the blob */
struct membuf bufbuf; /* temporary store for the blob */
struct membuf *buf;
};
@ -255,6 +277,28 @@ put32 (struct membuf *mb, u32 a )
put_membuf (mb, tmp, 4);
}
/* Store a value in the fixup list */
static void
add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
{
struct fixup_list *fl;
if (blob->fixup_out_of_core)
return;
fl = xtrycalloc(1, sizeof *fl);
if (!fl)
blob->fixup_out_of_core = 1;
else
{
fl->off = off;
fl->val = val;
fl->next = blob->fixups;
blob->fixups = fl;
}
}
/*
Some wrappers
@ -396,16 +440,7 @@ pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
int n;
u32 kbstart = a->len;
{
struct fixup_list *fl = xtrycalloc(1, sizeof *fl );
if (!fl)
return KEYBOX_Out_Of_Core;
fl->off = 8;
fl->val = kbstart;
fl->next = blob->fixups;
blob->fixups = fl;
}
add_fixup (blob, kbstart);
for (n = 0, node = keyblock; node; node = node->next)
{
@ -420,28 +455,16 @@ pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
PKT_user_id *u = node->pkt->pkt.user_id;
/* build_packet has set the offset of the name into u ;
* now we can do the fixup */
struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
fl->off = blob->uids[n].off_addr;
fl->val = u->stored_at;
fl->next = blob->fixups;
blob->fixups = fl;
add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
n++;
}
}
assert (n == blob->nuids);
{
struct fixup_list *fl = xcalloc(1, sizeof *fl ); /* fixme */
fl->off = 12;
fl->val = a->len - kbstart;
fl->next = blob->fixups;
blob->fixups = fl;
}
add_fixup (blob, a->len - kbstart);
return 0;
}
#endif /*KEYBOX_WITH_OPENPGP*/
@ -450,6 +473,27 @@ pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
X.509 specific stuff
*/
/* Write the raw certificate out */
static int
x509_create_blob_cert (KEYBOXBLOB blob, KsbaCert cert)
{
struct membuf *a = blob->buf;
const unsigned char *image;
size_t length;
u32 kbstart = a->len;
/* Store our offset for later fixup */
add_fixup (blob, 8, kbstart);
image = ksba_cert_get_image (cert, &length);
if (!image)
return KEYBOX_General_Error;
put_membuf (a, image, length);
add_fixup (blob, 12, a->len - kbstart);
return 0;
}
#endif /*KEYBOX_WITH_X509*/
/* Write a stored keyID out to the buffer */
@ -509,6 +553,10 @@ create_blob_header (KEYBOXBLOB blob, int blobtype)
put16 ( a, 0 ); /* reserved */
}
put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
if (blob->serial)
put_membuf (a, blob->serial+4, blob->seriallen);
put16 ( a, blob->nuids );
put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
for (i=0; i < blob->nuids; i++)
@ -537,31 +585,42 @@ create_blob_header (KEYBOXBLOB blob, int blobtype)
put32 ( a, 0 ); /* size of reserved space */
/* reserved space (which is currently of size 0) */
/* We need to store the keyids for all pgp v3 keys because those key
IDs are not part of the fingerprint. While we are doing that, we
fixup all the keyID offsets */
for (i=0; i < blob->nkeys; i++ )
/* space where we write keyIDs and and other stuff so that the
pointers can actually point to somewhere */
if (blobtype == BLOBTYPE_PGP)
{
struct fixup_list *fl = xtrycalloc(1, sizeof *fl );
if (!fl)
return KEYBOX_Out_Of_Core;
fl->off = blob->keys[i].off_kid_addr;
fl->next = blob->fixups;
blob->fixups = fl;
if (blob->keys[i].off_kid)
{ /* this is a v3 one */
fl->val = a->len;
write_stored_kid (blob, blob->keys[i].off_kid);
}
else
{ /* the better v4 key IDs - just store an offset 8 bytes back */
fl->val = blob->keys[i].off_kid_addr - 8;
}
/* We need to store the keyids for all pgp v3 keys because those key
IDs are not part of the fingerprint. While we are doing that, we
fixup all the keyID offsets */
for (i=0; i < blob->nkeys; i++ )
{
if (blob->keys[i].off_kid)
{ /* this is a v3 one */
add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
write_stored_kid (blob, blob->keys[i].off_kid);
}
else
{ /* the better v4 key IDs - just store an offset 8 bytes back */
add_fixup (blob, blob->keys[i].off_kid_addr,
blob->keys[i].off_kid_addr - 8);
}
}
}
if (blobtype == BLOBTYPE_X509)
{
/* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
the utf-8 string represenation of them */
for (i=0; i < blob->nuids; i++ )
{
if (blob->uids[i].name)
{ /* this is a v3 one */
add_fixup (blob, blob->uids[i].off_addr, a->len);
put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
}
}
}
return 0;
}
@ -585,25 +644,21 @@ create_blob_finish (KEYBOXBLOB blob)
/* write a placeholder for the checksum */
for (i = 0; i < 16; i++ )
put32 (a, 0);
put32 (a, 0); /* Hmmm: why put32() ?? */
/* get the memory area */
p = a->buf;
n = a->len;
p = get_membuf (a, &n);
if (!p)
return KEYBOX_Out_Of_Core;
assert (n >= 20);
/* fixup the length */
{
struct fixup_list *fl = xtrycalloc(1, sizeof *fl);
if (!fl)
return KEYBOX_Out_Of_Core;
fl->off = 0;
fl->val = n;
fl->next = blob->fixups;
blob->fixups = fl;
}
add_fixup (blob, 0, n);
/* do the fixups */
if (blob->fixup_out_of_core)
return KEYBOX_Out_Of_Core;
{
struct fixup_list *fl;
for (fl = blob->fixups; fl; fl = fl->next)
@ -680,7 +735,8 @@ _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
if (rc)
goto leave;
init_membuf (blob->buf, 1024);
init_membuf (&blob->bufbuf, 1024);
blob->buf = &blob->bufbuf;
rc = create_blob_header (blob, BLOBTYPE_OPENPGP);
if (rc)
goto leave;
@ -711,6 +767,101 @@ _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
}
#endif /*KEYBOX_WITH_OPENPGP*/
#ifdef KEYBOX_WITH_X509
/* 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)
{
int rc = 0;
KEYBOXBLOB blob;
unsigned char *p;
*r_blob = NULL;
blob = xtrycalloc (1, sizeof *blob);
if( !blob )
return KEYBOX_Out_Of_Core;
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;
blob->serial = p;
}
blob->nkeys = 1;
blob->nuids = 2; /* issuer and subject - fixme: count alternate names */
blob->nsigs = 1;
blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
if (!blob->keys || !blob->uids || !blob->sigs)
{
rc = KEYBOX_Out_Of_Core;
goto leave;
}
memcpy (blob->keys[0].fpr, sha1_digest, 20);
blob->keys[0].off_kid = 0; /* We don't have keyids */
blob->keys[0].flags = 0;
/* issuer */
p = ksba_cert_get_issuer (cert);
blob->uids[0].name = p;
blob->uids[0].len = p? (strlen(p)+1):0;
blob->uids[0].flags = 0;
blob->uids[0].validity = 0;
/* subject */
p = ksba_cert_get_subject (cert);
blob->uids[1].name = p;
blob->uids[1].len = p? (strlen(p)+1):0;
blob->uids[1].flags = 0;
blob->uids[1].validity = 0;
/* fixme: add alternate names */
/* signatures */
blob->sigs[0] = 0; /* not yet checked */
/* Create a temporary buffer for further processing */
init_membuf (&blob->bufbuf, 1024);
blob->buf = &blob->bufbuf;
/* write out what we already have */
rc = create_blob_header (blob, BLOBTYPE_X509);
if (rc)
goto leave;
rc = x509_create_blob_cert (blob, cert);
if (rc)
goto leave;
rc = create_blob_trailer (blob);
if (rc)
goto leave;
rc = create_blob_finish ( blob );
if (rc)
goto leave;
leave:
release_kid_list (blob->temp_kids);
blob->temp_kids = NULL;
if (rc)
{
_keybox_release_blob (blob);
*r_blob = NULL;
}
else
{
*r_blob = blob;
}
return rc;
}
#endif /*KEYBOX_WITH_X509*/
int
@ -732,11 +883,14 @@ _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
void
_keybox_release_blob (KEYBOXBLOB blob)
{
int i;
if (!blob)
return;
/* if (blob->buf) */
/* iobuf_cancel( blob->buf ); */
/* hmmm: release membuf here?*/
xfree (blob->keys );
xfree (blob->serial);
for (i=0; i < blob->nuids; i++)
xfree (blob->uids[i].name);
xfree (blob->uids );
xfree (blob->sigs );
xfree (blob->blob );
@ -751,5 +905,3 @@ _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
*n = blob->bloblen;
return blob->blob;
}