Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions src/pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -6838,7 +6838,7 @@ static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,

*start = *len = 0;
/* Find prefix part. */
for (; idx < pemLen - prefixLen; idx++) {
for (; idx <= pemLen - prefixLen; idx++) {
if ((pem[idx] == prefix[0]) &&
(XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) {
idx += prefixLen;
Expand All @@ -6847,7 +6847,7 @@ static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix,
}
}
/* Find postfix part. */
for (; idx < pemLen - postfixLen; idx++) {
for (; idx <= pemLen - postfixLen; idx++) {
Comment thread
philljj marked this conversation as resolved.
if ((pem[idx] == postfix[0]) &&
(XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) {
*len = idx - *start;
Expand Down Expand Up @@ -6900,9 +6900,21 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header,
}
}
if (ret == 0) {
/* Find encryption headers after header. */
/* Find footer. */
start += nameLen + PEM_HDR_FIN_SZ;
pem_find_pattern(pem, pemLen, start, "\n", "\n\n", &startHdr, &hdrLen);
pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
&endLen);
/* Validate header name and footer name are the same. */
if ((endLen != nameLen) ||
(XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
ret = ASN_NO_PEM_HEADER;
}
}
if (ret == 0) {
/* Find encryption headers - bounded by the footer so that a blank line
* after it isn't matched. */
pem_find_pattern(pem, startEnd - PEM_END_SZ, start, "\n", "\n\n",
&startHdr, &hdrLen);
if (hdrLen > 0) {
/* Include first of two '\n' characters. */
hdrLen++;
Expand All @@ -6921,15 +6933,6 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header,
XMEMCPY(*header, pem + startHdr, (size_t)hdrLen);
start = startHdr + hdrLen + 1;
}

/* Find footer. */
pem_find_pattern(pem, pemLen, start, PEM_END, PEM_HDR_FIN, &startEnd,
&endLen);
/* Validate header name and footer name are the same. */
if ((endLen != nameLen) ||
(XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) {
ret = ASN_NO_PEM_HEADER;
}
}
if (ret == 0) {
unsigned char* der = (unsigned char*)pem;
Expand Down
40 changes: 40 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -29182,6 +29182,17 @@ static int test_wolfSSL_PEM_read(void)
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_BIO)
const char* filename = "./certs/server-keyEnc.pem";
/* Footer's final "-----" is the last byte of the input - no trailing EOL. */
const char* pemNoEol =
"-----BEGIN TEST-----\n"
"AAECAwQ=\n"
"-----END TEST-----";
/* Blank line after the footer - must not be taken as an encryption
* header terminator. */
const char* pemBlankEol =
"-----BEGIN TEST-----\n"
"AAECAwQ=\n"
"-----END TEST-----\n\n";
XFILE fp = XBADFILE;
char* name = NULL;
char* header = NULL;
Expand Down Expand Up @@ -29330,10 +29341,39 @@ static int test_wolfSSL_PEM_read(void)
ExpectIntEQ(XMEMCMP(out, fileData, fileDataSz), 0);

BIO_free(bio);
bio = NULL;
XFREE(fileData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);

/* Valid PEM that ends at the last dash of the footer must still parse. */
name = NULL;
header = NULL;
data = NULL;
ExpectNotNull(bio = BIO_new_mem_buf(pemNoEol, (int)XSTRLEN(pemNoEol)));
ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
ExpectIntEQ(XSTRNCMP(name, "TEST", 4), 0);
ExpectIntEQ(len, 5);
BIO_free(bio);
bio = NULL;
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);

/* Valid PEM ending with a blank line must still parse. */
name = NULL;
header = NULL;
data = NULL;
ExpectNotNull(bio = BIO_new_mem_buf(pemBlankEol, (int)XSTRLEN(pemBlankEol)));
ExpectIntEQ(PEM_read_bio(bio, &name, &header, &data, &len), 1);
ExpectIntEQ(XSTRNCMP(name, "TEST", 4), 0);
ExpectIntEQ(XSTRLEN(header), 0);
ExpectIntEQ(len, 5);
BIO_free(bio);
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(data, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXPECT_RESULT();
}
Expand Down
Loading