diff options
author | Werner Koch <[email protected]> | 2001-11-19 10:25:00 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2001-11-19 10:25:00 +0000 |
commit | 2b99de5a5deb73b26978969547e69cb086707da4 (patch) | |
tree | 2147976cfc0cde7b8f754ba0f5f1104c652ce969 /sm/import.c | |
parent | Base code for gpgsm --verify does work (diff) | |
download | gnupg-2b99de5a5deb73b26978969547e69cb086707da4.tar.gz gnupg-2b99de5a5deb73b26978969547e69cb086707da4.zip |
gpgsm --verify does now work like gpg including the
--enable-special-filenames option.
Diffstat (limited to 'sm/import.c')
-rw-r--r-- | sm/import.c | 188 |
1 files changed, 178 insertions, 10 deletions
diff --git a/sm/import.c b/sm/import.c index 8dc36c1ad..8913f8092 100644 --- a/sm/import.c +++ b/sm/import.c @@ -36,32 +36,200 @@ struct reader_cb_parm_s { FILE *fp; + unsigned char line[1024]; + int linelen; + int readpos; + int have_lf; + unsigned long line_counter; + + int identified; + int is_pem; + int stop_seen; + + struct { + int idx; + unsigned char val; + int stop_seen; + } base64; + + +}; + +/* static unsigned char bintoasc[] = */ +/* "ABCDEFGHIJKLMNOPQRSTUVWXYZ" */ +/* "abcdefghijklmnopqrstuvwxyz" */ +/* "0123456789+/"; */ + +static unsigned char asctobin[256] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff }; + static int reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) { struct reader_cb_parm_s *parm = cb_value; size_t n; - int c = 0; + int c, c2; *nread = 0; if (!buffer) return -1; /* not supported */ - for (n=0; n < count; n++) + next: + if (!parm->linelen) { - c = getc (parm->fp); - if (c == EOF) + /* read an entire line or up to the size of the buffer */ + parm->line_counter++; + parm->have_lf = 0; + for (n=0; n < DIM(parm->line);) + { + c = getc (parm->fp); + if (c == EOF) + { + if (ferror (parm->fp)) + return -1; + break; + } + parm->line[n++] = c; + if (c == '\n') + { + parm->have_lf = 1; + /* FIXME: we need to skip overlong lines while detecting + the dashed lines */ + break; + } + } + parm->linelen = n; + if (!n) + return -1; /* eof */ + parm->readpos = 0; + } + + if (!parm->identified) + { + if (parm->line_counter == 1 && !parm->have_lf) + { + /* first line too long - assume DER encoding */ + parm->is_pem = 0; + } + else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30) + { + /* the very first bytes does pretty much look like a SEQUENCE tag*/ + parm->is_pem = 0; + } + else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) + && strncmp (parm->line+11, "PGP ", 4) ) + { + /* Fixme: we must only compare if the line really starts at + the beginning */ + parm->is_pem = 1; + parm->linelen = parm->readpos = 0; + } + else + { + parm->linelen = parm->readpos = 0; + goto next; + } + parm->identified = 1; + parm->base64.stop_seen = 0; + parm->base64.idx = 0; + } + + + n = 0; + if (parm->is_pem) + { + if (parm->have_lf && !strncmp (parm->line, "-----END ", 9)) + { + parm->identified = 0; + parm->linelen = parm->readpos = 0; + /* let us return 0 */ + } + else if (parm->stop_seen) + { /* skip the rest of the line */ + parm->linelen = parm->readpos = 0; + } + else { - if ( ferror (parm->fp) ) - return -1; - if (n) - break; /* return what we have before an EOF */ - return -1; + int idx = parm->base64.idx; + unsigned char val = parm->base64.val; + + while (n < count && parm->readpos < parm->linelen ) + { + c = parm->line[parm->readpos++]; + if (c == '\n' || c == ' ' || c == '\r' || c == '\t') + continue; + if (c == '=') + { /* pad character: stop */ + if (idx == 1) + buffer[n++] = val; + parm->stop_seen = 1; + break; + } + if( (c = asctobin[(c2=c)]) == 255 ) + { + log_error (_("invalid radix64 character %02x skipped\n"), + c2); + continue; + } + switch (idx) + { + case 0: + val = c << 2; + break; + case 1: + val |= (c>>4)&3; + buffer[n++] = val; + val = (c<<4)&0xf0; + break; + case 2: + val |= (c>>2)&15; + buffer[n++] = val; + val = (c<<6)&0xc0; + break; + case 3: + val |= c&0x3f; + buffer[n++] = val; + break; + } + idx = (idx+1) % 4; + } + if (parm->readpos == parm->linelen) + parm->linelen = parm->readpos = 0; + + parm->base64.idx = idx; + parm->base64.val = val; } - *(byte *)buffer++ = c; + } + else + { /* DER encoded */ + while (n < count && parm->readpos < parm->linelen) + buffer[n++] = parm->line[parm->readpos++]; + if (parm->readpos == parm->linelen) + parm->linelen = parm->readpos = 0; } *nread = n; |