Skip to content

Commit 98af895

Browse files
committed
DRY decrypt code
1 parent 8075ae5 commit 98af895

File tree

1 file changed

+21
-31
lines changed

1 file changed

+21
-31
lines changed

lib/xmlenc.js

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -123,58 +123,30 @@ function decrypt(xml, options, callback) {
123123
if (!options.key)
124124
return callback(new Error('key option is mandatory and you should provide a valid RSA private key'));
125125

126-
var decrypted;
127-
128126
try {
129127
var doc = typeof xml === 'string' ? new xmldom.DOMParser().parseFromString(xml) : xml;
130128

131129
var symmetricKey = decryptKeyInfo(doc, options);
132130
var encryptionMethod = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='EncryptionMethod']", doc)[0];
133131
var encryptionAlgorithm = encryptionMethod.getAttribute('Algorithm');
134132

135-
var algorithm;
136-
var ivLength;
137133
var encryptedContent = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='CipherData']/*[local-name(.)='CipherValue']", doc)[0];
138134

139135
var encrypted = new Buffer(encryptedContent.textContent, 'base64');
140136

141137
switch (encryptionAlgorithm) {
142138
case 'http://www.w3.org/2001/04/xmlenc#aes128-cbc':
143-
algorithm = 'aes-128-cbc';
144-
ivLength = 16;
145-
break;
139+
return callback(null, decryptWithAlgorithm('aes-128-cbc', symmetricKey, 16, encrypted));
146140
case 'http://www.w3.org/2001/04/xmlenc#aes256-cbc':
147-
algorithm = 'aes-256-cbc';
148-
ivLength = 16;
149-
break;
141+
return callback(null, decryptWithAlgorithm('aes-256-cbc', symmetricKey, 16, encrypted));
150142
case 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc':
151-
algorithm = 'des-ede3-cbc';
152-
ivLength = 8;
153-
break;
143+
return callback(null, decryptWithAlgorithm('des-ede3-cbc', symmetricKey, 8, encrypted));
154144
default:
155145
return callback(new Error('encryption algorithm ' + encryptionAlgorithm + ' not supported'));
156146
}
157-
158-
var decipher = crypto.createDecipheriv(algorithm, symmetricKey, encrypted.slice(0,ivLength));
159-
decipher.setAutoPadding(false);
160-
161-
decrypted = decipher.update(encrypted.slice(ivLength), null, 'binary') + decipher.final('binary');
162-
163-
// Remove padding bytes equal to the value of the last byte of the returned data.
164-
var padding = decrypted.charCodeAt(decrypted.length - 1);
165-
if (1 <= padding && padding <= ivLength) {
166-
decrypted = decrypted.substr(0, decrypted.length - padding);
167-
} else {
168-
callback(new Error('padding length invalid'));
169-
return;
170-
}
171-
172-
decrypted = new Buffer(decrypted, 'binary').toString('utf8');
173147
} catch (e) {
174148
return callback(e);
175149
}
176-
177-
callback(null, decrypted);
178150
}
179151

180152
function decryptKeyInfo(doc, options) {
@@ -233,6 +205,24 @@ function encryptWithAlgorithm(algorithm, symmetricKey, ivLength, content, encodi
233205
});
234206
}
235207

208+
function decryptWithAlgorithm(algorithm, symmetricKey, ivLength, content) {
209+
var decipher = crypto.createDecipheriv(algorithm, symmetricKey, content.slice(0,ivLength));
210+
decipher.setAutoPadding(false);
211+
212+
var decrypted = decipher.update(content.slice(ivLength), null, 'binary') + decipher.final('binary');
213+
214+
// Remove padding bytes equal to the value of the last byte of the returned data.
215+
var padding = decrypted.charCodeAt(decrypted.length - 1);
216+
if (1 <= padding && padding <= ivLength) {
217+
decrypted = decrypted.substr(0, decrypted.length - padding);
218+
} else {
219+
callback(new Error('padding length invalid'));
220+
return;
221+
}
222+
223+
return new Buffer(decrypted, 'binary').toString('utf8');
224+
}
225+
236226
exports = module.exports = {
237227
decrypt: decrypt,
238228
encrypt: encrypt,

0 commit comments

Comments
 (0)