/[winpt]/trunk/Gnupg/armor.c
ViewVC logotype

Diff of /trunk/Gnupg/armor.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 308 by twoaday, Sat Aug 5 10:31:06 2006 UTC revision 309 by twoaday, Sat Apr 7 11:07:07 2007 UTC
# Line 1040  enum unarmor_state_e { Line 1040  enum unarmor_state_e {
1040      STA_ready      STA_ready
1041  };  };
1042    
 struct unarmor_pump_s {  
     enum unarmor_state_e state;  
     byte val;  
     int checkcrc;  
     int pos;   /* counts from 0..3 */  
     u32 crc;  
     u32 mycrc; /* the one store in the data */  
 };  
   
   
   
 UnarmorPump  
 unarmor_pump_new (void)  
 {  
     UnarmorPump x;  
       
     if( !is_initialized )  
         initialize();  
     x = calloc (1, sizeof *x);  
     return x;  
 }  
   
 void  
 unarmor_pump_release (UnarmorPump x)  
 {  
     safe_free (x);  
 }  
   
 /*  
  * Get the next character from the ascii armor taken from the gpg_iobuf_t  
  * created earlier by unarmor_pump_new().  
  * Return:  c = Character  
  *        256 = ignore this value  
  *         -1 = End of current armor  
  *         -2 = Premature EOF (not used)  
  *         -3 = Invalid armor  
  */  
 int  
 unarmor_pump (UnarmorPump x, int c)  
 {  
     int rval = 256; /* default is to ignore the return value */  
       
     switch (x->state) {  
     case STA_init:  
     {  
         byte tmp[1];  
         tmp[0] = c;  
         if ( is_armored (tmp) )  
             x->state = c == '-'? STA_first_dash : STA_wait_newline;  
         else {  
             x->state = STA_bypass;  
             return c;  
         }  
     }  
     break;  
     case STA_bypass:  
         return c; /* return here to avoid crc calculation */  
     case STA_wait_newline:  
         if (c == '\n')  
             x->state = STA_wait_dash;  
         break;  
     case STA_wait_dash:  
         x->state = c == '-'? STA_first_dash : STA_wait_newline;  
         break;  
     case STA_first_dash: /* just need for initalization */  
         x->pos = 0;  
         x->state = STA_compare_header;  
     case STA_compare_header:  
         if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {  
             if ( x->pos == 28 )  
                 x->state = STA_found_header_wait_newline;  
         }  
         else  
             x->state = c == '\n'? STA_wait_dash : STA_wait_newline;  
         break;  
     case STA_found_header_wait_newline:  
         /* to make CR,LF issues easier we simply allow for white space  
            behind the 5 dashes */  
         if ( c == '\n' )  
             x->state = STA_skip_header_lines;  
         else if ( c != '\r' && c != ' ' && c != '\t' )  
             x->state = STA_wait_dash; /* garbage after the header line */  
         break;  
     case STA_skip_header_lines:  
         /* i.e. wait for one empty line */  
         if ( c == '\n' ) {  
             x->state = STA_read_data;  
             x->crc = CRCINIT;  
             x->val = 0;  
             x->pos = 0;  
         }  
         else if ( c != '\r' && c != ' ' && c != '\t' )  
             x->state = STA_skip_header_lines_non_ws;  
         break;  
     case STA_skip_header_lines_non_ws:  
         /* like above but we already encountered non white space */  
         if ( c == '\n' )  
             x->state = STA_skip_header_lines;  
         break;  
     case STA_read_data:  
         /* fixme: we don't check for the trailing dash lines but rely  
          * on the armor stop characters */  
         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )  
             break; /* skip all kind of white space */  
           
         if( c == '=' ) { /* pad character: stop */  
             if( x->pos == 1 ) /* in this case val has some value */  
                 rval = x->val;  
             x->state = STA_wait_crc;  
             break;  
         }  
           
         {  
             int c2;  
             if( (c = asctobin[(c2=c)]) == 255 ) {  
                 char msg[128];  
                 _snprintf( msg, sizeof msg-1, "invalid radix64 character %02x skipped\n", c2);  
                 set_armor_error( msg );  
                 break;  
             }  
         }  
           
         switch(x->pos) {  
         case 0:  
             x->val = c << 2;  
             break;  
         case 1:  
             x->val |= (c>>4)&3;  
             rval = x->val;  
             x->val = (c<<4)&0xf0;  
             break;  
         case 2:  
             x->val |= (c>>2)&15;  
             rval = x->val;  
             x->val = (c<<6)&0xc0;  
             break;  
         case 3:  
             x->val |= c&0x3f;  
             rval = x->val;  
             break;  
         }  
         x->pos = (x->pos+1) % 4;  
         break;  
     case STA_wait_crc:  
         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )  
             break; /* skip ws and pad characters */  
         /* assume that we are at the next line */  
         x->state = STA_read_crc;  
         x->pos = 0;  
         x->mycrc = 0;  
     case STA_read_crc:  
         if( (c = asctobin[c]) == 255 ) {  
             rval = -1; /* ready */  
             if( x->crc != x->mycrc ) {  
                 char msg[128];  
                 _snprintf( msg, sizeof msg-1, "CRC error; %06lx - %06lx\n",  
                         (ulong)x->crc, (ulong)x->mycrc);  
                 set_armor_error( msg );  
                 if ( invalid_crc() )  
                     rval = -3;  
             }  
             x->state = STA_ready; /* not sure whether this is correct */  
             break;  
         }  
           
         switch(x->pos) {  
         case 0:  
             x->val = c << 2;  
             break;  
         case 1:  
             x->val |= (c>>4)&3;  
             x->mycrc |= x->val << 16;  
             x->val = (c<<4)&0xf0;  
             break;  
         case 2:  
             x->val |= (c>>2)&15;  
             x->mycrc |= x->val << 8;  
             x->val = (c<<6)&0xc0;  
             break;  
         case 3:  
             x->val |= c&0x3f;  
             x->mycrc |= x->val;  
             break;  
         }  
         x->pos = (x->pos+1) % 4;  
         break;  
     case STA_ready:  
         rval = -1;  
         break;  
     }  
       
     if ( !(rval & ~255) ) { /* compute the CRC */  
         x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];  
         x->crc &= 0x00ffffff;  
     }  
       
     return rval;  
 }  
   
1043    

Legend:
Removed from v.308  
changed lines
  Added in v.309

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26