Skip to content

Commit 1e04092

Browse files
committed
Only zero unused tail of PKCS#8 PEM buffer
F-2148 The prior fix zeroed the computed DER staging area, but PEM output from wc_DerToPemEx fills most of the buffer and overlaps that region, corrupting the valid PEM. Preserve the allocation size and zero only the bytes beyond the actual PEM length, or the whole buffer on failure.
1 parent 00fff0f commit 1e04092

1 file changed

Lines changed: 17 additions & 4 deletions

File tree

src/pk.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7117,6 +7117,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
71177117
char password[NAME_SZ];
71187118
byte* key = NULL;
71197119
word32 keySz = 0;
7120+
word32 allocSz = 0;
71207121
int type = PKCS8_PRIVATEKEY_TYPE;
71217122

71227123
/* Validate parameters. */
@@ -7155,6 +7156,10 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
71557156
res = 0;
71567157
}
71577158
else {
7159+
/* Remember the allocation size before *pemSz is updated to the
7160+
* actual PEM output length, so we can zero any unused tail that
7161+
* held the DER staging area. */
7162+
allocSz = (word32)*pemSz;
71587163
/* Use end of PEM buffer for key data. */
71597164
key = *pem + *pemSz - keySz;
71607165
}
@@ -7208,10 +7213,18 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
72087213
}
72097214
}
72107215

7211-
/* Zero the DER staging area at the tail of the buffer so the plaintext
7212-
* private key material is not left in freed heap memory. */
7213-
if (key != NULL && keySz > 0) {
7214-
ForceZero(key, keySz);
7216+
/* Zero any remnants of the DER staging area that persist after PEM
7217+
* conversion so plaintext private key material is not left in freed heap
7218+
* memory. On success, only the bytes past the actual PEM output need
7219+
* clearing; on failure, the whole buffer is zeroed since its state is
7220+
* indeterminate. */
7221+
if (*pem != NULL) {
7222+
if (res == 1 && (word32)*pemSz < allocSz) {
7223+
ForceZero(*pem + *pemSz, allocSz - (word32)*pemSz);
7224+
}
7225+
else if (res != 1) {
7226+
ForceZero(*pem, allocSz);
7227+
}
72157228
}
72167229

72177230
/* Return appropriate return code. */

0 commit comments

Comments
 (0)