Skip to content

Commit

Permalink
Fix DKIM
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlgo11 committed Jan 14, 2025
1 parent a14e624 commit 465813a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 38 deletions.
3 changes: 2 additions & 1 deletion outbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"main": "src/server.js",
"type": "module",
"scripts": {
"run": "node ./src/server.js"
"run": "node ./src/server.js",
"test": "node --test"
},
"dependencies": {
"@carlgo11/smtp-server": "^0.0.9",
Expand Down
58 changes: 21 additions & 37 deletions outbox/src/services/dkim.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,6 @@ function canonicalizeHeaders(headers, algo = 'relaxed') {
return headers.join('\r\n');
}

function canonicalizeBody(body) {
// Normalize line endings to CRLF
let normalizedBody = body.replace(/\r?\n/g, '\r\n');

// Remove trailing whitespace from each line
normalizedBody = normalizedBody.split('\r\n').
map(line => line.replace(/\s+$/, '')).
join('\r\n');

// Remove trailing empty lines and ensure the body ends with a single CRLF
normalizedBody = normalizedBody.replace(/(\r\n)*$/, '\r\n');

return normalizedBody;
}

export function parseHeaders(allHeaders, headersToSign) {
if (typeof allHeaders === 'object') {
let headersMap = {}
Expand All @@ -42,8 +27,18 @@ export function parseHeaders(allHeaders, headersToSign) {
}

export function parseBody(body) {
const canonicalBody = canonicalizeBody(body);
return crypto.createHash('sha256').update(canonicalBody).digest('base64');
// Normalize line endings to CRLF
let normalizedBody = body.replace(/\r?\n/g, '\r\n');

// Remove trailing whitespace from each line
normalizedBody = normalizedBody.split('\r\n').
map(line => line.replace(/\s+$/, '')).
join('\r\n');

// Remove trailing empty lines and ensure the body ends with a single CRLF
normalizedBody = normalizedBody.replace(/(\r\n)*$/, '\r\n');

return crypto.createHash('sha256').update(normalizedBody).digest('base64');
}

const headersToSign = [
Expand All @@ -56,31 +51,20 @@ const headersToSign = [
'content-type',
'content-transfer-encoding',
];
/**
* Signs an email message using the specified headers, body, domain, selector, and private key,
* creating a DKIM-Signature header.
*
* @param {String} headers An array containing all email headers.
* @param {string} body The body of the email message.
* @param {string} domain The domain name used for the DKIM signature.
* @param {string} selector The selector corresponding to the DNS entry of the DKIM key.
* @param {String} keyPath The private key used to sign the email.
* @return {string} The constructed DKIM-Signature header with the attached digital signature.
* @throws {Error} If any headers listed in `headersToSign` are missing from the provided headers.
*/

/**
* Creates DKIM signature header for a supplied email message (IMF text)
*
* @param {Email} email
* @param {string} keyDir
* @param {string} selector
* @returns {Promise<string>}
* @param {Email} email Email object containing headers and body.
* @param {string} keyDir (Optional) Path to locate the appropriate DKIM private key file.
* @param {string} selector (Optional) DKIM record selector.
* @returns {Promise<string>} The constructed DKIM-Signature header.
* @since 0.0.2
*/
export default async function signMessage(email, keyDir = '/cert/dkim/', selector = 'dkim') {
const headers = email.headers;
const body = email.body;
const addr = email.from.split('@').slice(1);
const domain = addr
const domain = email.from.split('@').slice(1)

// Load private key
const privateKey = await fs.readFile(`${keyDir}${domain}.pem`, 'utf8');
Expand All @@ -96,6 +80,6 @@ export default async function signMessage(email, keyDir = '/cert/dkim/', selecto
const signatureInput = `${parsedHeaders}\r\n${dkimHeader}`;
const signature = crypto.sign('sha256', Buffer.from(signatureInput), privateKey);

// Add the signature to the DKIM-Signature header
// Add the signature (b parameter) to the DKIM-Signature header
return `${dkimHeader} b=${signature.toString('base64')};`;
}
}

0 comments on commit 465813a

Please sign in to comment.