gpgscm: Make it possible to set the logfile name.
[gnupg.git] / kbx / keybox-openpgp.c
index 4306ed1..0ba0b9a 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/>.
  */
 
 /* This is a simple OpenPGP parser suitable for all OpenPGP key
@@ -36,7 +36,7 @@
 #include <gcrypt.h>
 
 #include "../common/openpgpdefs.h"
-
+#include "../common/host2net.h"
 
 /* Assume a valid OpenPGP packet at the address pointed to by BUFBTR
    which has a maximum length as stored at BUFLEN.  Return the header
@@ -71,7 +71,6 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
   if ( !(ctb & 0x80) )
     return gpg_error (GPG_ERR_INV_PACKET); /* Invalid CTB. */
 
-  pktlen = 0;
   if ((ctb & 0x40))  /* New style (OpenPGP) CTB.  */
     {
       pkttype = (ctb & 0x3f);
@@ -94,10 +93,8 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
         {
           if (len <4 )
             return gpg_error (GPG_ERR_INV_PACKET); /* No length bytes. */
-          pktlen  = (*buf++) << 24;
-          pktlen |= (*buf++) << 16;
-          pktlen |= (*buf++) << 8;
-          pktlen |= (*buf++);
+          pktlen = buf32_to_ulong (buf);
+          buf += 4;
           len -= 4;
       }
       else /* Partial length encoding is not allowed for key packets. */
@@ -141,7 +138,14 @@ next_packet (unsigned char const **bufptr, size_t *buflen,
       return gpg_error (GPG_ERR_UNEXPECTED);
     }
 
-  if (pktlen == (unsigned long)(-1))
+  if (pkttype == 63 && pktlen == 0xFFFFFFFF)
+    /* Sometimes the decompressing layer enters an error state in
+       which it simply outputs 0xff for every byte read.  If we have a
+       stream of 0xff bytes, then it will be detected as a new format
+       packet with type 63 and a 4-byte encoded length that is 4G-1.
+       Since packets with type 63 are private and we use them as a
+       control packet, which won't be 4 GB, we reject such packets as
+       invalid.  */
     return gpg_error (GPG_ERR_INV_PACKET);
 
   if (pktlen > len)
@@ -170,7 +174,6 @@ parse_key (const unsigned char *data, size_t datalen,
   const unsigned char *data_start = data;
   int i, version, algorithm;
   size_t n;
-  unsigned long timestamp, expiredate;
   int npkey;
   unsigned char hashbuffer[768];
   const unsigned char *mpi_n = NULL;
@@ -184,21 +187,15 @@ parse_key (const unsigned char *data, size_t datalen,
   if (version < 2 || version > 4 )
     return gpg_error (GPG_ERR_INV_PACKET); /* Invalid version. */
 
-  timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));
+  /*timestamp = ((data[0]<<24)|(data[1]<<16)|(data[2]<<8)|(data[3]));*/
   data +=4; datalen -=4;
 
   if (version < 4)
     {
-      unsigned short ndays;
-
       if (datalen < 2)
         return gpg_error (GPG_ERR_INV_PACKET);
-      ndays = ((data[0]<<8)|(data[1]));
       data +=2; datalen -= 2;
-      expiredate = ndays? (timestamp + ndays * 86400L) : 0;
     }
-  else
-    expiredate = 0; /* This is stored in the self-signature. */
 
   if (!datalen)
     return gpg_error (GPG_ERR_INV_PACKET);
@@ -206,23 +203,24 @@ parse_key (const unsigned char *data, size_t datalen,
 
   switch (algorithm)
     {
-    case 1:
-    case 2:
-    case 3: /* RSA */
+    case PUBKEY_ALGO_RSA:
+    case PUBKEY_ALGO_RSA_E:
+    case PUBKEY_ALGO_RSA_S:
       npkey = 2;
       break;
-    case 16:
-    case 20: /* Elgamal */
+    case PUBKEY_ALGO_ELGAMAL_E:
+    case PUBKEY_ALGO_ELGAMAL:
       npkey = 3;
       break;
-    case 17: /* DSA */
+    case PUBKEY_ALGO_DSA:
       npkey = 4;
       break;
-    case 18: /* ECDH */
+    case PUBKEY_ALGO_ECDH:
       npkey = 3;
       is_ecc = 1;
       break;
-    case 19: /* ECDSA */
+    case PUBKEY_ALGO_ECDSA:
+    case PUBKEY_ALGO_EDDSA:
       npkey = 2;
       is_ecc = 1;
       break;
@@ -230,6 +228,8 @@ parse_key (const unsigned char *data, size_t datalen,
       return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM);
     }
 
+  ki->algo = algorithm;
+
   for (i=0; i < npkey; i++ )
     {
       unsigned int nbits, nbytes;
@@ -296,7 +296,7 @@ parse_key (const unsigned char *data, size_t datalen,
     }
   else
     {
-      /* Its a pitty that we need to prefix the buffer with the tag
+      /* Its a pity that we need to prefix the buffer with the tag
          and a length header: We can't simply pass it to the fast
          hashing function for that reason.  It might be a good idea to
          have a scatter-gather enabled hash function. What we do here