#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().