po: Some updates to the German translation.
[gnupg.git] / kbx / keybox-blob.c
index 62d1c9f..73ecfbe 100644 (file)
@@ -14,7 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 /*
@@ -42,8 +42,9 @@
    - u32  Length of this blob
    - byte Blob type (1)
    - byte Version number (1)
-   - byte RFU
-   - byte RFU
+   - u16  Header flags
+          bit 0 - RFU
+          bit 1 - Is being or has been used for OpenPGP blobs
    - b4   Magic 'KBXf'
    - u32  RFU
    - u32  file_created_at
@@ -53,7 +54,7 @@
 
 ** The OpenPGP and X.509 blobs
 
-   The OpenPGP and X.509 blobs are very similiar, things which are
+   The OpenPGP and X.509 blobs are very similar, things which are
    X.509 specific are noted like [X.509: xxx]
 
    - u32  Length of this blob (including these 4 bytes)
    - bN   Arbitrary space for example used to store data which is not
           part of the keyblock or certificate.  For example the v3 key
           IDs go here.
-   - bN   Space for the keyblock or certifciate.
-   - bN   RFU
+   - bN   Space for the keyblock or certificate.
+   - bN   RFU.  This is the remaining space after keyblock and before
+          the checksum.  Is is not covered by the checksum.
    - b20  SHA-1 checksum (useful for KS syncronisation?)
           Note, that KBX versions before GnuPG 2.1 used an MD5
           checksum.  However it was only created but never checked.
@@ -261,7 +263,10 @@ put_membuf (struct membuf *mb, const void *buf, size_t len)
         }
       mb->buf = p;
     }
-  memcpy (mb->buf + mb->len, buf, len);
+  if (buf)
+    memcpy (mb->buf + mb->len, buf, len);
+  else
+    memset (mb->buf + mb->len, 0, len);
   mb->len += len;
 }
 
@@ -311,6 +316,7 @@ put32 (struct membuf *mb, u32 a )
   put_membuf (mb, tmp, 4);
 }
 
+
 \f
 /* Store a value in the fixup list */
 static void
@@ -585,7 +591,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
 
   /* space where we write keyIDs and and other stuff so that the
      pointers can actually point to somewhere */
-  if (blobtype == BLOBTYPE_PGP)
+  if (blobtype == KEYBOX_BLOBTYPE_PGP)
     {
       /* 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
@@ -605,7 +611,7 @@ create_blob_header (KEYBOXBLOB blob, int blobtype, int as_ephemeral)
         }
     }
 
-  if (blobtype == BLOBTYPE_X509)
+  if (blobtype == KEYBOX_BLOBTYPE_X509)
     {
       /* We don't want to point to ASN.1 encoded UserIDs (DNs) but to
          the utf-8 string represenation of them */
@@ -638,12 +644,10 @@ create_blob_finish (KEYBOXBLOB blob)
   struct membuf *a = blob->buf;
   unsigned char *p;
   unsigned char *pp;
-  int i;
   size_t n;
 
-  /* write a placeholder for the checksum */
-  for (i = 0; i < 16; i++ )
-    put32 (a, 0);  /* Hmmm: why put32() ?? */
+  /* Write a placeholder for the checksum */
+  put_membuf (a, NULL, 20);
 
   /* get the memory area */
   n = 0; /* (Just to avoid compiler warning.) */
@@ -657,27 +661,37 @@ create_blob_finish (KEYBOXBLOB blob)
 
   /* do the fixups */
   if (blob->fixup_out_of_core)
-    return gpg_error (GPG_ERR_ENOMEM);
+    {
+      xfree (p);
+      return gpg_error (GPG_ERR_ENOMEM);
+    }
 
   {
-    struct fixup_list *fl;
-    for (fl = blob->fixups; fl; fl = fl->next)
+    struct fixup_list *fl, *next;
+    for (fl = blob->fixups; fl; fl = next)
       {
         assert (fl->off+4 <= n);
         p[fl->off+0] = fl->val >> 24;
         p[fl->off+1] = fl->val >> 16;
         p[fl->off+2] = fl->val >>  8;
         p[fl->off+3] = fl->val;
+        next = fl->next;
+        xfree (fl);
       }
+    blob->fixups = NULL;
   }
 
-  /* calculate and store the MD5 checksum */
-  gcry_md_hash_buffer (GCRY_MD_MD5, p + n - 16, p, n - 16);
+  /* Compute and store the SHA-1 checksum. */
+  gcry_md_hash_buffer (GCRY_MD_SHA1, p + n - 20, p, n - 20);
 
   pp = xtrymalloc (n);
   if ( !pp )
-    return gpg_error_from_syserror ();
+    {
+      xfree (p);
+      return gpg_error_from_syserror ();
+    }
   memcpy (pp , p, n);
+  xfree (p);
   blob->blob = pp;
   blob->bloblen = n;
 
@@ -699,9 +713,6 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
 
   *r_blob = NULL;
 
-  if (!info->nuids || !info->nsigs)
-    return gpg_error (GPG_ERR_BAD_PUBKEY);
-
   /* If we have a signature status vector, check that the number of
      elements matches the actual number of signatures.  */
   if (sigstatus && sigstatus[0] != info->nsigs)
@@ -718,19 +729,27 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
       err = gpg_error_from_syserror ();
       goto leave;
     }
+
   blob->nuids = info->nuids;
-  blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
-  if (!blob->uids)
+  if (blob->nuids)
     {
-      err = gpg_error_from_syserror ();
-      goto leave;
+      blob->uids = xtrycalloc (blob->nuids, sizeof *blob->uids );
+      if (!blob->uids)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
+
   blob->nsigs = info->nsigs;
-  blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
-  if (!blob->sigs)
+  if (blob->nsigs)
     {
-      err = gpg_error_from_syserror ();
-      goto leave;
+      blob->sigs = xtrycalloc (blob->nsigs, sizeof *blob->sigs );
+      if (!blob->sigs)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
     }
 
   err = pgp_create_key_part (blob, info);
@@ -741,7 +760,7 @@ _keybox_create_openpgp_blob (KEYBOXBLOB *r_blob,
 
   init_membuf (&blob->bufbuf, 1024);
   blob->buf = &blob->bufbuf;
-  err = create_blob_header (blob, BLOBTYPE_PGP, as_ephemeral);
+  err = create_blob_header (blob, KEYBOX_BLOBTYPE_PGP, as_ephemeral);
   if (err)
     goto leave;
   err = pgp_create_blob_keyblock (blob, image, imagelen);
@@ -928,7 +947,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
   init_membuf (&blob->bufbuf, 1024);
   blob->buf = &blob->bufbuf;
   /* write out what we already have */
-  rc = create_blob_header (blob, BLOBTYPE_X509, as_ephemeral);
+  rc = create_blob_header (blob, KEYBOX_BLOBTYPE_X509, as_ephemeral);
   if (rc)
     goto leave;
   rc = x509_create_blob_cert (blob, cert);
@@ -945,12 +964,12 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert,
  leave:
   release_kid_list (blob->temp_kids);
   blob->temp_kids = NULL;
-  if (blob && names)
+  if (names)
     {
       for (i=0; i < blob->nuids; i++)
         xfree (names[i]);
+      xfree (names);
     }
-  xfree (names);
   if (rc)
     {
       _keybox_release_blob (blob);
@@ -991,7 +1010,11 @@ _keybox_release_blob (KEYBOXBLOB blob)
   int i;
   if (!blob)
     return;
-  /* hmmm: release membuf here?*/
+  if (blob->buf)
+    {
+      size_t len;
+      xfree (get_membuf (blob->buf, &len));
+    }
   xfree (blob->keys );
   xfree (blob->serialbuf);
   for (i=0; i < blob->nuids; i++)
@@ -1020,9 +1043,9 @@ _keybox_get_blob_fileoffset (KEYBOXBLOB blob)
 
 
 void
-_keybox_update_header_blob (KEYBOXBLOB blob)
+_keybox_update_header_blob (KEYBOXBLOB blob, int for_openpgp)
 {
-  if (blob->bloblen >= 32 && blob->blob[4] == BLOBTYPE_HEADER)
+  if (blob->bloblen >= 32 && blob->blob[4] == KEYBOX_BLOBTYPE_HEADER)
     {
       u32 val = make_timestamp ();
 
@@ -1031,5 +1054,8 @@ _keybox_update_header_blob (KEYBOXBLOB blob)
       blob->blob[20+1] = (val >> 16);
       blob->blob[20+2] = (val >>  8);
       blob->blob[20+3] = (val      );
+
+      if (for_openpgp)
+        blob->blob[7] |= 0x02;  /* OpenPGP data may be available.  */
     }
 }