agent/
[gnupg.git] / kbx / keybox-blob.c
blob64e534f9f00925b5969cc024c6210243ad7f29a4
1 /* keybox-blob.c - KBX Blob handling
2 * Copyright (C) 2000, 2001, 2002, 2003, 2008 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 3 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, see <http://www.gnu.org/licenses/>.
21 /* The keybox data formats
23 The KeyBox uses an augmented OpenPGP/X.509 key format. This makes
24 random access to a keyblock/certificate easier and also gives the
25 opportunity to store additional information (e.g. the fingerprint)
26 along with the key. All integers are stored in network byte order,
27 offsets are counted from the beginning of the Blob.
29 The first record of a plain KBX file has a special format:
31 u32 length of the first record
32 byte Blob type (1)
33 byte version number (1)
34 byte reserved
35 byte reserved
36 u32 magic 'KBXf'
37 u32 reserved
38 u32 file_created_at
39 u32 last_maintenance_run
40 u32 reserved
41 u32 reserved
43 The OpenPGP and X.509 blob are very similiar, things which are
44 X.509 specific are noted like [X.509: xxx]
46 u32 length of this blob (including these 4 bytes)
47 byte Blob type (2) [X509: 3]
48 byte version number of this blob type (1)
49 u16 Blob flags
50 bit 0 = contains secret key material
51 bit 1 = ephemeral blob (e.g. used while quering external resources)
53 u32 offset to the OpenPGP keyblock or X509 DER encoded certificate
54 u32 and its length
55 u16 number of keys (at least 1!) [X509: always 1]
56 u16 size of additional key information
57 n times:
58 b20 The keys fingerprint
59 (fingerprints are always 20 bytes, MD5 left padded with zeroes)
60 u32 offset to the n-th key's keyID (a keyID is always 8 byte)
61 or 0 if not known which is the case only for X509.
62 u16 special key flags
63 bit 0 = qualified signature (not yet implemented}
64 u16 reserved
65 u16 size of serialnumber(may be zero)
66 n u16 (see above) bytes of serial number
67 u16 number of user IDs
68 u16 size of additional user ID information
69 n times:
70 u32 offset to the n-th user ID
71 u32 length of this user ID.
72 u16 special user ID flags.
73 bit 0 =
74 byte validity
75 byte reserved
76 [For X509, the first user ID is the Issuer, the second the Subject
77 and the others are subjectAltNames]
78 u16 number of signatures
79 u16 size of signature information (4)
80 u32 expiration time of signature with some special values:
81 0x00000000 = not checked
82 0x00000001 = missing key
83 0x00000002 = bad signature
84 0x10000000 = valid and expires at some date in 1978.
85 0xffffffff = valid and does not expire
86 u8 assigned ownertrust [X509: not used]
87 u8 all_validity
88 OpenPGP: see ../g10/trustdb/TRUST_* [not yet used]
89 X509: Bit 4 set := key has been revoked. Note that this value
90 matches TRUST_FLAG_REVOKED
91 u16 reserved
92 u32 recheck_after
93 u32 Newest timestamp in the keyblock (useful for KS syncronsiation?)
94 u32 Blob created at
95 u32 size of reserved space (not including this field)
96 reserved space
98 Here we might want to put other data
100 Here comes the keyblock
102 maybe we put a signature here later.
104 b16 MD5 checksum (useful for KS syncronisation), we might also want to use
105 a mac here.
106 b4 reserved
111 #include <config.h>
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <string.h>
115 #include <errno.h>
116 #include <assert.h>
117 #include <time.h>
119 #include "keybox-defs.h"
120 #include <gcrypt.h>
122 #ifdef KEYBOX_WITH_OPENPGP
123 /* include stuff to parse the packets */
124 #endif
125 #ifdef KEYBOX_WITH_X509
126 #include <ksba.h>
127 #endif
131 /* special values of the signature status */
132 #define SF_NONE(a) ( !(a) )
133 #define SF_NOKEY(a) ((a) & (1<<0))
134 #define SF_BAD(a) ((a) & (1<<1))
135 #define SF_VALID(a) ((a) & (1<<29))
138 struct membuf {
139 size_t len;
140 size_t size;
141 char *buf;
142 int out_of_core;
146 /* #if MAX_FINGERPRINT_LEN < 20 */
147 /* #error fingerprints are 20 bytes */
148 /* #endif */
150 struct keyboxblob_key {
151 char fpr[20];
152 u32 off_kid;
153 ulong off_kid_addr;
154 u16 flags;
156 struct keyboxblob_uid {
157 ulong off_addr;
158 char *name; /* used only with x509 */
159 u32 len;
160 u16 flags;
161 byte validity;
164 struct keyid_list {
165 struct keyid_list *next;
166 int seqno;
167 byte kid[8];
170 struct fixup_list {
171 struct fixup_list *next;
172 u32 off;
173 u32 val;
177 struct keyboxblob {
178 byte *blob;
179 size_t bloblen;
180 off_t fileoffset;
182 /* stuff used only by keybox_create_blob */
183 unsigned char *serialbuf;
184 const unsigned char *serial;
185 size_t seriallen;
186 int nkeys;
187 struct keyboxblob_key *keys;
188 int nuids;
189 struct keyboxblob_uid *uids;
190 int nsigs;
191 u32 *sigs;
192 struct fixup_list *fixups;
193 int fixup_out_of_core;
195 struct keyid_list *temp_kids;
196 struct membuf bufbuf; /* temporary store for the blob */
197 struct membuf *buf;
202 /* A simple implemention of a dynamic buffer. Use init_membuf() to
203 create a buffer, put_membuf to append bytes and get_membuf to
204 release and return the buffer. Allocation errors are detected but
205 only returned at the final get_membuf(), this helps not to clutter
206 the code with out of core checks. */
208 static void
209 init_membuf (struct membuf *mb, int initiallen)
211 mb->len = 0;
212 mb->size = initiallen;
213 mb->out_of_core = 0;
214 mb->buf = xtrymalloc (initiallen);
215 if (!mb->buf)
216 mb->out_of_core = 1;
219 static void
220 put_membuf (struct membuf *mb, const void *buf, size_t len)
222 if (mb->out_of_core)
223 return;
225 if (mb->len + len >= mb->size)
227 char *p;
229 mb->size += len + 1024;
230 p = xtryrealloc (mb->buf, mb->size);
231 if (!p)
233 mb->out_of_core = 1;
234 return;
236 mb->buf = p;
238 memcpy (mb->buf + mb->len, buf, len);
239 mb->len += len;
242 static void *
243 get_membuf (struct membuf *mb, size_t *len)
245 char *p;
247 if (mb->out_of_core)
249 xfree (mb->buf);
250 mb->buf = NULL;
251 return NULL;
254 p = mb->buf;
255 *len = mb->len;
256 mb->buf = NULL;
257 mb->out_of_core = 1; /* don't allow a reuse */
258 return p;
262 static void
263 put8 (struct membuf *mb, byte a )
265 put_membuf (mb, &a, 1);
268 static void
269 put16 (struct membuf *mb, u16 a )
271 unsigned char tmp[2];
272 tmp[0] = a>>8;
273 tmp[1] = a;
274 put_membuf (mb, tmp, 2);
277 static void
278 put32 (struct membuf *mb, u32 a )
280 unsigned char tmp[4];
281 tmp[0] = a>>24;
282 tmp[1] = a>>16;
283 tmp[2] = a>>8;
284 tmp[3] = a;
285 put_membuf (mb, tmp, 4);
289 /* Store a value in the fixup list */
290 static void
291 add_fixup (KEYBOXBLOB blob, u32 off, u32 val)
293 struct fixup_list *fl;
295 if (blob->fixup_out_of_core)
296 return;
298 fl = xtrycalloc(1, sizeof *fl);
299 if (!fl)
300 blob->fixup_out_of_core = 1;
301 else
303 fl->off = off;
304 fl->val = val;
305 fl->next = blob->fixups;
306 blob->fixups = fl;
312 Some wrappers
315 static u32
316 make_timestamp (void)
318 return time(NULL);
323 #ifdef KEYBOX_WITH_OPENPGP
325 OpenPGP specific stuff
330 We must store the keyid at some place because we can't calculate the
331 offset yet. This is only used for v3 keyIDs. Function returns an
332 index value for later fixup or -1 for out of core. The value must be
333 a non-zero value */
334 static int
335 pgp_temp_store_kid (KEYBOXBLOB blob, PKT_public_key *pk)
337 struct keyid_list *k, *r;
339 k = xtrymalloc (sizeof *k);
340 if (!k)
341 return -1;
342 k->kid[0] = pk->keyid[0] >> 24 ;
343 k->kid[1] = pk->keyid[0] >> 16 ;
344 k->kid[2] = pk->keyid[0] >> 8 ;
345 k->kid[3] = pk->keyid[0] ;
346 k->kid[4] = pk->keyid[0] >> 24 ;
347 k->kid[5] = pk->keyid[0] >> 16 ;
348 k->kid[6] = pk->keyid[0] >> 8 ;
349 k->kid[7] = pk->keyid[0] ;
350 k->seqno = 0;
351 k->next = blob->temp_kids;
352 blob->temp_kids = k;
353 for (r=k; r; r = r->next)
354 k->seqno++;
356 return k->seqno;
359 static int
360 pgp_create_key_part (KEYBOXBLOB blob, KBNODE keyblock)
362 KBNODE node;
363 size_t fprlen;
364 int n;
366 for (n=0, node = keyblock; node; node = node->next)
368 if ( node->pkt->pkttype == PKT_PUBLIC_KEY
369 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
371 PKT_public_key *pk = node->pkt->pkt.public_key;
372 char tmp[20];
374 fingerprint_from_pk (pk, tmp , &fprlen);
375 memcpy (blob->keys[n].fpr, tmp, 20);
376 if ( fprlen != 20 ) /*v3 fpr - shift right and fill with zeroes*/
378 assert (fprlen == 16);
379 memmove (blob->keys[n].fpr+4, blob->keys[n].fpr, 16);
380 memset (blob->keys[n].fpr, 0, 4);
381 blob->keys[n].off_kid = pgp_temp_store_kid (blob, pk);
383 else
385 blob->keys[n].off_kid = 0; /* will be fixed up later */
387 blob->keys[n].flags = 0;
388 n++;
390 else if ( node->pkt->pkttype == PKT_SECRET_KEY
391 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
393 never_reached (); /* actually not yet implemented */
396 assert (n == blob->nkeys);
397 return 0;
400 static int
401 pgp_create_uid_part (KEYBOXBLOB blob, KBNODE keyblock)
403 KBNODE node;
404 int n;
406 for (n=0, node = keyblock; node; node = node->next)
408 if (node->pkt->pkttype == PKT_USER_ID)
410 PKT_user_id *u = node->pkt->pkt.user_id;
412 blob->uids[n].len = u->len;
413 blob->uids[n].flags = 0;
414 blob->uids[n].validity = 0;
415 n++;
418 assert (n == blob->nuids);
419 return 0;
422 static int
423 pgp_create_sig_part (KEYBOXBLOB blob, KBNODE keyblock)
425 KBNODE node;
426 int n;
428 for (n=0, node = keyblock; node; node = node->next)
430 if (node->pkt->pkttype == PKT_SIGNATURE)
432 PKT_signature *sig = node->pkt->pkt.signature;
434 blob->sigs[n] = 0; /* FIXME: check the signature here */
435 n++;
438 assert( n == blob->nsigs );
439 return 0;
442 static int
443 pgp_create_blob_keyblock (KEYBOXBLOB blob, KBNODE keyblock)
445 struct membuf *a = blob->buf;
446 KBNODE node;
447 int rc;
448 int n;
449 u32 kbstart = a->len;
451 add_fixup (blob, kbstart);
453 for (n = 0, node = keyblock; node; node = node->next)
455 rc = build_packet ( a, node->pkt );
456 if ( rc ) {
457 gpg_log_error ("build_packet(%d) for keyboxblob failed: %s\n",
458 node->pkt->pkttype, gpg_errstr(rc) );
459 return GPGERR_WRITE_FILE;
461 if ( node->pkt->pkttype == PKT_USER_ID )
463 PKT_user_id *u = node->pkt->pkt.user_id;
464 /* build_packet has set the offset of the name into u ;
465 * now we can do the fixup */
466 add_fixup (blob, blob->uids[n].off_addr, u->stored_at);
467 n++;
470 assert (n == blob->nuids);
472 add_fixup (blob, a->len - kbstart);
473 return 0;
476 #endif /*KEYBOX_WITH_OPENPGP*/
479 #ifdef KEYBOX_WITH_X509
481 X.509 specific stuff
484 /* Write the raw certificate out */
485 static int
486 x509_create_blob_cert (KEYBOXBLOB blob, ksba_cert_t cert)
488 struct membuf *a = blob->buf;
489 const unsigned char *image;
490 size_t length;
491 u32 kbstart = a->len;
493 /* Store our offset for later fixup */
494 add_fixup (blob, 8, kbstart);
496 image = ksba_cert_get_image (cert, &length);
497 if (!image)
498 return gpg_error (GPG_ERR_GENERAL);
499 put_membuf (a, image, length);
501 add_fixup (blob, 12, a->len - kbstart);
502 return 0;
505 #endif /*KEYBOX_WITH_X509*/
507 /* Write a stored keyID out to the buffer */
508 static void
509 write_stored_kid (KEYBOXBLOB blob, int seqno)
511 struct keyid_list *r;
513 for ( r = blob->temp_kids; r; r = r->next )
515 if (r->seqno == seqno )
517 put_membuf (blob->buf, r->kid, 8);
518 return;
521 never_reached ();
524 /* Release a list of key IDs */
525 static void
526 release_kid_list (struct keyid_list *kl)
528 struct keyid_list *r, *r2;
530 for ( r = kl; r; r = r2 )
532 r2 = r->next;
533 xfree (r);
539 static int
540 create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
542 struct membuf *a = blob->buf;
543 int i;
545 put32 ( a, 0 ); /* blob length, needs fixup */
546 put8 ( a, blobtype);
547 put8 ( a, 1 ); /* blob type version */
548 put16 ( a, as_ephemeral? 2:0 ); /* blob flags */
550 put32 ( a, 0 ); /* offset to the raw data, needs fixup */
551 put32 ( a, 0 ); /* length of the raw data, needs fixup */
553 put16 ( a, blob->nkeys );
554 put16 ( a, 20 + 4 + 2 + 2 ); /* size of key info */
555 for ( i=0; i < blob->nkeys; i++ )
557 put_membuf (a, blob->keys[i].fpr, 20);
558 blob->keys[i].off_kid_addr = a->len;
559 put32 ( a, 0 ); /* offset to keyid, fixed up later */
560 put16 ( a, blob->keys[i].flags );
561 put16 ( a, 0 ); /* reserved */
564 put16 (a, blob->seriallen); /*fixme: check that it fits into 16 bits*/
565 if (blob->serial)
566 put_membuf (a, blob->serial, blob->seriallen);
568 put16 ( a, blob->nuids );
569 put16 ( a, 4 + 4 + 2 + 1 + 1 ); /* size of uid info */
570 for (i=0; i < blob->nuids; i++)
572 blob->uids[i].off_addr = a->len;
573 put32 ( a, 0 ); /* offset to userid, fixed up later */
574 put32 ( a, blob->uids[i].len );
575 put16 ( a, blob->uids[i].flags );
576 put8 ( a, 0 ); /* validity */
577 put8 ( a, 0 ); /* reserved */
580 put16 ( a, blob->nsigs );
581 put16 ( a, 4 ); /* size of sig info */
582 for (i=0; i < blob->nsigs; i++)
584 put32 ( a, blob->sigs[i]);
587 put8 ( a, 0 ); /* assigned ownertrust */
588 put8 ( a, 0 ); /* validity of all user IDs */
589 put16 ( a, 0 ); /* reserved */
590 put32 ( a, 0 ); /* time of next recheck */
591 put32 ( a, 0 ); /* newest timestamp (none) */
592 put32 ( a, make_timestamp() ); /* creation time */
593 put32 ( a, 0 ); /* size of reserved space */
594 /* reserved space (which is currently of size 0) */
596 /* space where we write keyIDs and and other stuff so that the
597 pointers can actually point to somewhere */
598 if (blobtype == BLOBTYPE_PGP)
600 /* We need to store the keyids for all pgp v3 keys because those key
601 IDs are not part of the fingerprint. While we are doing that, we
602 fixup all the keyID offsets */
603 for (i=0; i < blob->nkeys; i++ )
605 if (blob->keys[i].off_kid)
606 { /* this is a v3 one */
607 add_fixup (blob, blob->keys[i].off_kid_addr, a->len);
608 write_stored_kid (blob, blob->keys[i].off_kid);
610 else
611 { /* the better v4 key IDs - just store an offset 8 bytes back */
612 add_fixup (blob, blob->keys[i].off_kid_addr,
613 blob->keys[i].off_kid_addr - 8);
618 if (blobtype == BLOBTYPE_X509)
620 /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
621 the utf-8 string represenation of them */
622 for (i=0; i < blob->nuids; i++ )
624 if (blob->uids[i].name)
625 { /* this is a v3 one */
626 add_fixup (blob, blob->uids[i].off_addr, a->len);
627 put_membuf (blob->buf, blob->uids[i].name, blob->uids[i].len);
632 return 0;
637 static int
638 create_blob_trailer (KEYBOXBLOB blob)
640 (void)blob;
641 return 0;
645 static int
646 create_blob_finish (KEYBOXBLOB blob)
648 struct membuf *a = blob->buf;
649 unsigned char *p;
650 unsigned char *pp;
651 int i;
652 size_t n;
654 /* write a placeholder for the checksum */
655 for (i = 0; i < 16; i++ )
656 put32 (a, 0); /* Hmmm: why put32() ?? */
658 /* get the memory area */
659 n = 0; /* (Just to avoid compiler warning.) */
660 p = get_membuf (a, &n);
661 if (!p)
662 return gpg_error (GPG_ERR_ENOMEM);
663 assert (n >= 20);
665 /* fixup the length */
666 add_fixup (blob, 0, n);
668 /* do the fixups */
669 if (blob->fixup_out_of_core)
670 return gpg_error (GPG_ERR_ENOMEM);
673 struct fixup_list *fl;
674 for (fl = blob->fixups; fl; fl = fl->next)
676 assert (fl->off+4 <= n);
677 p[fl->off+0] = fl->val >> 24;
678 p[fl->off+1] = fl->val >> 16;
679 p[fl->off+2] = fl->val >> 8;
680 p[fl->off+3] = fl->val;
684 /* calculate and store the MD5 checksum */
685 gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
687 pp = xtrymalloc (n);
688 if ( !pp )
689 return gpg_error_from_syserror ();
690 memcpy (pp , p, n);
691 blob->blob = pp;
692 blob->bloblen = n;
694 return 0;
698 #ifdef KEYBOX_WITH_OPENPGP
701 _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral)
703 int rc = 0;
704 KBNODE node;
705 KEYBOXBLOB blob;
707 *r_blob = NULL;
708 blob = xtrycalloc (1, sizeof *blob);
709 if (!blob)
710 return gpg_error_from_syserror ();
712 /* fixme: Do some sanity checks on the keyblock */
714 /* count userids and keys so that we can allocate the arrays */
715 for (node = keyblock; node; node = node->next)
717 switch (node->pkt->pkttype)
719 case PKT_PUBLIC_KEY:
720 case PKT_SECRET_KEY:
721 case PKT_PUBLIC_SUBKEY:
722 case PKT_SECRET_SUBKEY: blob->nkeys++; break;
723 case PKT_USER_ID: blob->nuids++; break;
724 case PKT_SIGNATURE: blob->nsigs++; break;
725 default: break;
729 blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
730 blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
731 blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
732 if (!blob->keys || !blob->uids || !blob->sigs)
734 rc = gpg_error (GPG_ERR_ENOMEM);
735 goto leave;
738 rc = pgp_create_key_part ( blob, keyblock );
739 if (rc)
740 goto leave;
741 rc = pgp_create_uid_part ( blob, keyblock );
742 if (rc)
743 goto leave;
744 rc = pgp_create_sig_part ( blob, keyblock );
745 if (rc)
746 goto leave;
748 init_membuf (&blob->bufbuf, 1024);
749 blob->buf = &blob->bufbuf;
750 rc = create_blob_header (blob, BLOBTYPE_OPENPGP, as_ephemeral);
751 if (rc)
752 goto leave;
753 rc = pgp_create_blob_keyblock (blob, keyblock);
754 if (rc)
755 goto leave;
756 rc = create_blob_trailer (blob);
757 if (rc)
758 goto leave;
759 rc = create_blob_finish ( blob );
760 if (rc)
761 goto leave;
764 leave:
765 release_kid_list (blob->temp_kids);
766 blob->temp_kids = NULL;
767 if (rc)
769 keybox_release_blob (blob);
770 *r_blob = NULL;
772 else
774 *r_blob = blob;
776 return rc;
778 #endif /*KEYBOX_WITH_OPENPGP*/
780 #ifdef KEYBOX_WITH_X509
782 /* Return an allocated string with the email address extracted from a
783 DN. Note hat we use this code also in ../sm/keylist.c. */
784 static char *
785 x509_email_kludge (const char *name)
787 const char *p, *string;
788 unsigned char *buf;
789 int n;
791 string = name;
792 for (;;)
794 p = strstr (string, "1.2.840.113549.1.9.1=#");
795 if (!p)
796 return NULL;
797 if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
799 name = p + 22;
800 break;
802 string = p + 22;
806 /* This looks pretty much like an email address in the subject's DN
807 we use this to add an additional user ID entry. This way,
808 OpenSSL generated keys get a nicer and usable listing. */
809 for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
811 if (!n)
812 return NULL;
813 buf = xtrymalloc (n+3);
814 if (!buf)
815 return NULL; /* oops, out of core */
816 *buf = '<';
817 for (n=1, p=name; hexdigitp (p); p +=2, n++)
818 buf[n] = xtoi_2 (p);
819 buf[n++] = '>';
820 buf[n] = 0;
821 return (char*)buf;
826 /* Note: We should move calculation of the digest into libksba and
827 remove that parameter */
829 _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
830 unsigned char *sha1_digest, int as_ephemeral)
832 int i, rc = 0;
833 KEYBOXBLOB blob;
834 unsigned char *sn;
835 char *p;
836 char **names = NULL;
837 size_t max_names;
839 *r_blob = NULL;
840 blob = xtrycalloc (1, sizeof *blob);
841 if( !blob )
842 return gpg_error_from_syserror ();
844 sn = ksba_cert_get_serial (cert);
845 if (sn)
847 size_t n, len;
848 n = gcry_sexp_canon_len (sn, 0, NULL, NULL);
849 if (n < 2)
851 xfree (sn);
852 return gpg_error (GPG_ERR_GENERAL);
854 blob->serialbuf = sn;
855 sn++; n--; /* skip '(' */
856 for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++)
857 len = len*10 + atoi_1 (sn);
858 if (*sn != ':')
860 xfree (blob->serialbuf);
861 blob->serialbuf = NULL;
862 return gpg_error (GPG_ERR_GENERAL);
864 sn++;
865 blob->serial = sn;
866 blob->seriallen = len;
869 blob->nkeys = 1;
871 /* create list of names */
872 blob->nuids = 0;
873 max_names = 100;
874 names = xtrymalloc (max_names * sizeof *names);
875 if (!names)
877 rc = gpg_error_from_syserror ();
878 goto leave;
881 p = ksba_cert_get_issuer (cert, 0);
882 if (!p)
884 rc = gpg_error (GPG_ERR_MISSING_VALUE);
885 goto leave;
887 names[blob->nuids++] = p;
888 for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
890 if (blob->nuids >= max_names)
892 char **tmp;
894 max_names += 100;
895 tmp = xtryrealloc (names, max_names * sizeof *names);
896 if (!tmp)
898 rc = gpg_error_from_syserror ();
899 goto leave;
902 names[blob->nuids++] = p;
903 if (!i && (p=x509_email_kludge (p)))
904 names[blob->nuids++] = p; /* due to !i we don't need to check bounds*/
907 /* space for signature information */
908 blob->nsigs = 1;
910 blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
911 blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
912 blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
913 if (!blob->keys || !blob->uids || !blob->sigs)
915 rc = gpg_error (GPG_ERR_ENOMEM);
916 goto leave;
919 memcpy (blob->keys[0].fpr, sha1_digest, 20);
920 blob->keys[0].off_kid = 0; /* We don't have keyids */
921 blob->keys[0].flags = 0;
923 /* issuer and subject names */
924 for (i=0; i < blob->nuids; i++)
926 blob->uids[i].name = names[i];
927 blob->uids[i].len = strlen(names[i]);
928 names[i] = NULL;
929 blob->uids[i].flags = 0;
930 blob->uids[i].validity = 0;
932 xfree (names);
933 names = NULL;
935 /* signatures */
936 blob->sigs[0] = 0; /* not yet checked */
938 /* Create a temporary buffer for further processing */
939 init_membuf (&blob->bufbuf, 1024);
940 blob->buf = &blob->bufbuf;
941 /* write out what we already have */
942 rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
943 if (rc)
944 goto leave;
945 rc = x509_create_blob_cert (blob, cert);
946 if (rc)
947 goto leave;
948 rc = create_blob_trailer (blob);
949 if (rc)
950 goto leave;
951 rc = create_blob_finish ( blob );
952 if (rc)
953 goto leave;
956 leave:
957 release_kid_list (blob->temp_kids);
958 blob->temp_kids = NULL;
959 if (blob && names)
961 for (i=0; i < blob->nuids; i++)
962 xfree (names[i]);
964 xfree (names);
965 if (rc)
967 _keybox_release_blob (blob);
968 *r_blob = NULL;
970 else
972 *r_blob = blob;
974 return rc;
976 #endif /*KEYBOX_WITH_X509*/
981 _keybox_new_blob (KEYBOXBLOB *r_blob,
982 unsigned char *image, size_t imagelen, off_t off)
984 KEYBOXBLOB blob;
986 *r_blob = NULL;
987 blob = xtrycalloc (1, sizeof *blob);
988 if (!blob)
989 return gpg_error_from_syserror ();
991 blob->blob = image;
992 blob->bloblen = imagelen;
993 blob->fileoffset = off;
994 *r_blob = blob;
995 return 0;
999 void
1000 _keybox_release_blob (KEYBOXBLOB blob)
1002 int i;
1003 if (!blob)
1004 return;
1005 /* hmmm: release membuf here?*/
1006 xfree (blob->keys );
1007 xfree (blob->serialbuf);
1008 for (i=0; i < blob->nuids; i++)
1009 xfree (blob->uids[i].name);
1010 xfree (blob->uids );
1011 xfree (blob->sigs );
1012 xfree (blob->blob );
1013 xfree (blob );
1018 const unsigned char *
1019 _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n )
1021 *n = blob->bloblen;
1022 return blob->blob;
1025 off_t
1026 _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
1028 return blob->fileoffset;
1033 void
1034 _keybox_update_header_blob (KEYBOXBLOB blob)
1036 if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
1038 u32 val = make_timestamp ();
1040 /* Update the last maintenance run times tamp. */
1041 blob->blob[20] = (val >> 24);
1042 blob->blob[20+1] = (val >> 16);
1043 blob->blob[20+2] = (val >> 8);
1044 blob->blob[20+3] = (val );