debug: add diagnostic logging to 3DES S/MIME decrypt path
Log legacy key import success/failure, CMS algorithm OIDs (content encryption + key transport), legacy key availability during decrypt attempts, and detailed error messages from both RSA-OAEP and RSAES-PKCS1-v1_5 decrypt paths.
This commit is contained in:
@@ -1546,7 +1546,12 @@ export function EmailViewer({
|
|||||||
if (detection.type === 'enveloped-data') {
|
if (detection.type === 'enveloped-data') {
|
||||||
// Encrypted message
|
// Encrypted message
|
||||||
const { keyRecords, unlockedDecryptionKeys, unlockedLegacyDecryptionKeys } = smimeStore;
|
const { keyRecords, unlockedDecryptionKeys, unlockedLegacyDecryptionKeys } = smimeStore;
|
||||||
smimeDebug('[S/MIME] decrypt attempt:', { keyRecordCount: keyRecords.length, unlockedKeyCount: unlockedDecryptionKeys.size, keyRecordIds: keyRecords.map(k => k.id) });
|
smimeDebug('[S/MIME] decrypt attempt:', {
|
||||||
|
keyRecordCount: keyRecords.length,
|
||||||
|
unlockedKeyCount: unlockedDecryptionKeys.size,
|
||||||
|
legacyKeyCount: unlockedLegacyDecryptionKeys.size,
|
||||||
|
keyRecordIds: keyRecords.map(k => k.id),
|
||||||
|
});
|
||||||
|
|
||||||
// Short-circuit: no keys imported at all
|
// Short-circuit: no keys imported at all
|
||||||
if (keyRecords.length === 0) {
|
if (keyRecords.length === 0) {
|
||||||
|
|||||||
@@ -298,8 +298,12 @@ export async function unlockPrivateKey(
|
|||||||
false,
|
false,
|
||||||
['decrypt'],
|
['decrypt'],
|
||||||
);
|
);
|
||||||
} catch {
|
console.debug('[S/MIME] legacy RSAES-PKCS1-v1_5 key imported successfully:', {
|
||||||
// webcrypto-liner may not be available or key format unsupported
|
algorithm: legacyDecryptionKey.algorithm,
|
||||||
|
usages: legacyDecryptionKey.usages,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('[S/MIME] legacy RSAES-PKCS1-v1_5 key import failed:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,18 @@ export async function smimeDecrypt(input: DecryptionInput): Promise<DecryptionRe
|
|||||||
const contentInfo = parseContentInfo(cmsBytes);
|
const contentInfo = parseContentInfo(cmsBytes);
|
||||||
const envelopedData = extractEnvelopedData(contentInfo);
|
const envelopedData = extractEnvelopedData(contentInfo);
|
||||||
|
|
||||||
|
// Log CMS algorithm details for diagnostics
|
||||||
|
const contentEncOid = envelopedData.encryptedContentInfo?.contentEncryptionAlgorithm?.algorithmId;
|
||||||
|
const recipientAlgs = envelopedData.recipientInfos?.map((ri) =>
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(ri as any).value?.keyEncryptionAlgorithm?.algorithmId as string | undefined,
|
||||||
|
);
|
||||||
|
console.debug('[S/MIME] CMS algorithms:', {
|
||||||
|
contentEncryption: contentEncOid,
|
||||||
|
keyTransport: recipientAlgs,
|
||||||
|
legacyKeysAvailable: legacyUnlockedKeys?.size ?? 0,
|
||||||
|
});
|
||||||
|
|
||||||
// Find matching key records
|
// Find matching key records
|
||||||
const matchedRecords = findMatchingKeyRecords(envelopedData, keyRecords);
|
const matchedRecords = findMatchingKeyRecords(envelopedData, keyRecords);
|
||||||
|
|
||||||
@@ -75,9 +87,11 @@ export async function smimeDecrypt(input: DecryptionInput): Promise<DecryptionRe
|
|||||||
mimeBytes: new Uint8Array(decrypted),
|
mimeBytes: new Uint8Array(decrypted),
|
||||||
keyRecordId: keyRecord.id,
|
keyRecordId: keyRecord.id,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch (oaepError) {
|
||||||
// RSA-OAEP key didn't work, try legacy RSAES-PKCS1-v1_5 key
|
// RSA-OAEP key didn't work, try legacy RSAES-PKCS1-v1_5 key
|
||||||
|
console.debug('[S/MIME] RSA-OAEP decrypt failed:', oaepError instanceof Error ? oaepError.message : oaepError);
|
||||||
const legacyKey = legacyUnlockedKeys?.get(keyRecord.id);
|
const legacyKey = legacyUnlockedKeys?.get(keyRecord.id);
|
||||||
|
console.debug('[S/MIME] legacy key available:', !!legacyKey, legacyKey ? { algorithm: (legacyKey as CryptoKey).algorithm } : undefined);
|
||||||
if (legacyKey) {
|
if (legacyKey) {
|
||||||
try {
|
try {
|
||||||
const decrypted = await decryptWithKey(envelopedData, recipientIndex, legacyKey, keyRecord);
|
const decrypted = await decryptWithKey(envelopedData, recipientIndex, legacyKey, keyRecord);
|
||||||
@@ -85,8 +99,9 @@ export async function smimeDecrypt(input: DecryptionInput): Promise<DecryptionRe
|
|||||||
mimeBytes: new Uint8Array(decrypted),
|
mimeBytes: new Uint8Array(decrypted),
|
||||||
keyRecordId: keyRecord.id,
|
keyRecordId: keyRecord.id,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch (legacyError) {
|
||||||
// Legacy key also didn't work, try the next record
|
// Legacy key also didn't work, try the next record
|
||||||
|
console.debug('[S/MIME] RSAES-PKCS1-v1_5 decrypt also failed:', legacyError instanceof Error ? legacyError.message : legacyError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user