gpg: Remove the extra prompt for Curve25519.
[gnupg.git] / g10 / armor.c
index efdc92e..98fb105 100644 (file)
@@ -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;
 }
 
 
@@ -274,7 +315,7 @@ parse_hash_header( const char *line )
        return 0; /* too short or too long */
     if( memcmp( line, "Hash:", 5 ) )
        return 0; /* invalid header */
-    s = line+5;
+
     for(s=line+5;;s=s2) {
        for(; *s && (*s==' ' || *s == '\t'); s++ )
            ;
@@ -286,8 +327,6 @@ parse_hash_header( const char *line )
            found |= 1;
        else if( !strncmp( s, "SHA1", s2-s ) )
            found |= 2;
-       else if( !strncmp( s, "MD5", s2-s ) )
-           found |= 4;
        else if( !strncmp( s, "SHA224", s2-s ) )
            found |= 8;
        else if( !strncmp( s, "SHA256", s2-s ) )
@@ -536,7 +575,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
        i = parse_header_line( afx, line, len );
        if( i <= 0 ) {
            if (i && RFC2440)
-               rc = G10ERR_INVALID_ARMOR;
+               rc = GPG_ERR_INV_ARMOR;
            break;
        }
     }
@@ -664,10 +703,9 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
          {
            int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
 
-           /* PGP2 does not treat a tab as white space character */
            afx->buffer_len=
              trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
-                                  afx->pgp2mode ? " \r\n" : " \t\r\n");
+                                  " \t\r\n");
            afx->buffer_len+=afx->buffer_pos;
            /* the buffer is always allocated with enough space to append
             * the removed [CR], LF and a Nul
@@ -799,6 +837,24 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
                }
            }
 
+            /* Occasionally a bug MTA will leave the = escaped as
+               =3D.  If the 4 characters following that are valid
+               Radix64 characters and they are following by a new
+               line, assume that this is the case and skip the
+               3D.  */
+            if (afx->buffer_pos + 6 < afx->buffer_len
+                && afx->buffer[afx->buffer_pos + 0] == '3'
+                && afx->buffer[afx->buffer_pos + 1] == 'D'
+                && asctobin[afx->buffer[afx->buffer_pos + 2]] != 255
+                && asctobin[afx->buffer[afx->buffer_pos + 3]] != 255
+                && asctobin[afx->buffer[afx->buffer_pos + 4]] != 255
+                && asctobin[afx->buffer[afx->buffer_pos + 5]] != 255
+                && afx->buffer[afx->buffer_pos + 6] == '\n')
+              {
+                afx->buffer_pos += 2;
+                afx->qp_detected = 1;
+              }
+
            if (!n)
              onlypad = 1;
 
@@ -918,11 +974,11 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
                    rc = 0;
                else if( rc == 2 ) {
                    log_error(_("premature eof (in trailer)\n"));
-                   rc = G10ERR_INVALID_ARMOR;
+                   rc = GPG_ERR_INVALID_ARMOR;
                }
                else {
                    log_error(_("error in trailer line\n"));
-                   rc = G10ERR_INVALID_ARMOR;
+                   rc = GPG_ERR_INVALID_ARMOR;
                }
 #endif
            }
@@ -1009,14 +1065,9 @@ armor_filter( void *opaque, int control,
                /* the buffer is at least 15+n*15 bytes long, so it
                 * is easy to construct the packets */
 
-               hashes &= 1|2|4|8|16|32|64;
+               hashes &= 1|2|8|16|32|64;
                if( !hashes ) {
-                   hashes |= 4;  /* default to MD 5 */
-                   /* This is non-ideal since PGP 5-8 have the same
-                      end-of-line bugs as PGP 2. However, we only
-                      enable pgp2mode if there is no Hash: header. */
-                   if( opt.pgp2_workarounds )
-                       afx->pgp2mode = 1;
+                   hashes |= 2;  /* Default to SHA-1. */
                }
                n=0;
                 /* First a gpg control packet... */
@@ -1029,8 +1080,6 @@ armor_filter( void *opaque, int control,
                     buf[n++] = DIGEST_ALGO_RMD160;
                 if( hashes & 2 )
                     buf[n++] = DIGEST_ALGO_SHA1;
-                if( hashes & 4 )
-                    buf[n++] = DIGEST_ALGO_MD5;
                 if( hashes & 8 )
                     buf[n++] = DIGEST_ALGO_SHA224;
                 if( hashes & 16 )
@@ -1261,7 +1310,7 @@ armor_filter( void *opaque, int control,
         release_armor_context (afx);
     }
     else if( control == IOBUFCTRL_DESC )
-       *(char**)buf = "armor_filter";
+        mem2str (buf, "armor_filter", *ret_len);
     return rc;
 }