Skip to content

Commit c1437de

Browse files
committed
Fix hang when decoding PEM
Reported via [0] [0] DCIT/perl-CryptX#110 (comment) Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 29af892 commit c1437de

File tree

9 files changed

+53
-0
lines changed

9 files changed

+53
-0
lines changed

src/misc/pem/pem_read.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_ch
163163
unsigned long slen, linelen;
164164
int err, hdr_ok = 0;
165165
int would_overflow = 0;
166+
unsigned char empty_lines = 0;
166167

167168
linelen = sizeof(buf);
168169
if (s_get_line(buf, &linelen, g) == NULL) {
@@ -184,6 +185,11 @@ int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_ch
184185
hdr_ok = 1;
185186
break;
186187
}
188+
if (!slen) {
189+
if (empty_lines)
190+
break;
191+
empty_lines++;
192+
}
187193
if (!would_overflow && s_fits_buf(wpem, slen, end)) {
188194
XMEMCPY(wpem, buf, slen);
189195
} else {

tests/pem/pkcs/invalid/single_line

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-----BEGIN EC PRIVATE KEY-----MHcCAQEEIFF9oAGC6vxNLIU8D+nuvM8ms1QQlPtpGzQTfzEBVB06oAoGCCqGSM49AwEHoUQDQgAE3VU0nT1p5W0zKHDknAgQpsOODuM2/AoZ/6wNqC9AoUCEpQempFg0aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2mlw==-----END EC PRIVATE KEY-----
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-----BEGIN PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3VU0nT1p5W0zKHDknAgQpsOODuM2/AoZ/6wNqC9AoUCEpQempFg0aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2mlw==-----END PUBLIC KEY-----
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
3+
MHcCAQEEIFF9oAGC6vxNLIU8D+nuvM8ms1QQlPtpGzQTfzEBVB06oAoGCCqGSM49
4+
5+
AwEHoUQDQgAE3VU0nT1p5W0zKHDknAgQpsOODuM2/AoZ/6wNqC9AoUCEpQempFg0
6+
7+
aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2mlw==
8+
9+
-----END EC PRIVATE KEY-----
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-----BEGIN PUBLIC KEY-----
2+
3+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3VU0nT1p5W0zKHDknAgQpsOODuM2
4+
5+
/AoZ/6wNqC9AoUCEpQempFg0aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2mlw==
6+
7+
-----END PUBLIC KEY-----'
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MHcCAQEEIFF9oAGC6vxNLIU8D+nuvM8ms1QQlPtp
3+
GzQTfzEBVB06oAoGCCqGSM49AwEHoUQDQgAE3VU0
4+
nT1p5W0zKHDknAgQpsOODuM2/AoZ/6wNqC9AoUCE
5+
pQempFg0aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2m
6+
lw==-----END PUBLIC KEY-----
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MHcCAQEEIFF9oAGC6vxNLIU8D+nuvM8m
3+
s1QQlPtpGzQTfzEBVB06oAoGCCqGSM49
4+
AwEHoUQDQgAE3VU0nT1p5W0zKHDknAgQ
5+
psOODuM2/AoZ/6wNqC9AoUCEpQempFg0
6+
aBqxleOP0uW0HG1YwCnOF8N0D8Q2RR2m
7+
lw==
8+
-----END EC PRIVATE KEY-----
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
3+
QgAE3VU0nT1p5W0zKHDknAgQpsOODuM2
4+
/AoZ/6wNqC9AoUCEpQempFg0aBqxleOP
5+
0uW0HG1YwCnOF8N0D8Q2RR2mlw==
6+
-----END PUBLIC KEY-----

tests/pem_test.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ static int s_key_cmp(ltc_pka_key *key)
9393
return CRYPT_INVALID_ARG;
9494
}
9595

96+
static int s_pem_decode_invalid_pkcs(const void *in, unsigned long inlen, void *key)
97+
{
98+
password_ctx pw_ctx = { .callback = password_get };
99+
SHOULD_FAIL(pem_decode_pkcs(in, inlen, key, &pw_ctx));
100+
return CRYPT_OK;
101+
}
102+
96103
static int s_pem_only_decode_pkcs(const void *in, unsigned long inlen, void *key)
97104
{
98105
password_ctx pw_ctx = { .callback = password_get };
@@ -158,6 +165,8 @@ int pem_test(void)
158165
DO(test_process_dir("tests/pem/pkcs/ecc-pkcs8", &key, s_pem_decode_pkcs, NULL, (dir_cleanup_cb)pka_key_free, "pem_pkcs_test+ecc"));
159166
DO(test_process_dir("tests/pem/pkcs/ecc-pkcs8", &key, NULL, s_pem_decode_pkcs_f, (dir_cleanup_cb)pka_key_free, "pem_pkcs_test_filehandle+ecc"));
160167
DO(test_process_dir("tests/pem/pkcs/extra", &key, s_pem_only_decode_pkcs, NULL, (dir_cleanup_cb)pka_key_free, "pem_pkcs_test+extra"));
168+
DO(test_process_dir("tests/pem/pkcs/invalid", &key, s_pem_decode_invalid_pkcs, NULL, NULL, "pem_test_invalid"));
169+
DO(test_process_dir("tests/pem/pkcs/invalid_but_supported", &key, s_pem_only_decode_pkcs, NULL, (dir_cleanup_cb)pka_key_free, "pem_pkcs_invalid_but_supported"));
161170
#ifdef LTC_SSH
162171
DO(test_process_dir("tests/pem/ssh", &key, s_pem_decode_ssh, NULL, (dir_cleanup_cb)pka_key_free, "pem_ssh_test"));
163172
DO(test_process_dir("tests/pem/ssh", &key, NULL, s_pem_decode_ssh_f, (dir_cleanup_cb)pka_key_free, "pem_ssh_test_filehandle"));

0 commit comments

Comments
 (0)