#include "postgres.h"#include "px.h"#include "mbuf.h"#include "pgp.h"
Go to the source code of this file.
Defines | |
| #define | CRC24_INIT 0x00b704ceL |
| #define | CRC24_POLY 0x01864cfbL |
Functions | |
| static int | b64_encode (const uint8 *src, unsigned len, uint8 *dst) |
| static int | b64_decode (const uint8 *src, unsigned len, uint8 *dst) |
| static unsigned | b64_enc_len (unsigned srclen) |
| static unsigned | b64_dec_len (unsigned srclen) |
| static long | crc24 (const uint8 *data, unsigned len) |
| int | pgp_armor_encode (const uint8 *src, unsigned len, uint8 *dst) |
| static const uint8 * | find_str (const uint8 *data, const uint8 *data_end, const char *str, int strlen) |
| static int | find_header (const uint8 *data, const uint8 *datend, const uint8 **start_p, int is_end) |
| int | pgp_armor_decode (const uint8 *src, unsigned len, uint8 *dst) |
| unsigned | pgp_armor_enc_len (unsigned len) |
| unsigned | pgp_armor_dec_len (unsigned len) |
Variables | |
| static const unsigned char | _base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" |
| static const char * | armor_header = "-----BEGIN PGP MESSAGE-----\n\n" |
| static const char * | armor_footer = "\n-----END PGP MESSAGE-----\n" |
| #define CRC24_INIT 0x00b704ceL |
Definition at line 186 of file pgp-armor.c.
| #define CRC24_POLY 0x01864cfbL |
Definition at line 187 of file pgp-armor.c.
| static unsigned b64_dec_len | ( | unsigned | srclen | ) | [static] |
Definition at line 173 of file pgp-armor.c.
Referenced by pgp_armor_dec_len().
{
return (srclen * 3) >> 2;
}
Definition at line 96 of file pgp-armor.c.
Referenced by pgp_armor_decode().
{
const uint8 *srcend = src + len,
*s = src;
uint8 *p = dst;
char c;
unsigned b = 0;
unsigned long buf = 0;
int pos = 0,
end = 0;
while (s < srcend)
{
c = *s++;
if (c >= 'A' && c <= 'Z')
b = c - 'A';
else if (c >= 'a' && c <= 'z')
b = c - 'a' + 26;
else if (c >= '0' && c <= '9')
b = c - '0' + 52;
else if (c == '+')
b = 62;
else if (c == '/')
b = 63;
else if (c == '=')
{
/*
* end sequence
*/
if (!end)
{
if (pos == 2)
end = 1;
else if (pos == 3)
end = 2;
else
return PXE_PGP_CORRUPT_ARMOR;
}
b = 0;
}
else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
continue;
else
return PXE_PGP_CORRUPT_ARMOR;
/*
* add it to buffer
*/
buf = (buf << 6) + b;
pos++;
if (pos == 4)
{
*p++ = (buf >> 16) & 255;
if (end == 0 || end > 1)
*p++ = (buf >> 8) & 255;
if (end == 0 || end > 2)
*p++ = buf & 255;
buf = 0;
pos = 0;
}
}
if (pos != 0)
return PXE_PGP_CORRUPT_ARMOR;
return p - dst;
}
| static unsigned b64_enc_len | ( | unsigned | srclen | ) | [static] |
Definition at line 164 of file pgp-armor.c.
Referenced by pgp_armor_enc_len().
{
/*
* 3 bytes will be converted to 4, linefeed after 76 chars
*/
return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4);
}
Definition at line 46 of file pgp-armor.c.
References _base64, buf, and end.
Referenced by pgp_armor_encode().
{
uint8 *p,
*lend = dst + 76;
const uint8 *s,
*end = src + len;
int pos = 2;
unsigned long buf = 0;
s = src;
p = dst;
while (s < end)
{
buf |= *s << (pos << 3);
pos--;
s++;
/*
* write it out
*/
if (pos < 0)
{
*p++ = _base64[(buf >> 18) & 0x3f];
*p++ = _base64[(buf >> 12) & 0x3f];
*p++ = _base64[(buf >> 6) & 0x3f];
*p++ = _base64[buf & 0x3f];
pos = 2;
buf = 0;
}
if (p >= lend)
{
*p++ = '\n';
lend = p + 76;
}
}
if (pos != 2)
{
*p++ = _base64[(buf >> 18) & 0x3f];
*p++ = _base64[(buf >> 12) & 0x3f];
*p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';
*p++ = '=';
}
return p - dst;
}
| static long crc24 | ( | const uint8 * | data, | |
| unsigned | len | |||
| ) | [static] |
Definition at line 189 of file pgp-armor.c.
References i.
Referenced by pgp_armor_decode(), and pgp_armor_encode().
{
unsigned crc = CRC24_INIT;
int i;
while (len--)
{
crc ^= (*data++) << 16;
for (i = 0; i < 8; i++)
{
crc <<= 1;
if (crc & 0x1000000)
crc ^= CRC24_POLY;
}
}
return crc & 0xffffffL;
}
| static int find_header | ( | const uint8 * | data, | |
| const uint8 * | datend, | |||
| const uint8 ** | start_p, | |||
| int | is_end | |||
| ) | [static] |
Definition at line 265 of file pgp-armor.c.
References find_str(), memcmp(), and NULL.
Referenced by pgp_armor_decode().
{
const uint8 *p = data;
static const char *start_sep = "-----BEGIN";
static const char *end_sep = "-----END";
const char *sep = is_end ? end_sep : start_sep;
/* find header line */
while (1)
{
p = find_str(p, datend, sep, strlen(sep));
if (p == NULL)
return PXE_PGP_CORRUPT_ARMOR;
/* it must start at beginning of line */
if (p == data || *(p - 1) == '\n')
break;
p += strlen(sep);
}
*start_p = p;
p += strlen(sep);
/* check if header text ok */
for (; p < datend && *p != '-'; p++)
{
/* various junk can be there, but definitely not line-feed */
if (*p >= ' ')
continue;
return PXE_PGP_CORRUPT_ARMOR;
}
if (datend - p < 5 || memcmp(p, sep, 5) != 0)
return PXE_PGP_CORRUPT_ARMOR;
p += 5;
/* check if at end of line */
if (p < datend)
{
if (*p != '\n' && *p != '\r')
return PXE_PGP_CORRUPT_ARMOR;
if (*p == '\r')
p++;
if (p < datend && *p == '\n')
p++;
}
return p - *start_p;
}
| static const uint8* find_str | ( | const uint8 * | data, | |
| const uint8 * | data_end, | |||
| const char * | str, | |||
| int | strlen | |||
| ) | [static] |
Definition at line 242 of file pgp-armor.c.
References memcmp(), and NULL.
Referenced by find_header().
| unsigned pgp_armor_dec_len | ( | unsigned | len | ) |
Definition at line 380 of file pgp-armor.c.
References b64_dec_len().
Referenced by pg_dearmor().
{
return b64_dec_len(len);
}
Definition at line 313 of file pgp-armor.c.
References b64_decode(), buf, crc24(), find_header(), and NULL.
Referenced by pg_dearmor().
{
const uint8 *p = src;
const uint8 *data_end = src + len;
long crc;
const uint8 *base64_start,
*armor_end;
const uint8 *base64_end = NULL;
uint8 buf[4];
int hlen;
int res = PXE_PGP_CORRUPT_ARMOR;
/* armor start */
hlen = find_header(src, data_end, &p, 0);
if (hlen <= 0)
goto out;
p += hlen;
/* armor end */
hlen = find_header(p, data_end, &armor_end, 1);
if (hlen <= 0)
goto out;
/* skip comments - find empty line */
while (p < armor_end && *p != '\n' && *p != '\r')
{
p = memchr(p, '\n', armor_end - p);
if (!p)
goto out;
/* step to start of next line */
p++;
}
base64_start = p;
/* find crc pos */
for (p = armor_end; p >= base64_start; p--)
if (*p == '=')
{
base64_end = p - 1;
break;
}
if (base64_end == NULL)
goto out;
/* decode crc */
if (b64_decode(p + 1, 4, buf) != 3)
goto out;
crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2];
/* decode data */
res = b64_decode(base64_start, base64_end - base64_start, dst);
/* check crc */
if (res >= 0 && crc24(dst, res) != crc)
res = PXE_PGP_CORRUPT_ARMOR;
out:
return res;
}
| unsigned pgp_armor_enc_len | ( | unsigned | len | ) |
Definition at line 374 of file pgp-armor.c.
References armor_footer, armor_header, and b64_enc_len().
Referenced by pg_armor().
{
return b64_enc_len(len) + strlen(armor_header) + strlen(armor_footer) + 16;
}
Definition at line 208 of file pgp-armor.c.
References _base64, armor_footer, armor_header, b64_encode(), and crc24().
Referenced by pg_armor().
{
int n;
uint8 *pos = dst;
unsigned crc = crc24(src, len);
n = strlen(armor_header);
memcpy(pos, armor_header, n);
pos += n;
n = b64_encode(src, len, pos);
pos += n;
if (*(pos - 1) != '\n')
*pos++ = '\n';
*pos++ = '=';
pos[3] = _base64[crc & 0x3f];
crc >>= 6;
pos[2] = _base64[crc & 0x3f];
crc >>= 6;
pos[1] = _base64[crc & 0x3f];
crc >>= 6;
pos[0] = _base64[crc & 0x3f];
pos += 4;
n = strlen(armor_footer);
memcpy(pos, armor_footer, n);
pos += n;
return pos - dst;
}
const unsigned char _base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" [static] |
Definition at line 42 of file pgp-armor.c.
Referenced by b64_encode(), and pgp_armor_encode().
const char* armor_footer = "\n-----END PGP MESSAGE-----\n" [static] |
Definition at line 183 of file pgp-armor.c.
Referenced by pgp_armor_enc_len(), and pgp_armor_encode().
const char* armor_header = "-----BEGIN PGP MESSAGE-----\n\n" [static] |
Definition at line 182 of file pgp-armor.c.
Referenced by pgp_armor_enc_len(), and pgp_armor_encode().
1.7.1