Skip to content

Commit 973f46d

Browse files
committed
Make pem_read() ignore all junk before a real PEM header is found
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent b23adcc commit 973f46d

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

src/headers/tomcrypt_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ struct get_char {
363363
} data;
364364
struct str unget_buf;
365365
char unget_buf_[LTC_PEM_DECODE_BUFSZ];
366+
int prev_get;
366367
};
367368
#endif
368369

src/misc/pem/pem_read.c

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ static void s_tts(char *buf, unsigned long *buflen)
6262
}
6363
}
6464

65-
static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
65+
static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, int search_for_start)
6666
{
67-
unsigned long blen = 0;
68-
int c = -1, c_;
67+
unsigned long blen = 0, wr = 0;
68+
int c_;
6969
if (g->unget_buf.p) {
7070
if (*buflen < g->unget_buf.len) {
7171
return NULL;
@@ -75,30 +75,44 @@ static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
7575
RESET_STR(g->unget_buf);
7676
return buf;
7777
}
78-
while(blen < *buflen) {
79-
c_ = c;
80-
c = g->get(g);
81-
if (c == '\n') {
82-
buf[blen] = '\0';
78+
if (g->prev_get == -1) {
79+
return NULL;
80+
}
81+
while(blen < *buflen || search_for_start) {
82+
wr = blen < *buflen ? blen : *buflen - 1;
83+
c_ = g->prev_get;
84+
g->prev_get = g->get(g);
85+
if (g->prev_get == '\n') {
86+
buf[wr] = '\0';
8387
if (c_ == '\r') {
84-
buf[--blen] = '\0';
88+
buf[--wr] = '\0';
8589
}
86-
s_tts(buf, &blen);
87-
*buflen = blen;
90+
s_tts(buf, &wr);
91+
*buflen = wr;
8892
return buf;
8993
}
90-
if (c == -1 || c == '\0') {
91-
buf[blen] = '\0';
92-
s_tts(buf, &blen);
93-
*buflen = blen;
94+
if (g->prev_get == -1 || g->prev_get == '\0') {
95+
buf[wr] = '\0';
96+
s_tts(buf, &wr);
97+
*buflen = wr;
9498
return buf;
9599
}
96-
buf[blen] = c;
100+
buf[wr] = g->prev_get;
97101
blen++;
98102
}
99103
return NULL;
100104
}
101105

106+
LTC_INLINE static char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g)
107+
{
108+
return s_get_line_i(buf, buflen, g, 1);
109+
}
110+
111+
LTC_INLINE static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
112+
{
113+
return s_get_line_i(buf, buflen, g, 0);
114+
}
115+
102116
static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end)
103117
{
104118
unsigned char *d = dest;
@@ -181,15 +195,24 @@ int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr,
181195
char buf[LTC_PEM_DECODE_BUFSZ];
182196
char *wpem = asn1_cert;
183197
char *end = wpem + *asn1_len;
198+
const char pem_start[] = "----";
184199
unsigned long slen, linelen;
185200
int err, hdr_ok = 0;
186201
int would_overflow = 0;
187202
unsigned char empty_lines = 0;
188203

189-
linelen = sizeof(buf);
190-
if (s_get_line(buf, &linelen, g) == NULL) {
191-
return CRYPT_INVALID_PACKET;
192-
}
204+
g->prev_get = 0;
205+
do {
206+
linelen = sizeof(buf);
207+
if (s_get_first_line(buf, &linelen, g) == NULL) {
208+
if (g->prev_get == -1)
209+
return CRYPT_NOP;
210+
else
211+
return CRYPT_INVALID_PACKET;
212+
}
213+
if (linelen < sizeof(pem_start) - 1)
214+
continue;
215+
} while(XMEMCMP(buf, pem_start, sizeof(pem_start) - 1) != 0);
193216
if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) {
194217
s_unget_line(buf, linelen, g);
195218
return CRYPT_UNKNOWN_PEM;

0 commit comments

Comments
 (0)