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}
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++;
111 else if (c >= 'a' && c <= 'z')
113 else if (c >= '0' && c <= '9')
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 |
---|
◆ armor_footer
const char* const armor_footer = "\n-----END PGP MESSAGE-----\n" | static |
---|
◆ armor_header
const char* const armor_header = "-----BEGIN PGP MESSAGE-----\n" | static |
---|