Skip to content

Commit

Permalink
fix(dkim-relaxed): Faster DKIM hash calculation for relaxed body if t…
Browse files Browse the repository at this point in the history
…he body contains extremely long lines
  • Loading branch information
andris9 committed Aug 22, 2024
1 parent 4a88d8f commit fd8c89e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
28 changes: 20 additions & 8 deletions lib/dkim/body/relaxed.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,24 +122,36 @@ class RelaxedHash {
this._updateBodyHash(chunk);
}

/**
* Performs the following modifications for a single line:
* - Replace all <LF> chars with <CR><LF>
* - Replace all spaces and tabs with a single space.
* - Remove trailing whitespace
* @param {Buffer} line
* @returns {Buffer} fixed line
*/
fixLineBuffer(line) {
let resultLine = [];
// Allocate maximum expected buffer length
// If the line is only filled with <LF> bytes then we need 2 times the size of the line
let lineBuf = Buffer.alloc(line.length * 2);
// Start processing the line from the end to beginning
let writePos = lineBuf.length - 1;

let nonWspFound = false;
let prevWsp = false;

for (let i = line.length - 1; i >= 0; i--) {
if (line[i] === CHAR_LF) {
resultLine.unshift(line[i]);
lineBuf[writePos--] = line[i];
if (i === 0 || line[i - 1] !== CHAR_CR) {
// add missing carriage return
resultLine.unshift(CHAR_CR);
lineBuf[writePos--] = CHAR_CR;
}
continue;
}

if (line[i] === CHAR_CR) {
resultLine.unshift(line[i]);
lineBuf[writePos--] = line[i];
continue;
}

Expand All @@ -151,19 +163,19 @@ class RelaxedHash {
}

if (prevWsp) {
resultLine.unshift(CHAR_SPACE);
lineBuf[writePos--] = CHAR_SPACE;
prevWsp = false;
}

nonWspFound = true;
resultLine.unshift(line[i]);
lineBuf[writePos--] = line[i];
}

if (prevWsp && nonWspFound) {
resultLine.unshift(CHAR_SPACE);
lineBuf[writePos--] = CHAR_SPACE;
}

return Buffer.from(resultLine);
return lineBuf.subarray(writePos + 1);
}

update(chunk, final) {
Expand Down
14 changes: 14 additions & 0 deletions test/dkim/body/relaxed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,18 @@ describe('DKIM RelaxedBody Tests', () => {
.digest('base64')
);
});

it('Should process a very long line', async () => {
const lineLen = 10 * 1024 * 1024;
const message = Buffer.alloc(lineLen);
// Fill the line with printable characters from 0x20 to 0x7E
for (let i = 1; i < lineLen + 1; i++) {
message[i] = (i % 95) + 0x20;
}

let s = new RelaxedHash('rsa-sha256');
let buf = s.fixLineBuffer(message);

expect(buf).to.exist;
});
});

0 comments on commit fd8c89e

Please sign in to comment.