* pcsc-wrapper.c: New.
[gnupg.git] / g10 / armor.c
index 9c7858f..121ec3a 100644 (file)
@@ -1,5 +1,6 @@
 /* armor.c - Armor flter
 /* armor.c - Armor flter
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *                                             Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  *
  * This file is part of GnuPG.
  *
@@ -26,6 +27,7 @@
 #include <assert.h>
 #include <ctype.h>
 
 #include <assert.h>
 #include <ctype.h>
 
+#include "gpg.h"
 #include "errors.h"
 #include "iobuf.h"
 #include "memory.h"
 #include "errors.h"
 #include "iobuf.h"
 #include "memory.h"
@@ -38,9 +40,9 @@
 #include "i18n.h"
 
 #ifdef HAVE_DOSISH_SYSTEM
 #include "i18n.h"
 
 #ifdef HAVE_DOSISH_SYSTEM
-  #define LF "\r\n"
+#define LF "\r\n"
 #else
 #else
-  #define LF "\n"
+#define LF "\n"
 #endif
 
 #define MAX_LINELEN 20000
 #endif
 
 #define MAX_LINELEN 20000
@@ -191,7 +193,7 @@ is_armored( const byte *buf )
  *        filter to do further processing.
  */
 int
  *        filter to do further processing.
  */
 int
-use_armor_filter( IOBUF a )
+use_armor_filter( iobuf_t a )
 {
     byte buf[1];
     int n;
 {
     byte buf[1];
     int n;
@@ -247,10 +249,12 @@ parse_hash_header( const char *line )
            found |= 2;
        else if( !strncmp( s, "MD5", s2-s ) )
            found |= 4;
            found |= 2;
        else if( !strncmp( s, "MD5", s2-s ) )
            found |= 4;
-       else if( !strncmp( s, "TIGER192", s2-s ) )
-           found |= 8;
-       else if( !strncmp( s, "TIGER", s2-s ) ) /* used by old versions */
+       else if( !strncmp( s, "SHA256", s2-s ) )
            found |= 8;
            found |= 8;
+       else if( !strncmp( s, "SHA384", s2-s ) )
+           found |= 16;
+       else if( !strncmp( s, "SHA512", s2-s ) )
+           found |= 32;
        else
            return 0;
        for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
        else
            return 0;
        for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
@@ -291,7 +295,7 @@ is_armor_header( byte *line, unsigned len )
     /* Some mail programs on Windows seem to add spaces to the end of
        the line.  This becomes strict if --openpgp is set. */
 
     /* Some mail programs on Windows seem to add spaces to the end of
        the line.  This becomes strict if --openpgp is set. */
 
-    if(!opt.rfc2440)
+    if(!RFC2440)
       while(*p==' ')
        p++;
 
       while(*p==' ')
        p++;
 
@@ -330,7 +334,7 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
     int hashes=0;
     unsigned int len2;
 
     int hashes=0;
     unsigned int len2;
 
-    len2 = check_trailing_ws( line, len );
+    len2 = length_sans_trailing_ws( line, len );
     if( !len2 ) {
         afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
        return 0; /* WS only: same as empty line */
     if( !len2 ) {
         afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
        return 0; /* WS only: same as empty line */
@@ -369,7 +373,7 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
 
 /* figure out whether the data is armored or not */
 static int
 
 /* figure out whether the data is armored or not */
 static int
-check_input( armor_filter_context_t *afx, IOBUF a )
+check_input( armor_filter_context_t *afx, iobuf_t a )
 {
     int rc = 0;
     int i;
 {
     int rc = 0;
     int i;
@@ -411,7 +415,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
            if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
                if( afx->in_cleartext ) {
                    log_error(_("nested clear text signatures\n"));
            if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
                if( afx->in_cleartext ) {
                    log_error(_("nested clear text signatures\n"));
-                   rc = G10ERR_INVALID_ARMOR;
+                   rc = GPG_ERR_INV_ARMOR;
                }
                afx->in_cleartext = 1;
            }
                }
                afx->in_cleartext = 1;
            }
@@ -441,7 +445,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
        i = parse_header_line( afx, line, len );
        if( i <= 0 ) {
            if( i )
        i = parse_header_line( afx, line, len );
        if( i <= 0 ) {
            if( i )
-               rc = G10ERR_INVALID_ARMOR;
+               rc = GPG_ERR_INV_ARMOR;
            break;
        }
     }
            break;
        }
     }
@@ -469,7 +473,7 @@ check_input( armor_filter_context_t *afx, IOBUF a )
  *       not implemented/checked.
  */
 static int
  *       not implemented/checked.
  */
 static int
-fake_packet( armor_filter_context_t *afx, IOBUF a,
+fake_packet( armor_filter_context_t *afx, iobuf_t a,
             size_t *retn, byte *buf, size_t size  )
 {
     int rc = 0;
             size_t *retn, byte *buf, size_t size  )
 {
     int rc = 0;
@@ -608,12 +612,12 @@ invalid_crc(void)
     if ( opt.ignore_crc_error )
         return 0;
     log_inc_errorcount();
     if ( opt.ignore_crc_error )
         return 0;
     log_inc_errorcount();
-    return G10ERR_INVALID_ARMOR;
+    return GPG_ERR_INV_ARMOR;
 }
 
 
 static int
 }
 
 
 static int
-radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
+radix64_read( armor_filter_context_t *afx, iobuf_t a, size_t *retn,
              byte *buf, size_t size )
 {
     byte val;
              byte *buf, size_t size )
 {
     byte val;
@@ -766,7 +770,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
                 /* FIXME: Here we should emit another control packet,
                  * so that we know in mainproc that we are processing
                  * a clearsign message */
                 /* FIXME: Here we should emit another control packet,
                  * so that we know in mainproc that we are processing
                  * a clearsign message */
-             #if 0
+#if 0
                for(rc=0;!rc;) {
                    rc = 0 /*check_trailer( &fhdr, c )*/;
                    if( !rc ) {
                for(rc=0;!rc;) {
                    rc = 0 /*check_trailer( &fhdr, c )*/;
                    if( !rc ) {
@@ -778,13 +782,13 @@ 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 = 0;
                else if( rc == 2 ) {
                    log_error(_("premature eof (in Trailer)\n"));
-                   rc = G10ERR_INVALID_ARMOR;
+                   rc = GPG_ERR_INV_ARMOR;
                }
                else {
                    log_error(_("error in trailer line\n"));
                }
                else {
                    log_error(_("error in trailer line\n"));
-                   rc = G10ERR_INVALID_ARMOR;
+                   rc = GPG_ERR_INV_ARMOR;
                }
                }
-             #endif
+#endif
            }
        }
     }
            }
        }
     }
@@ -801,7 +805,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
  */
 int
 armor_filter( void *opaque, int control,
  */
 int
 armor_filter( void *opaque, int control,
-            IOBUF a, byte *buf, size_t *ret_len)
+            iobuf_t a, byte *buf, size_t *ret_len)
 {
     size_t size = *ret_len;
     armor_filter_context_t *afx = opaque;
 {
     size_t size = *ret_len;
     armor_filter_context_t *afx = opaque;
@@ -810,14 +814,14 @@ armor_filter( void *opaque, int control,
     int  idx, idx2;
     size_t n=0;
     u32 crc;
     int  idx, idx2;
     size_t n=0;
     u32 crc;
-  #if 0
+#if 0
     static FILE *fp ;
 
     if( !fp ) {
        fp = fopen("armor.out", "w");
        assert(fp);
     }
     static FILE *fp ;
 
     if( !fp ) {
        fp = fopen("armor.out", "w");
        assert(fp);
     }
-  #endif
+#endif
 
     if( DBG_FILTER )
        log_debug("armor-filter: control: %d\n", control );
 
     if( DBG_FILTER )
        log_debug("armor-filter: control: %d\n", control );
@@ -857,7 +861,7 @@ armor_filter( void *opaque, int control,
                    rc = -1;
            }
            else if( afx->faked ) {
                    rc = -1;
            }
            else if( afx->faked ) {
-               unsigned int hashes = afx->hashes;
+               unsigned int hashes = afx->hashes;
                 const byte *sesmark;
                 size_t sesmarklen;
                 
                 const byte *sesmark;
                 size_t sesmarklen;
                 
@@ -868,9 +872,12 @@ armor_filter( void *opaque, int control,
                /* the buffer is at least 15+n*15 bytes long, so it
                 * is easy to construct the packets */
 
                /* the buffer is at least 15+n*15 bytes long, so it
                 * is easy to construct the packets */
 
-               hashes &= 1|2|4|8;
+               hashes &= 1|2|4|8|16|32|64;
                if( !hashes ) {
                    hashes |= 4;  /* default to MD 5 */
                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;
                }
                    if( opt.pgp2_workarounds )
                        afx->pgp2mode = 1;
                }
@@ -881,14 +888,18 @@ armor_filter( void *opaque, int control,
                 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
                 buf[n++] = CTRLPKT_CLEARSIGN_START; 
                 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
                 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
                 buf[n++] = CTRLPKT_CLEARSIGN_START; 
                 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
-                if( hashes & 1 ) 
+                if( hashes & 1 )
                     buf[n++] = DIGEST_ALGO_RMD160;
                     buf[n++] = DIGEST_ALGO_RMD160;
-                if( hashes & 2 ) 
+                if( hashes & 2 )
                     buf[n++] = DIGEST_ALGO_SHA1;
                     buf[n++] = DIGEST_ALGO_SHA1;
-                if( hashes & 4 ) 
+                if( hashes & 4 )
                     buf[n++] = DIGEST_ALGO_MD5;
                     buf[n++] = DIGEST_ALGO_MD5;
-                if( hashes & 8 ) 
-                    buf[n++] = DIGEST_ALGO_TIGER;
+                if( hashes & 8 )
+                    buf[n++] = DIGEST_ALGO_SHA256;
+                if( hashes & 16 )
+                    buf[n++] = DIGEST_ALGO_SHA384;
+                if( hashes & 32 )
+                    buf[n++] = DIGEST_ALGO_SHA512;
                 buf[1] = n - 2;
 
                /* followed by a plaintext packet */
                 buf[1] = n - 2;
 
                /* followed by a plaintext packet */
@@ -905,16 +916,17 @@ armor_filter( void *opaque, int control,
        }
        else
            rc = radix64_read( afx, a, &n, buf, size );
        }
        else
            rc = radix64_read( afx, a, &n, buf, size );
-      #if 0
+#if 0
        if( n )
            if( fwrite(buf, n, 1, fp ) != 1 )
                BUG();
        if( n )
            if( fwrite(buf, n, 1, fp ) != 1 )
                BUG();
-      #endif
+#endif
        *ret_len = n;
     }
     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
        if( !afx->status ) { /* write the header line */
            const char *s;
        *ret_len = n;
     }
     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
        if( !afx->status ) { /* write the header line */
            const char *s;
+            STRLIST comment = opt.comments;
 
            if( afx->what >= DIM(head_strings) )
                log_bug("afx->what=%d", afx->what);
 
            if( afx->what >= DIM(head_strings) )
                log_bug("afx->what=%d", afx->what);
@@ -925,29 +937,31 @@ armor_filter( void *opaque, int control,
                iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
                                              PRINTABLE_OS_NAME ")" LF );
 
                iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
                                              PRINTABLE_OS_NAME ")" LF );
 
-           /* write the comment string or a default one */
-           s = opt.comment_string;
-           if( s && *s ) {
+           /* Write the comment string. */
+           for(s=comment? comment->d:NULL; comment;
+                comment=comment->next,s=comment->d)
+             {
                iobuf_writestr(a, "Comment: " );
                iobuf_writestr(a, "Comment: " );
-               for( ; *s; s++ ) {
+               for ( ; *s; s++ )
+                  {
                    if( *s == '\n' )
                    if( *s == '\n' )
-                       iobuf_writestr(a, "\\n" );
+                      iobuf_writestr(a, "\\n" );
                    else if( *s == '\r' )
                    else if( *s == '\r' )
-                       iobuf_writestr(a, "\\r" );
+                      iobuf_writestr(a, "\\r" );
                    else if( *s == '\v' )
                    else if( *s == '\v' )
-                       iobuf_writestr(a, "\\v" );
+                      iobuf_writestr(a, "\\v" );
                    else
                    else
-                       iobuf_put(a, *s );
-               }
+                      iobuf_put(a, *s );
+                  }
                iobuf_writestr(a, LF );
                iobuf_writestr(a, LF );
-           }
+              }
 
            if ( afx->hdrlines ) {
                 for ( s = afx->hdrlines; *s; s++ ) {
 
            if ( afx->hdrlines ) {
                 for ( s = afx->hdrlines; *s; s++ ) {
-                  #ifdef HAVE_DOSISH_SYSTEM
+#ifdef HAVE_DOSISH_SYSTEM
                     if ( *s == '\n' )
                         iobuf_put( a, '\r');
                     if ( *s == '\n' )
                         iobuf_put( a, '\r');
-                  #endif
+#endif
                     iobuf_put(a, *s );
                 }
             }
                     iobuf_put(a, *s );
                 }
             }
@@ -1065,7 +1079,7 @@ armor_filter( void *opaque, int control,
        if( afx->qp_detected )
            log_error(_("quoted printable character in armor - "
                        "probably a buggy MTA has been used\n") );
        if( afx->qp_detected )
            log_error(_("quoted printable character in armor - "
                        "probably a buggy MTA has been used\n") );
-       m_free( afx->buffer );
+       xfree ( afx->buffer );
        afx->buffer = NULL;
     }
     else if( control == IOBUFCTRL_DESC )
        afx->buffer = NULL;
     }
     else if( control == IOBUFCTRL_DESC )
@@ -1082,7 +1096,7 @@ make_radix64_string( const byte *data, size_t len )
 {
     char *buffer, *p;
 
 {
     char *buffer, *p;
 
-    buffer = p = m_alloc( (len+2)/3*4 + 1 );
+    buffer = p = xmalloc ( (len+2)/3*4 + 1 );
     for( ; len >= 3 ; len -= 3, data += 3 ) {
        *p++ = bintoasc[(data[0] >> 2) & 077];
        *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
     for( ; len >= 3 ; len -= 3, data += 3 ) {
        *p++ = bintoasc[(data[0] >> 2) & 077];
        *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
@@ -1142,14 +1156,14 @@ unarmor_pump_new (void)
 
     if( !is_initialized )
         initialize();
 
     if( !is_initialized )
         initialize();
-    x = m_alloc_clear (sizeof *x);
+    x = xcalloc (1,sizeof *x);
     return x;
 }
 
 void
 unarmor_pump_release (UnarmorPump x)
 {
     return x;
 }
 
 void
 unarmor_pump_release (UnarmorPump x)
 {
-    m_free (x);
+    xfree (x);
 }
 
 /* 
 }
 
 /* 
@@ -1318,5 +1332,3 @@ unarmor_pump (UnarmorPump x, int c)
 
     return rval;
 }
 
     return rval;
 }
-
-