aboutsummaryrefslogtreecommitdiffstats
path: root/g10/armor.c
diff options
context:
space:
mode:
authorNeal H. Walfield <[email protected]>2016-03-02 14:47:01 +0000
committerNeal H. Walfield <[email protected]>2016-03-02 19:36:18 +0000
commit605276ef8cd449bfd574ae6c498fa5d7d265c5c7 (patch)
tree707c3f703aa6c5006481ba5c37d88f0553704420 /g10/armor.c
parentcommon: Provide a function for mapping packet types to strings. (diff)
downloadgnupg-605276ef8cd449bfd574ae6c498fa5d7d265c5c7.tar.gz
gnupg-605276ef8cd449bfd574ae6c498fa5d7d265c5c7.zip
gpg: More robustly detect valid non-armored OpenPGP messages.
* g10/armor.c (is_armored): More robustly detect valid non-armored OpenPGP messages. -- Signed-off-by: Neal H. Walfield <[email protected]>
Diffstat (limited to 'g10/armor.c')
-rw-r--r--g10/armor.c67
1 files changed, 54 insertions, 13 deletions
diff --git a/g10/armor.c b/g10/armor.c
index e34518e0b..98fb1056b 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -193,36 +193,77 @@ initialize(void)
/****************
* Check whether this is an armored file or not See also
- * parse-packet.c for details on this code For unknown historic
- * reasons we use a string here but only the first byte will be used.
+ * parse-packet.c for details on this code.
* Returns: True if it seems to be armored
*/
static int
is_armored( const byte *buf )
{
- int ctb, pkttype;
+ int ctb, pkttype;
+ int indeterminate_length_allowed;
ctb = *buf;
if( !(ctb & 0x80) )
- return 1; /* invalid packet: assume it is armored */
+ /* The most significant bit of the CTB must be set. Since it is
+ cleared, this is not a binary OpenPGP message. Assume it is
+ armored. */
+ return 1;
+
pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
switch( pkttype ) {
- case PKT_MARKER:
+ case PKT_PUBKEY_ENC:
+ case PKT_SIGNATURE:
case PKT_SYMKEY_ENC:
case PKT_ONEPASS_SIG:
- case PKT_PUBLIC_KEY:
case PKT_SECRET_KEY:
- case PKT_PUBKEY_ENC:
- case PKT_SIGNATURE:
- case PKT_COMMENT:
- case PKT_OLD_COMMENT:
- case PKT_PLAINTEXT:
+ case PKT_PUBLIC_KEY:
+ case PKT_SECRET_SUBKEY:
+ case PKT_MARKER:
+ case PKT_RING_TRUST:
+ case PKT_USER_ID:
+ case PKT_PUBLIC_SUBKEY:
+ case PKT_ATTRIBUTE:
+ case PKT_MDC:
+ indeterminate_length_allowed = 0;
+ break;
+
case PKT_COMPRESSED:
case PKT_ENCRYPTED:
- return 0; /* seems to be a regular packet: not armored */
+ case PKT_ENCRYPTED_MDC:
+ case PKT_PLAINTEXT:
+ case PKT_OLD_COMMENT:
+ case PKT_COMMENT:
+ case PKT_GPG_CONTROL:
+ indeterminate_length_allowed = 1;
+ break;
+
+ default:
+ /* Invalid packet type. */
+ return 1;
}
- return 1;
+ if (! indeterminate_length_allowed)
+ /* It is only legal to use an indeterminate length with a few
+ packet types. If a packet uses an indeterminate length, but
+ that is not allowed, then the data is not valid binary
+ OpenPGP data. */
+ {
+ int new_format;
+ int indeterminate_length;
+
+ new_format = !! (ctb & (1 << 6));
+ if (new_format)
+ indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
+ else
+ indeterminate_length = (ctb & 3) == 3;
+
+ if (indeterminate_length)
+ return 1;
+ }
+
+ /* The first CTB seems legit. It is probably not armored
+ data. */
+ return 0;
}