[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Cvs-cvs] ccvs/src ChangeLog gpg.c [signed-commits3]
From: |
Derek Robert Price |
Subject: |
[Cvs-cvs] ccvs/src ChangeLog gpg.c [signed-commits3] |
Date: |
Mon, 13 Mar 2006 17:28:51 +0000 |
CVSROOT: /cvsroot/cvs
Module name: ccvs
Branch: signed-commits3
Changes by: Derek Robert Price <address@hidden> 06/03/13 17:28:51
Modified files:
src : ChangeLog gpg.c
Log message:
Handle OpenPGP version 4 signatures.
* gpg.c (struct openpgp_signature_subpacket): New struct.
(parse_signature_subpacket): New function.
(parse_signature): Process version 4 signatures.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/ChangeLog.diff?only_with_tag=signed-commits3&tr1=1.3328.2.44&tr2=1.3328.2.45&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/gpg.c.diff?only_with_tag=signed-commits3&tr1=1.1.6.10&tr2=1.1.6.11&r1=text&r2=text
Patches:
Index: ccvs/src/ChangeLog
diff -u ccvs/src/ChangeLog:1.3328.2.44 ccvs/src/ChangeLog:1.3328.2.45
--- ccvs/src/ChangeLog:1.3328.2.44 Fri Jan 27 22:19:59 2006
+++ ccvs/src/ChangeLog Mon Mar 13 17:28:51 2006
@@ -1,3 +1,10 @@
+2006-03-13 Derek Price <address@hidden>
+
+ Handle OpenPGP version 4 signatures.
+ * gpg.c (struct openpgp_signature_subpacket): New struct.
+ (parse_signature_subpacket): New function.
+ (parse_signature): Process version 4 signatures.
+
2006-01-27 Derek Price <address@hidden>
* verify.c: #include "wait.h" from GNULIB.
Index: ccvs/src/gpg.c
diff -u ccvs/src/gpg.c:1.1.6.10 ccvs/src/gpg.c:1.1.6.11
--- ccvs/src/gpg.c:1.1.6.10 Fri Jan 13 05:08:12 2006
+++ ccvs/src/gpg.c Mon Mar 13 17:28:51 2006
@@ -2,7 +2,8 @@
* Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
*
* This file is part of of CVS
- * (derived from gpgsplit.c distributed with GnuPG).
+ * (originally derived from gpgsplit.c distributed with GnuPG, but much
+ * has been rewritten from scratch using RFC 2440).
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -368,6 +369,139 @@
+struct openpgp_signature_subpacket
+{
+ uint8_t *raw;
+ size_t rawlen;
+ uint8_t type;
+ union
+ {
+ time_t ctime;
+ uint64_t keyid;
+ } u;
+};
+
+/* Parse a single signature version 4 subpacket from BPIN, populating
+ * structure at SPOUT.
+ *
+ * RETURNS
+ * 0 On success.
+ * -1 If EOF is encountered before a full packet is read.
+ * -2 On memory allocation errors from buf_read_data().
+ *
+ * ERRORS
+ * Aside from the error returns above, buf_output() can call its memory
+ * failure function on memory allocation failures, which could exit.
+ */
+static int
+parse_signature_subpacket (struct buffer *bpin,
+ struct openpgp_signature_subpacket *spout)
+{
+ int rc;
+ uint8_t c;
+ uint32_t tmp32;
+ uint32_t splen;
+ size_t raw_idx = 0;
+
+ /* Enough to store the subpacket length. */
+ spout->raw = xmalloc (4);
+
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+
+ spout->raw[raw_idx++] = c;
+
+ if (c < 192)
+ splen = c;
+ else if (c < 255)
+ {
+ splen = (c - 192) << 8;
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ splen += c + 192;
+ }
+ else /* c == 255 */
+ {
+ if ((rc = read_u32 (bpin, &splen)))
+ return rc;
+ spout->raw[raw_idx++] = splen >> 24;
+ spout->raw[raw_idx++] = splen >> 16;
+ spout->raw[raw_idx++] = splen >> 8;
+ spout->raw[raw_idx++] = splen;
+ }
+
+ if (splen == 0)
+ error (1, 0, "Received zero length subpacket in OpenPGP signature.");
+
+ /* Allocate enough bytes for the rest of the subpacket. */
+ spout->raw = xrealloc (spout->raw, splen);
+
+ /* Read the subpacket type. */
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ splen -= 1;
+ spout->type = c;
+
+ switch (c)
+ {
+ /* Signature creation time. */
+ case 2:
+ if (splen != 4)
+ error (1, 0, "Missized signature subpacket (%lu)", (long)splen);
+
+ if ((rc = read_u32 (bpin, &tmp32)))
+ return rc;
+ spout->u.ctime = tmp32;
+ spout->raw[raw_idx++] = (tmp32 >> 24) & 0xFF;
+ spout->raw[raw_idx++] = (tmp32 >> 16) & 0xFF;
+ spout->raw[raw_idx++] = (tmp32 >> 8) & 0xFF;
+ spout->raw[raw_idx++] = tmp32 & 0xFF;
+ break;
+
+ /* Signer's key ID. */
+ case 16:
+ if (splen != 8)
+ error (1, 0, "Missized signature subpacket (%lu)", (long)splen);
+
+ if ((rc = read_u64 (bpin, &spout->u.keyid)))
+ return rc;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 56) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 48) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 40) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 32) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 24) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 16) & 0xFF;
+ spout->raw[raw_idx++] = (spout->u.keyid >> 8) & 0xFF;
+ spout->raw[raw_idx++] = spout->u.keyid & 0xFF;
+ break;
+
+ /* Store but ignore other subpacket types. */
+ default:
+ while (splen)
+ {
+ size_t got;
+ char *tmp;
+ if ((rc = buf_read_data (bpin, splen, &tmp, &got)) < 0)
+ return rc;
+ assert (got); /* Blocking buffers cannot return 0 bytes. */
+ memcpy (spout->raw + raw_idx, tmp, got);
+ raw_idx += got;
+ splen -= got;
+ }
+ break;
+ }
+
+ /* This should be the original length read plus the 1, 2, or 5 bytes in the
+ * length header itself.
+ */
+ spout->rawlen = raw_idx;
+ return 0;
+}
+
+
+
/* Parse a single signature packet from BPIN, populating structure at SPOUT.
*
* RETURNS
@@ -389,8 +523,11 @@
int header_len = sizeof header;
int rc;
uint8_t c;
+ uint16_t tsplen;
uint32_t tmp32;
size_t raw_idx = 0;
+ bool got_ctime;
+ bool got_keyid;
if ((rc = parse_header (bpin, &pkttype, &pktlen, &partial, header,
&header_len)))
@@ -414,47 +551,198 @@
spout->raw[raw_idx++] = c;
pktlen -= 1;
- if (c != 3)
+ if (c != 3 && c != 4)
error (1, 0, "Unhandled OpenPGP signature version (%hhu)", c);
- if ((rc = read_u8 (bpin, &c)))
- return rc;
- spout->raw[raw_idx++] = c;
- pktlen -= 1;
+ switch (c)
+ {
+ case 3:
+ /* RFC 2440 Section 5.2.2 Version 4 Signature Packet Format */
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ pktlen -= 1;
- if (c != 5)
- error (1, 0, "Malformed OpenPGP signature (type/time length invalid)");
+ if (c != 5)
+ error (1, 0, "Malformed OpenPGP signature (type/time length invalid)");
- if ((rc = read_u8 (bpin, &c)))
- return rc;
- spout->raw[raw_idx++] = c;
- pktlen -= 1;
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ pktlen -= 1;
- if (c & 0xF0)
- error (1, 0, "Unhandled OpenPGP signature type (%hhu)", c);
+ if (c & 0xF0)
+ error (1, 0, "Unhandled OpenPGP signature type (%hhu)", c);
- /* Read the creation time. */
- if ((rc = read_u32 (bpin, &tmp32)))
- return rc;
- spout->ctime = tmp32;
- spout->raw[raw_idx++] = (tmp32 >> 24) & 0xFF;
- spout->raw[raw_idx++] = (tmp32 >> 16) & 0xFF;
- spout->raw[raw_idx++] = (tmp32 >> 8) & 0xFF;
- spout->raw[raw_idx++] = tmp32 & 0xFF;
- pktlen -= 4;
-
- /* Read the key ID. */
- if ((rc = read_u64 (bpin, &spout->keyid)))
- return rc;
- spout->raw[raw_idx++] = (spout->keyid >> 56) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 48) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 40) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 32) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 24) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 16) & 0xFF;
- spout->raw[raw_idx++] = (spout->keyid >> 8) & 0xFF;
- spout->raw[raw_idx++] = spout->keyid & 0xFF;
- pktlen -= 8;
+ /* Read the creation time. */
+ if ((rc = read_u32 (bpin, &tmp32)))
+ return rc;
+ spout->ctime = tmp32;
+ spout->raw[raw_idx++] = (tmp32 >> 24) & 0xFF;
+ spout->raw[raw_idx++] = (tmp32 >> 16) & 0xFF;
+ spout->raw[raw_idx++] = (tmp32 >> 8) & 0xFF;
+ spout->raw[raw_idx++] = tmp32 & 0xFF;
+ pktlen -= 4;
+
+ /* Read the key ID. */
+ if ((rc = read_u64 (bpin, &spout->keyid)))
+ return rc;
+ spout->raw[raw_idx++] = (spout->keyid >> 56) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 48) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 40) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 32) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 24) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 16) & 0xFF;
+ spout->raw[raw_idx++] = (spout->keyid >> 8) & 0xFF;
+ spout->raw[raw_idx++] = spout->keyid & 0xFF;
+ pktlen -= 8;
+ break;
+
+ case 4:
+ /* RFC 2440 Section 5.2.3 Version 4 Signature Packet Format */
+ got_ctime = false;
+ got_keyid = false;
+
+ /* Discard one-octet signature type. */
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ pktlen -= 1;
+
+ /* Discard one-octet public key algorithm. */
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ pktlen -= 1;
+
+ /* Discard one-octet hash algorithm. */
+ if ((rc = read_u8 (bpin, &c)))
+ return rc;
+ spout->raw[raw_idx++] = c;
+ pktlen -= 1;
+
+ /* Read the hashed subpacket length. */
+ if ((rc = read_u16 (bpin, &tsplen)))
+ return rc;
+ spout->raw[raw_idx++] = (tsplen >> 8) & 0xFF;
+ spout->raw[raw_idx++] = tsplen & 0xFF;
+ pktlen -= 2;
+
+ /* Process hashed subpackets. */
+ while (tsplen > 0)
+ {
+ struct openpgp_signature_subpacket sp;
+
+ if (got_ctime && got_keyid)
+ {
+ while (tsplen)
+ {
+ size_t got;
+ char *tmp;
+ if ((rc = buf_read_data (bpin, tsplen, &tmp, &got)) < 0)
+ return rc;
+ assert (got); /* Blocking buffers cannot return 0 bytes. */
+ memcpy (spout->raw + raw_idx, tmp, got);
+ raw_idx += got;
+ tsplen -= got;
+ pktlen -= got;
+ }
+ break;
+ }
+
+ if ((rc = parse_signature_subpacket (bpin, &sp)))
+ return rc;
+
+ if (sp.rawlen > tsplen)
+ error (1, 0,
+"Signature subpacket length exceeds total hashed subpackets length.");
+
+ memcpy (spout->raw + raw_idx, sp.raw, sp.rawlen);
+ free (sp.raw);
+ raw_idx += sp.rawlen;
+ pktlen -= sp.rawlen;
+ tsplen -= sp.rawlen;
+
+ switch (sp.type)
+ {
+ case 2:
+ spout->ctime = sp.u.ctime;
+ got_ctime = true;
+ break;
+ case 16:
+ spout->keyid = sp.u.keyid;
+ got_keyid = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Read the unhashed subpacket length. */
+ if ((rc = read_u16 (bpin, &tsplen)))
+ return rc;
+ spout->raw[raw_idx++] = (tsplen >> 8) & 0xFF;
+ spout->raw[raw_idx++] = tsplen & 0xFF;
+ pktlen -= 2;
+
+ /* Process unhashed subpackets. */
+ while (tsplen > 0)
+ {
+ struct openpgp_signature_subpacket sp;
+
+ if (got_ctime && got_keyid)
+ {
+ while (tsplen)
+ {
+ size_t got;
+ char *tmp;
+ if ((rc = buf_read_data (bpin, tsplen, &tmp, &got)) < 0)
+ return rc;
+ assert (got); /* Blocking buffers cannot return 0 bytes. */
+ memcpy (spout->raw + raw_idx, tmp, got);
+ raw_idx += got;
+ tsplen -= got;
+ pktlen -= got;
+ }
+ break;
+ }
+
+ if ((rc = parse_signature_subpacket (bpin, &sp)))
+ return rc;
+
+ if (sp.rawlen > tsplen)
+ error (1, 0,
+"Signature subpacket length exceeds total unhashed subpackets length.");
+
+ memcpy (spout->raw + raw_idx, sp.raw, sp.rawlen);
+ free (sp.raw);
+ raw_idx += sp.rawlen;
+ pktlen -= sp.rawlen;
+ tsplen -= sp.rawlen;
+
+ switch (sp.type)
+ {
+ case 2:
+ error (1, 0, "Creation time found in unhashed subpacket.");
+ /* Exits here, but who knows if that confuses the optimizer. */
+ break;
+
+ case 16:
+ spout->keyid = sp.u.keyid;
+ got_keyid = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!got_ctime)
+ error (1, 0, "Signature did not contain creation time.");
+ if (!got_keyid)
+ error (1, 0, "Signature did not contain keyid.");
+ break;
+ }
/* Don't need the rest of the packet yet. */
while (pktlen)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Cvs-cvs] ccvs/src ChangeLog gpg.c [signed-commits3],
Derek Robert Price <=