2002-04-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / kbx / keybox-blob.c
blob2c80a10ad2a8f93c4dad5e7d18b78e5725445a30
1 /* keybox-blob.c - KBX Blob handling
2 * Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 /* The keybox data formats
24 The KeyBox uses an augmented OpenPGP/X.509 key format. This makes
25 random access to a keyblock/Certificate easier and also gives the
26 opportunity to store additional information (e.g. the fingerprint)
27 along with the key. All integers are stored in network byte order,
28 offsets are counted from the beginning of the Blob.
30 The first record of a plain KBX file has a special format:
32 u32 length of the first record
33 byte Blob type (1)
34 byte version number (1)
35 byte reserved
36 byte reserved
37 u32 magic 'KBXf'
38 byte pgp_marginals used for validity calculation of this file
39 byte pgp_completes ditto.
40 byte pgp_cert_depth ditto.
42 The OpenPGP and X.509 blob are verry similiar, things which are
43 X.509 specific are noted like [X.509: xxx]
45 u32 length of this blob (including these 4 bytes)
46 byte Blob type (2) [X509: 3]
47 byte version number of this blob type (1)
48 u16 Blob flags
49 bit 0 = contains secret key material
51 u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
52 u32 ant its length
53 u16 number of keys (at least 1!) [X509: always 1]
54 u16 size of additional key information
55 n times:
56 b20 The keys fingerprint
57 (fingerprints are always 20 bytes, MD5 left padded with zeroes)
58 u32 offset to the n-th key's keyID (a keyID is always 8 byte)
59 or 0 if not known which is the case opnly for X509.
60 u16 special key flags
61 bit 0 =
62 u16 reserved
63 u16 size of serialnumber(may be zero)
64 n u16 (see above) bytes of serial number
65 u16 number of user IDs
66 u16 size of additional user ID information
67 n times:
68 u32 offset to the n-th user ID
69 u32 length of this user ID.
70 u16 special user ID flags.
71 bit 0 =
72 byte validity
73 byte reserved
74 [For X509, the first user ID is the ISsuer, the second the subject
75 and the others are subjectAltNames]
76 u16 number of signatures
77 u16 size of signature information (4)
78 u32 expiration time of signature with some special values:
79 0x00000000 = not checked
80 0x00000001 = missing key
81 0x00000002 = bad signature
82 0x10000000 = valid and expires at some date in 1978.
83 0xffffffff = valid and does not expire
84 u8 assigned ownertrust [X509: no used]
85 u8 all_validity [X509: no used]
86 u16 reserved
87 u32 recheck_after
88 u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
89 u32 Blob created at
90 u32 size of reserved space (not including this field)
91 reserved space
93 Here we might want to put other data
95 Here comes the keyblock
97 maybe we put a signature here later.
99 b16 MD5 checksum (useful for KS syncronisation), we might also want to use
100 a mac here.
101 b4 resevered
106 #include <config.h>
107 #include <stdio.h>
108 #include <stdlib.h>
109 #include <string.h>
110 #include <errno.h>
111 #include <assert.h>
112 #include <gcrypt.h>
114 #ifdef KEYBOX_WITH_OPENPGP
115 /* include stuff to parse the packets */
116 #endif
117 #ifdef KEYBOX_WITH_X509
118 #include <ksba.h>
119 #endif
121 #include "keybox-defs.h"
124 /* special values of the signature status */
125 #define SF_NONE(a) ( !(a) )
126 #define SF_NOKEY(a) ((a) & (1<<0))
127 #define SF_BAD(a) ((a) & (1<<1))
128 #define SF_VALID(a) ((a) & (1<<29))
131 struct membuf {
132 size_t len;
133 size_t size;
134 char *buf;
135 int out_of_core;
139 /* #if MAX_FINGERPRINT_LEN < 20 */
140 /* #error fingerprints are 20 bytes */
141 /* #endif */
143 struct keyboxblob_key {
144 char fpr[20];
145 u32 off_kid;
146 ulong off_kid_addr;
147 u16 flags;
149 struct keyboxblob_uid {
150 ulong off_addr;
151 char *name; /* used only with x509 */
152 u32 len;
153 u16 flags;
154 byte validity;
157 struct keyid_list {
158 struct keyid_list *next;
159 int seqno;
160 byte kid[8];
163 struct fixup_list {
164 struct fixup_list *next;
165 u32 off;
166 u32 val;
170 struct keyboxblob {
171 byte *blob;
172 size_t bloblen;
174 /* stuff used only by keybox_create_blob */
175 unsigned char *serialbuf;
176 const unsigned char *serial;
177 size_t seriallen;
178 int nkeys;
179 struct keyboxblob_key *keys;
180 int nuids;
181 struct keyboxblob_uid *uids;
182 int nsigs;
183 u32 *sigs;
184 struct fixup_list *fixups;
185 int fixup_out_of_core;
187 struct keyid_list *temp_kids;
188 struct membuf bufbuf; /* temporary store for the blob */
189 struct membuf *buf;
194 /* A simple implemnation of a dynamic buffer. Use init_membuf() to
195 create a buffer, put_membuf to append bytes and get_membuf to
196 release and return the buffer. Allocation errors are detected but
197 only returned at the final get_membuf(), this helps not to clutter
198 the code with out of core checks. */
200 static void
201 init_membuf (struct membuf *mb, int initiallen)
203 mb->len = 0;
204 mb->size = initiallen;
205 mb->out_of_core = 0;
206 mb->buf = xtrymalloc (initiallen);
207 if (!mb->buf)
208 mb->out_of_core = 1;
211 static void
212 put_membuf (struct membuf *mb, const void *buf, size_t len)
214 if (mb->out_of_core)
215 return;
217 if (mb->len + len >= mb->size)
219 char *p;
221 mb->size += len + 1024;
222 p = xtryrealloc (mb->buf, mb->size);
223 if (!p)
225 mb->out_of_core = 1;
226 return;
228 mb->buf = p;
230 memcpy (mb->buf + mb->len, buf, len);
231 mb->len += len;
234 static void *
235 get_membuf (struct membuf *mb, size_t *len)
237 char *p;
239 if (mb->out_of_core)
241 xfree (mb->buf);
242 mb->buf = NULL;
243 return NULL;
246 p = mb->buf;
247 *len = mb->len;
248 mb->buf = NULL;
249 mb->out_of_core = 1; /* don't allow a reuse */
250 return p;
254 static void
255 put8 (struct membuf *mb, byte a )
257 put_membuf (mb, &a, 1);
260 static void
261 put16 (struct membuf *mb, u16 a )
263 unsigned char tmp[2];
264 tmp[0] = a>>8;
265 tmp[1] = a;
266 put_membuf (mb, tmp, 2);
269 static void
270 put32 (struct membuf *mb, u32 a )
272 unsigned char tmp[4];
273 tmp[0] = a>>24;
274 tmp[1] = a>>16;
275 tmp[2] = a>>8;
276 tmp[3] = a;
277 put_membuf (mb, tmp, 4);
281 /* Store a value in the fixup list */
282 static void
283 add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
285 struct fixup_list *fl;
287 if (blob->fixup_out_of_core)
288 return;
290 fl = xtrycalloc(1, sizeof *fl);
291 if (!fl)
292 blob->fixup_out_of_core = 1;
293 else
295 fl->off = off;
296 fl->val = val;
297 fl->next = blob->fixups;
298 blob->fixups = fl;
304 Some wrappers
307 static u32
308 make_timestamp (void)
310 return time(NULL);
315 #ifdef KEYBOX_WITH_OPENPGP
317 OpenPGP specific stuff
322 We must store the keyid at some place because we can't calculate the
323 offset yet. This is only used for v3 keyIDs. Function returns an
324 index value for later fixup or -1 for out of core. The value must be
325 a non-zero value */
326 static int
327 pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
329 struct keyid_list *k, *r;
331 k = xtrymalloc (sizeof *k);
332 if (!k)
333 return -1;
334 k->kid[0] = pk->keyid[0] >> 24 ;
335 k->kid[1] = pk->keyid[0] >> 16 ;
336 k->kid[2] = pk->keyid[0] >> 8 ;
337 k->kid[3] = pk->keyid[0] ;
338 k->kid[4] = pk->keyid[0] >> 24 ;
339 k->kid[5] = pk->keyid[0] >> 16 ;
340 k->kid[6] = pk->keyid[0] >> 8 ;
341 k->kid[7] = pk->keyid[0] ;
342 k->seqno = 0;
343 k->next = blob->temp_kids;
344 blob->temp_kids = k;
345 for (r=k; r; r = r->next)
346 k->seqno++;
348 return k->seqno;
351 static int
352 pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
354 KBNODE node;
355 size_t fprlen;
356 int n;
358 for (n=0, node = keyblock; node; node = node->next)
360 if ( node->pkt->pkttype == PKT_PUBLIC_KEY
361 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
363 PKT_public_key *pk = node->pkt->pkt.public_key;
364 char tmp[20];
366 fingerprint_from_pk (pk, tmp , &fprlen);
367 memcpy (blob->keys[n].fpr, tmp, 20);
368 if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
370 assert (fprlen == 16);
371 memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
372 memset (blob->keys[n].fpr, 0, 4);
373 blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
375 else
377 blob->keys[n].off_kid = 0; /* will be fixed up later */
379 blob->keys[n].flags = 0;
380 n++;
382 else if ( node->pkt->pkttype == PKT_SECRET_KEY
383 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
385 never_reached (); /* actually not yet implemented */
388 assert (n == blob->nkeys);
389 return 0;
392 static int
393 pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
395 KBNODE node;
396 int n;
398 for (n=0, node = keyblock; node; node = node->next)
400 if (node->pkt->pkttype == PKT_USER_ID)
402 PKT_user_id *u = node->pkt->pkt.user_id;
404 blob->uids[n].len = u->len;
405 blob->uids[n].flags = 0;
406 blob->uids[n].validity = 0;
407 n++;
410 assert (n == blob->nuids);
411 return 0;
414 static int
415 pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
417 KBNODE node;
418 int n;
420 for (n=0, node = keyblock; node; node = node->next)
422 if (node->pkt->pkttype == PKT_SIGNATURE)
424 PKT_signature *sig = node->pkt->pkt.signature;
426 blob->sigs[n] = 0; /* FIXME: check the signature here */
427 n++;
430 assert( n == blob->nsigs );
431 return 0;
434 static int
435 pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
437 struct membuf *a = blob->buf;
438 KBNODE node;
439 int rc;
440 int n;
441 u32 kbstart = a->len;
443 add_fixup (blob, kbstart);
445 for (n = 0, node = keyblock; node; node = node->next)
447 rc = build_packet ( a, node->pkt );
448 if ( rc ) {
449 gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
450 node->pkt->pkttype, gpg_errstr(rc) );
451 return GPGERR_WRITE_FILE;
453 if ( node->pkt->pkttype == PKT_USER_ID )
455 PKT_user_id *u = node->pkt->pkt.user_id;
456 /* build_packet has set the offset of the name into u ;
457 * now we can do the fixup */
458 add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
459 n++;
462 assert (n == blob->nuids);
464 add_fixup (blob, a->len - kbstart);
465 return 0;
468 #endif /*KEYBOX_WITH_OPENPGP*/
471 #ifdef KEYBOX_WITH_X509
473 X.509 specific stuff
476 /* Write the raw certificate out */
477 static int
478 x509_create_blob_cert (KEYBOXBLOB blob, KsbaCert cert)
480 struct membuf *a = blob->buf;
481 const unsigned char *image;
482 size_t length;
483 u32 kbstart = a->len;
485 /* Store our offset for later fixup */
486 add_fixup (blob, 8, kbstart);
488 image = ksba_cert_get_image (cert, &length);
489 if (!image)
490 return KEYBOX_General_Error;
491 put_membuf (a, image, length);
493 add_fixup (blob, 12, a->len - kbstart);
494 return 0;
497 #endif /*KEYBOX_WITH_X509*/
499 /* Write a stored keyID out to the buffer */
500 static void
501 write_stored_kid (KEYBOXBLOB blob, int seqno)
503 struct keyid_list *r;
505 for ( r = blob->temp_kids; r; r = r->next )
507 if (r->seqno == seqno )
509 put_membuf (blob->buf, r->kid, 8);
510 return;
513 never_reached ();
516 /* Release a list of key IDs */
517 static void
518 release_kid_list (struct keyid_list *kl)
520 struct keyid_list *r, *r2;
522 for ( r = kl; r; r = r2 )
524 r2 = r->next;
525 xfree (r);
531 static int
532 create_blob_header (KEYBOXBLOB blob, int blobtype)
534 struct membuf *a = blob->buf;
535 int i;
537 put32 ( a, 0 ); /* blob length, needs fixup */
538 put8 ( a, blobtype);
539 put8 ( a, 1 ); /* blob type version */
540 put16 ( a, 0 ); /* blob flags */
542 put32 ( a, 0 ); /* offset to the raw data, needs fixup */
543 put32 ( a, 0 ); /* length of the raw data, needs fixup */
545 put16 ( a, blob->nkeys );
546 put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
547 for ( i=0; i < blob->nkeys; i++ )
549 put_membuf (a, blob->keys[i].fpr, 20);
550 blob->keys[i].off_kid_addr = a->len;
551 put32 ( a, 0 ); /* offset to keyid, fixed up later */
552 put16 ( a, blob->keys[i].flags );
553 put16 ( a, 0 ); /* reserved */
556 put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
557 if (blob->serial)
558 put_membuf (a, blob->serial, blob->seriallen);
560 put16 ( a, blob->nuids );
561 put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
562 for (i=0; i < blob->nuids; i++)
564 blob->uids[i].off_addr = a->len;
565 put32 ( a, 0 ); /* offset to userid, fixed up later */
566 put32 ( a, blob->uids[i].len );
567 put16 ( a, blob->uids[i].flags );
568 put8 ( a, 0 ); /* validity */
569 put8 ( a, 0 ); /* reserved */
572 put16 ( a, blob->nsigs );
573 put16 ( a, 4 ); /* size of sig info */
574 for (i=0; i < blob->nsigs; i++)
576 put32 ( a, blob->sigs[i]);
579 put8 ( a, 0 ); /* assigned ownertrust */
580 put8 ( a, 0 ); /* validity of all user IDs */
581 put16 ( a, 0 ); /* reserved */
582 put32 ( a, 0 ); /* time of next recheck */
583 put32 ( a, 0 ); /* newest timestamp (none) */
584 put32 ( a, make_timestamp() ); /* creation time */
585 put32 ( a, 0 ); /* size of reserved space */
586 /* reserved space (which is currently of size 0) */
588 /* space where we write keyIDs and and other stuff so that the
589 pointers can actually point to somewhere */
590 if (blobtype == BLOBTYPE_PGP)
592 /* We need to store the keyids for all pgp v3 keys because those key
593 IDs are not part of the fingerprint. While we are doing that, we
594 fixup all the keyID offsets */
595 for (i=0; i < blob->nkeys; i++ )
597 if (blob->keys[i].off_kid)
598 { /* this is a v3 one */
599 add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
600 write_stored_kid (blob, blob->keys[i].off_kid);
602 else
603 { /* the better v4 key IDs - just store an offset 8 bytes back */
604 add_fixup (blob, blob->keys[i].off_kid_addr,
605 blob->keys[i].off_kid_addr - 8);
610 if (blobtype == BLOBTYPE_X509)
612 /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
613 the utf-8 string represenation of them */
614 for (i=0; i < blob->nuids; i++ )
616 if (blob->uids[i].name)
617 { /* this is a v3 one */
618 add_fixup (blob, blob->uids[i].off_addr, a->len);
619 put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
624 return 0;
629 static int
630 create_blob_trailer (KEYBOXBLOB blob)
632 return 0;
636 static int
637 create_blob_finish (KEYBOXBLOB blob)
639 struct membuf *a = blob->buf;
640 byte *p;
641 char *pp;
642 int i;
643 size_t n;
645 /* write a placeholder for the checksum */
646 for (i = 0; i < 16; i++ )
647 put32 (a, 0); /* Hmmm: why put32() ?? */
649 /* get the memory area */
650 p = get_membuf (a, &n);
651 if (!p)
652 return KEYBOX_Out_Of_Core;
653 assert (n >= 20);
655 /* fixup the length */
656 add_fixup (blob, 0, n);
658 /* do the fixups */
659 if (blob->fixup_out_of_core)
660 return KEYBOX_Out_Of_Core;
663 struct fixup_list *fl;
664 for (fl = blob->fixups; fl; fl = fl->next)
666 assert (fl->off+4 <= n);
667 p[fl->off+0] = fl->val >> 24;
668 p[fl->off+1] = fl->val >> 16;
669 p[fl->off+2] = fl->val >> 8;
670 p[fl->off+3] = fl->val;
674 /* calculate and store the MD5 checksum */
675 gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
677 pp = xtrymalloc (n);
678 if ( !pp )
679 return KEYBOX_Out_Of_Core;
680 memcpy (pp , p, n);
681 blob->blob = pp;
682 blob->bloblen = n;
684 return 0;
688 #ifdef KEYBOX_WITH_OPENPGP
691 _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock)
693 int rc = 0;
694 KBNODE node;
695 KEYBOXBLOB blob;
697 *r_blob = NULL;
698 blob = xtrycalloc (1, sizeof *blob);
699 if( !blob )
700 return KEYBOX_Out_Of_Core;
702 /* fixme: Do some sanity checks on the keyblock */
704 /* count userids and keys so that we can allocate the arrays */
705 for (node = keyblock; node; node = node->next)
707 switch (node->pkt->pkttype)
709 case PKT_PUBLIC_KEY:
710 case PKT_SECRET_KEY:
711 case PKT_PUBLIC_SUBKEY:
712 case PKT_SECRET_SUBKEY: blob->nkeys++; break;
713 case PKT_USER_ID: blob->nuids++; break;
714 case PKT_SIGNATURE: blob->nsigs++; break;
715 default: break;
719 blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
720 blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
721 blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
722 if (!blob->keys || !blob->uids || !blob->sigs)
724 rc = KEYBOX_Out_Of_Core;
725 goto leave;
728 rc = pgp_create_key_part ( blob, keyblock );
729 if (rc)
730 goto leave;
731 rc = pgp_create_uid_part ( blob, keyblock );
732 if (rc)
733 goto leave;
734 rc = pgp_create_sig_part ( blob, keyblock );
735 if (rc)
736 goto leave;
738 init_membuf (&blob->bufbuf, 1024);
739 blob->buf = &blob->bufbuf;
740 rc = create_blob_header (blob, BLOBTYPE_OPENPGP);
741 if (rc)
742 goto leave;
743 rc = pgp_create_blob_keyblock (blob, keyblock);
744 if (rc)
745 goto leave;
746 rc = create_blob_trailer (blob);
747 if (rc)
748 goto leave;
749 rc = create_blob_finish ( blob );
750 if (rc)
751 goto leave;
754 leave:
755 release_kid_list (blob->temp_kids);
756 blob->temp_kids = NULL;
757 if (rc)
759 keybox_release_blob (blob);
760 *r_blob = NULL;
762 else
764 *r_blob = blob;
766 return rc;
768 #endif /*KEYBOX_WITH_OPENPGP*/
770 #ifdef KEYBOX_WITH_X509
772 /* return an allocated string with the email address extracted from a
773 DN */
774 static char *
775 x509_email_kludge (const char *name)
777 const unsigned char *p;
778 unsigned char *buf;
779 int n;
781 if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
782 return NULL;
783 /* This looks pretty much like an email address in the subject's DN
784 we use this to add an additional user ID entry. This way,
785 openSSL generated keys get a nicer and usable listing */
786 name += 22;
787 for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
789 if (*p != '#' || !n)
790 return NULL;
791 buf = xtrymalloc (n+3);
792 if (!buf)
793 return NULL; /* oops, out of core */
794 *buf = '<';
795 for (n=1, p=name; *p != '#'; p +=2, n++)
796 buf[n] = xtoi_2 (p);
797 buf[n++] = '>';
798 buf[n] = 0;
799 return buf;
804 /* Note: We should move calculation of the digest into libksba and
805 remove that parameter */
807 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
808 unsigned char *sha1_digest)
810 int i, rc = 0;
811 KEYBOXBLOB blob;
812 unsigned char *p;
813 unsigned char **names = NULL;
814 size_t max_names;
816 *r_blob = NULL;
817 blob = xtrycalloc (1, sizeof *blob);
818 if( !blob )
819 return KEYBOX_Out_Of_Core;
821 p = ksba_cert_get_serial (cert);
822 if (p)
824 size_t n, len;
825 n = gcry_sexp_canon_len (p, 0, NULL, NULL);
826 if (n < 2)
828 xfree (p);
829 return KEYBOX_General_Error;
831 blob->serialbuf = p;
832 p++; n--; /* skip '(' */
833 for (len=0; n && *p && *p != ':' && digitp (p); n--, p++)
834 len = len*10 + atoi_1 (p);
835 if (*p != ':')
837 xfree (blob->serialbuf);
838 blob->serialbuf = NULL;
839 return KEYBOX_General_Error;
841 p++;
842 blob->serial = p;
843 blob->seriallen = len;
846 blob->nkeys = 1;
848 /* create list of names */
849 blob->nuids = 0;
850 max_names = 100;
851 names = xtrymalloc (max_names * sizeof *names);
852 if (!names)
854 rc = KEYBOX_Out_Of_Core;
855 goto leave;
857 p = ksba_cert_get_issuer (cert, 0);
858 if (!p)
860 rc = KEYBOX_Missing_Value;
861 goto leave;
863 names[blob->nuids++] = p;
864 for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
867 if (blob->nuids >= max_names)
869 unsigned char **tmp;
871 max_names += 100;
872 tmp = xtryrealloc (names, max_names * sizeof *names);
873 if (!tmp)
875 rc = KEYBOX_Out_Of_Core;
876 goto leave;
879 names[blob->nuids++] = p;
880 if (!i && (p=x509_email_kludge (p)))
881 names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
884 /* space for signature information */
885 blob->nsigs = 1;
887 blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
888 blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
889 blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
890 if (!blob->keys || !blob->uids || !blob->sigs)
892 rc = KEYBOX_Out_Of_Core;
893 goto leave;
896 memcpy (blob->keys[0].fpr, sha1_digest, 20);
897 blob->keys[0].off_kid = 0; /* We don't have keyids */
898 blob->keys[0].flags = 0;
900 /* issuer and subject names */
901 for (i=0; i < blob->nuids; i++)
903 blob->uids[i].name = names[i];
904 blob->uids[i].len = strlen(names[i]);
905 names[i] = NULL;
906 blob->uids[i].flags = 0;
907 blob->uids[i].validity = 0;
909 xfree (names);
910 names = NULL;
912 /* signatures */
913 blob->sigs[0] = 0; /* not yet checked */
915 /* Create a temporary buffer for further processing */
916 init_membuf (&blob->bufbuf, 1024);
917 blob->buf = &blob->bufbuf;
918 /* write out what we already have */
919 rc = create_blob_header (blob, BLOBTYPE_X509);
920 if (rc)
921 goto leave;
922 rc = x509_create_blob_cert (blob, cert);
923 if (rc)
924 goto leave;
925 rc = create_blob_trailer (blob);
926 if (rc)
927 goto leave;
928 rc = create_blob_finish ( blob );
929 if (rc)
930 goto leave;
933 leave:
934 release_kid_list (blob->temp_kids);
935 blob->temp_kids = NULL;
936 if (blob && names)
938 for (i=0; i < blob->nuids; i++)
939 xfree (names[i]);
941 xfree (names);
942 if (rc)
944 _keybox_release_blob (blob);
945 *r_blob = NULL;
947 else
949 *r_blob = blob;
951 return rc;
953 #endif /*KEYBOX_WITH_X509*/
958 _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen)
960 KEYBOXBLOB blob;
962 *r_blob = NULL;
963 blob = xtrycalloc (1, sizeof *blob);
964 if (!blob)
965 return KEYBOX_Out_Of_Core;
967 blob->blob = image;
968 blob->bloblen = imagelen;
969 *r_blob = blob;
970 return 0;
973 void
974 _keybox_release_blob (KEYBOXBLOB blob)
976 int i;
977 if (!blob)
978 return;
979 /* hmmm: release membuf here?*/
980 xfree (blob->keys );
981 xfree (blob->serialbuf);
982 for (i=0; i < blob->nuids; i++)
983 xfree (blob->uids[i].name);
984 xfree (blob->uids );
985 xfree (blob->sigs );
986 xfree (blob->blob );
987 xfree (blob );
992 const char *
993 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
995 *n = blob->bloblen;
996 return blob->blob;