summaryrefslogtreecommitdiffstats
path: root/common/b64enc.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2008-04-07 21:31:12 +0200
committerWerner Koch <wk@gnupg.org>2008-04-07 21:31:12 +0200
commit86f35a55d01f1ef7aec2b303a722ff5733148aa4 (patch)
tree99cb8163a8db0deba06608fec178ea9ad602e5c0 /common/b64enc.c
parentFixed last yat2m change. (diff)
downloadgnupg2-86f35a55d01f1ef7aec2b303a722ff5733148aa4.tar.xz
gnupg2-86f35a55d01f1ef7aec2b303a722ff5733148aa4.zip
Minor cleanups.
Implemented key helper kdns
Diffstat (limited to 'common/b64enc.c')
-rw-r--r--common/b64enc.c157
1 files changed, 148 insertions, 9 deletions
diff --git a/common/b64enc.c b/common/b64enc.c
index e886f9403..4722bd1e1 100644
--- a/common/b64enc.c
+++ b/common/b64enc.c
@@ -1,5 +1,5 @@
/* b64enc.c - Simple Base64 encoder.
- * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2003, 2004, 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -30,20 +30,121 @@
#define B64ENC_DID_HEADER 1
#define B64ENC_DID_TRAILER 2
#define B64ENC_NO_LINEFEEDS 16
-
+#define B64ENC_USE_PGPCRC 32
/* The base-64 character list */
static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
+/* Stuff required to create the OpenPGP CRC. This crc_table has been
+ created using this code:
+
+ #include <stdio.h>
+ #include <stdint.h>
+
+ #define CRCPOLY 0x864CFB
+
+ int
+ main (void)
+ {
+ int i, j;
+ uint32_t t;
+ uint32_t crc_table[256];
+
+ crc_table[0] = 0;
+ for (i=j=0; j < 128; j++ )
+ {
+ t = crc_table[j];
+ if ( (t & 0x00800000) )
+ {
+ t <<= 1;
+ crc_table[i++] = t ^ CRCPOLY;
+ crc_table[i++] = t;
+ }
+ else
+ {
+ t <<= 1;
+ crc_table[i++] = t;
+ crc_table[i++] = t ^ CRCPOLY;
+ }
+ }
+
+ puts ("static const u32 crc_table[256] = {");
+ for (i=j=0; i < 256; i++)
+ {
+ printf ("%s 0x%08lx", j? "":" ", (unsigned long)crc_table[i]);
+ if (i != 255)
+ {
+ putchar (',');
+ if ( ++j > 5)
+ {
+ j = 0;
+ putchar ('\n');
+ }
+ }
+ }
+ puts ("\n};");
+ return 0;
+ }
+*/
+#define CRCINIT 0xB704CE
+static const u32 crc_table[256] = {
+ 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a,
+ 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf,
+ 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272,
+ 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e,
+ 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa,
+ 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f,
+ 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b,
+ 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7,
+ 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a,
+ 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af,
+ 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29,
+ 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5,
+ 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1,
+ 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, 0x30563856, 0x30d074ad,
+ 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099,
+ 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375,
+ 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821,
+ 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4,
+ 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049,
+ 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5,
+ 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791,
+ 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52,
+ 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66,
+ 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a,
+ 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337,
+ 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2,
+ 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6,
+ 0x62b54340, 0x62330fbb, 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a,
+ 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e,
+ 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132,
+ 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506,
+ 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea,
+ 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c,
+ 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9,
+ 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604,
+ 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8,
+ 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc,
+ 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69,
+ 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d,
+ 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1,
+ 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c,
+ 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9,
+ 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538
+};
+
+
/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL
and not an empty string, this string will be used as the title for
the armor lines, with TITLE being an empty string, we don't write
the header lines and furthermore even don't write any linefeeds.
- With TITLE beeing NULL, we merely don't write header but make sure
- that lines are not too long. Note, that we don't write any output
- unless at least one byte get written using b64enc_write. */
+ If TITLE starts with "PGP " the OpenPGP CRC checksum will be
+ written as well. With TITLE beeing NULL, we merely don't write
+ header but make sure that lines are not too long. Note, that we
+ don't write any output unless at least one byte get written using
+ b64enc_write. */
gpg_error_t
b64enc_start (struct b64state *state, FILE *fp, const char *title)
{
@@ -53,9 +154,14 @@ b64enc_start (struct b64state *state, FILE *fp, const char *title)
state->flags |= B64ENC_NO_LINEFEEDS;
else if (title)
{
+ if (!strncmp (title, "PGP ", 4))
+ {
+ state->flags |= B64ENC_USE_PGPCRC;
+ state->crc = CRCINIT;
+ }
state->title = xtrystrdup (title);
if (!state->title)
- return gpg_error_from_syserror ();
+ return gpg_error_from_syserror ();
}
return 0;
}
@@ -88,7 +194,11 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
|| fputs (state->title, fp) == EOF
|| fputs ("-----\n", fp) == EOF)
goto write_error;
+ if ( (state->flags & B64ENC_USE_PGPCRC)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
}
+
state->flags |= B64ENC_DID_HEADER;
}
@@ -96,7 +206,17 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes)
quad_count = state->quad_count;
assert (idx < 4);
memcpy (radbuf, state->radbuf, idx);
-
+
+ if ( (state->flags & B64ENC_USE_PGPCRC) )
+ {
+ size_t n;
+ u32 crc = state->crc;
+
+ for (p=buffer, n=nbytes; n; p++, n-- )
+ crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ *p];
+ state->crc = (crc & 0x00ffffff);
+ }
+
for (p=buffer; nbytes; p++, nbytes--)
{
radbuf[idx++] = *p;
@@ -138,6 +258,7 @@ b64enc_finish (struct b64state *state)
unsigned char radbuf[4];
int idx, quad_count;
FILE *fp;
+ char tmp[4];
if (!(state->flags & B64ENC_DID_HEADER))
goto cleanup;
@@ -151,8 +272,6 @@ b64enc_finish (struct b64state *state)
if (idx)
{
- char tmp[4];
-
tmp[0] = bintoasc[(*radbuf>>2)&077];
if (idx == 1)
{
@@ -186,6 +305,26 @@ b64enc_finish (struct b64state *state)
&& !(state->flags & B64ENC_NO_LINEFEEDS)
&& fputs ("\n", fp) == EOF)
goto write_error;
+
+ if ( (state->flags & B64ENC_USE_PGPCRC) )
+ {
+ /* Write the CRC. */
+ putc ('=', fp);
+ radbuf[0] = state->crc >>16;
+ radbuf[1] = state->crc >> 8;
+ radbuf[2] = state->crc;
+ tmp[0] = bintoasc[(*radbuf>>2)&077];
+ tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
+ tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
+ tmp[3] = bintoasc[radbuf[2]&077];
+ for (idx=0; idx < 4; idx++)
+ putc (tmp[idx], fp);
+ if (ferror (fp))
+ goto write_error;
+ if (!(state->flags & B64ENC_NO_LINEFEEDS)
+ && fputs ("\n", fp) == EOF)
+ goto write_error;
+ }
if (state->title)
{