PostgreSQL Source Code: contrib/pgcrypto/pgp-armor.c File Reference (original) (raw)

#include "[postgres.h](postgres%5F8h%5Fsource.html)"
#include "[pgp.h](pgp%5F8h%5Fsource.html)"
#include "[px.h](px%5F8h%5Fsource.html)"

Go to the source code of this file.

Functions
static int pg_base64_encode (const uint8 *src, unsigned len, uint8 *dst)
static int pg_base64_decode (const uint8 *src, unsigned len, uint8 *dst)
static unsigned pg_base64_enc_len (unsigned srclen)
static unsigned pg_base64_dec_len (unsigned srclen)
static long crc24 (const uint8 *data, unsigned len)
void pgp_armor_encode (const uint8 *src, unsigned len, StringInfo dst, int num_headers, char **keys, char **values)
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, int len, StringInfo dst)
int pgp_extract_armor_headers (const uint8 *src, unsigned len, int *nheaders, char ***keys, char ***values)
Variables
static const unsigned char _base64 []
static const char *const armor_header = "-----BEGIN PGP MESSAGE-----\n"
static const char *const armor_footer = "\n-----END PGP MESSAGE-----\n"

CRC24_INIT

#define CRC24_INIT 0x00b704ceL

CRC24_POLY

#define CRC24_POLY 0x01864cfbL

crc24()

static long crc24 ( const uint8 * data, unsigned len ) static

find_header()

static int find_header ( const uint8 * data, const uint8 * datend, const uint8 ** start_p, int is_end ) static

Definition at line 266 of file pgp-armor.c.

268{

270 static const char *start_sep = "-----BEGIN";

271 static const char *end_sep = "-----END";

272 const char *sep = is_end ? end_sep : start_sep;

273

274

275 while (1)

276 {

277 p = find_str(p, datend, sep, strlen(sep));

278 if (p == NULL)

280

281 if (p == data || *(p - 1) == '\n')

282 break;

283 p += strlen(sep);

284 }

285 *start_p = p;

286 p += strlen(sep);

287

288

289 for (; p < datend && *p != '-'; p++)

290 {

291

292 if (*p >= ' ')

293 continue;

295 }

296 if (datend - p < 5 || memcmp(p, sep, 5) != 0)

298 p += 5;

299

300

301 if (p < datend)

302 {

303 if (*p != '\n' && *p != '\r')

305 if (*p == '\r')

306 p++;

307 if (p < datend && *p == '\n')

308 p++;

309 }

310 return p - *start_p;

311}

static const uint8 * find_str(const uint8 *data, const uint8 *data_end, const char *str, int strlen)

#define PXE_PGP_CORRUPT_ARMOR

References data, find_str(), and PXE_PGP_CORRUPT_ARMOR.

Referenced by pgp_armor_decode(), and pgp_extract_armor_headers().

find_str()

static const uint8 * find_str ( const uint8 * data, const uint8 * data_end, const char * str, int strlen ) static

Definition at line 243 of file pgp-armor.c.

244{

246

247 if (!strlen)

248 return NULL;

249 if (data_end - data < strlen)

250 return NULL;

251 while (p < data_end)

252 {

253 p = memchr(p, str[0], data_end - p);

254 if (p == NULL)

255 return NULL;

256 if (p + strlen > data_end)

257 return NULL;

258 if (memcmp(p, str, strlen) == 0)

259 return p;

260 p++;

261 }

262 return NULL;

263}

References data, and str.

Referenced by find_header().

pg_base64_dec_len()

static unsigned pg_base64_dec_len ( unsigned srclen) static

pg_base64_decode()

static int pg_base64_decode ( const uint8 * src, unsigned len, uint8 * dst ) static

Definition at line 95 of file pgp-armor.c.

96{

97 const uint8 *srcend = src + len,

98 *s = src;

100 char c;

101 unsigned b = 0;

102 unsigned long buf = 0;

103 int pos = 0,

104 end = 0;

105

106 while (s < srcend)

107 {

108 c = *s++;

109 if (c >= 'A' && c <= 'Z')

110 b = c - 'A';

111 else if (c >= 'a' && c <= 'z')

112 b = c - 'a' + 26;

113 else if (c >= '0' && c <= '9')

114 b = c - '0' + 52;

115 else if (c == '+')

116 b = 62;

117 else if (c == '/')

118 b = 63;

119 else if (c == '=')

120 {

121

122

123

124 if (!end)

125 {

126 if (pos == 2)

127 end = 1;

128 else if (pos == 3)

129 end = 2;

130 else

132 }

133 b = 0;

134 }

135 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')

136 continue;

137 else

139

140

141

142

144 pos++;

145 if (pos == 4)

146 {

147 *p++ = (buf >> 16) & 255;

148 if (end == 0 || end > 1)

149 *p++ = (buf >> 8) & 255;

150 if (end == 0 || end > 2)

151 *p++ = buf & 255;

153 pos = 0;

154 }

155 }

156

157 if (pos != 0)

159 return p - dst;

160}

References b, buf, len, and PXE_PGP_CORRUPT_ARMOR.

Referenced by pgp_armor_decode().

pg_base64_enc_len()

static unsigned pg_base64_enc_len ( unsigned srclen) static

pg_base64_encode()

static int pg_base64_encode ( const uint8 * src, unsigned len, uint8 * dst ) static

Definition at line 45 of file pgp-armor.c.

46{

48 *lend = dst + 76;

50 *end = src + len;

51 int pos = 2;

52 unsigned long buf = 0;

53

54 s = src;

55 p = dst;

56

57 while (s < end)

58 {

59 buf |= *s << (pos << 3);

60 pos--;

61 s++;

62

63

64

65

66 if (pos < 0)

67 {

72

73 pos = 2;

75 }

76 if (p >= lend)

77 {

78 *p++ = '\n';

79 lend = p + 76;

80 }

81 }

82 if (pos != 2)

83 {

86 *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '=';

87 *p++ = '=';

88 }

89

90 return p - dst;

91}

static const unsigned char _base64[]

References _base64, buf, and len.

Referenced by pgp_armor_encode().

pgp_armor_decode()

Definition at line 314 of file pgp-armor.c.

315{

316 const uint8 *p = src;

317 const uint8 *data_end = src + len;

318 long crc;

319 const uint8 *base64_start,

320 *armor_end;

321 const uint8 *base64_end = NULL;

323 int hlen;

324 int blen;

326

327

328 hlen = find_header(src, data_end, &p, 0);

329 if (hlen <= 0)

330 goto out;

331 p += hlen;

332

333

334 hlen = find_header(p, data_end, &armor_end, 1);

335 if (hlen <= 0)

336 goto out;

337

338

339 while (p < armor_end && *p != '\n' && *p != '\r')

340 {

341 p = memchr(p, '\n', armor_end - p);

342 if (!p)

343 goto out;

344

345

346 p++;

347 }

348 base64_start = p;

349

350

351 for (p = armor_end; p >= base64_start; p--)

352 if (*p == '=')

353 {

354 base64_end = p - 1;

355 break;

356 }

357 if (base64_end == NULL)

358 goto out;

359

360

362 goto out;

363 crc = (((long) buf[0]) << 16) + (((long) buf[1]) << 8) + (long) buf[2];

364

365

369 if (res > blen)

370 elog(FATAL, "overflow - decode estimate too small");

371 if (res >= 0)

372 {

374 dst->len += res;

375 else

377 }

378out:

379 return res;

380}

static long crc24(const uint8 *data, unsigned len)

static int find_header(const uint8 *data, const uint8 *datend, const uint8 **start_p, int is_end)

static int pg_base64_decode(const uint8 *src, unsigned len, uint8 *dst)

static unsigned pg_base64_dec_len(unsigned srclen)

void enlargeStringInfo(StringInfo str, int needed)

References buf, crc, crc24(), StringInfoData::data, elog, enlargeStringInfo(), FATAL, find_header(), StringInfoData::len, len, pg_base64_dec_len(), pg_base64_decode(), and PXE_PGP_CORRUPT_ARMOR.

Referenced by pg_dearmor().

pgp_armor_encode()

void pgp_armor_encode ( const uint8 * src,
unsigned len,
StringInfo dst,
int num_headers,
char ** keys,
char ** values
)

Definition at line 207 of file pgp-armor.c.

209{

210 int n;

211 int res;

212 unsigned b64len;

214

216

217 for (n = 0; n < num_headers; n++)

220

221

224

226 if (res > b64len)

227 elog(FATAL, "overflow - encode estimate too small");

228 dst->len += res;

229

230 if (*(dst->data + dst->len - 1) != '\n')

232

238

240}

static Datum values[MAXATTR]

static const char *const armor_footer

static unsigned pg_base64_enc_len(unsigned srclen)

static const char *const armor_header

static int pg_base64_encode(const uint8 *src, unsigned len, uint8 *dst)

void appendStringInfo(StringInfo str, const char *fmt,...)

void appendStringInfoString(StringInfo str, const char *s)

void appendStringInfoChar(StringInfo str, char ch)

References _base64, appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), armor_footer, armor_header, crc, crc24(), StringInfoData::data, elog, enlargeStringInfo(), FATAL, StringInfoData::len, len, pg_base64_enc_len(), pg_base64_encode(), and values.

Referenced by pg_armor().

pgp_extract_armor_headers()

int pgp_extract_armor_headers ( const uint8 * src,
unsigned len,
int * nheaders,
char *** keys,
char *** values
)

Definition at line 390 of file pgp-armor.c.

392{

393 const uint8 *data_end = src + len;

395 const uint8 *base64_start;

396 const uint8 *armor_start;

397 const uint8 *armor_end;

398 Size armor_len;

399 char *line;

400 char *nextline;

401 char *eol,

403 int hlen;

404 char *buf;

405 int hdrlines;

406 int n;

407

408

409 hlen = find_header(src, data_end, &armor_start, 0);

410 if (hlen <= 0)

412 armor_start += hlen;

413

414

415 hlen = find_header(armor_start, data_end, &armor_end, 1);

416 if (hlen <= 0)

418

419

420 hdrlines = 0;

421 p = armor_start;

422 while (p < armor_end && *p != '\n' && *p != '\r')

423 {

424 p = memchr(p, '\n', armor_end - p);

425 if (!p)

427

428

429 p++;

430 hdrlines++;

431 }

432 base64_start = p;

433

434

435

436

437

438 armor_len = base64_start - armor_start;

440 memcpy(buf, armor_start, armor_len);

441 buf[armor_len] = '\0';

442

443

444 *keys = (char **) palloc(hdrlines * sizeof(char *));

445 *values = (char **) palloc(hdrlines * sizeof(char *));

446

447

448

449

450

451 n = 0;

452 line = buf;

453 for (;;)

454 {

455

456 eol = strchr(line, '\n');

457 if (!eol)

458 break;

459 nextline = eol + 1;

460

461 if (eol > line && *(eol - 1) == '\r')

462 eol--;

463 *eol = '\0';

464

465

466 colon = strstr(line, ": ");

470

471

472 if (n >= hdrlines)

473 elog(ERROR, "unexpected number of armor header lines");

474

475 (*keys)[n] = line;

476 (*values)[n] = colon + 2;

477 n++;

478

479

480 line = nextline;

481 }

482

483 if (n != hdrlines)

484 elog(ERROR, "unexpected number of armor header lines");

485

486 *nheaders = n;

487 return 0;

488}

References buf, colon, elog, ERROR, find_header(), len, palloc(), PXE_PGP_CORRUPT_ARMOR, and values.

Referenced by pgp_armor_headers().

_base64

const unsigned char _base64[] static
const char* const armor_footer = "\n-----END PGP MESSAGE-----\n" static

armor_header

const char* const armor_header = "-----BEGIN PGP MESSAGE-----\n" static