@@ -123,58 +123,30 @@ function decrypt(xml, options, callback) {
123
123
if ( ! options . key )
124
124
return callback ( new Error ( 'key option is mandatory and you should provide a valid RSA private key' ) ) ;
125
125
126
- var decrypted ;
127
-
128
126
try {
129
127
var doc = typeof xml === 'string' ? new xmldom . DOMParser ( ) . parseFromString ( xml ) : xml ;
130
128
131
129
var symmetricKey = decryptKeyInfo ( doc , options ) ;
132
130
var encryptionMethod = xpath . select ( "//*[local-name(.)='EncryptedData']/*[local-name(.)='EncryptionMethod']" , doc ) [ 0 ] ;
133
131
var encryptionAlgorithm = encryptionMethod . getAttribute ( 'Algorithm' ) ;
134
132
135
- var algorithm ;
136
- var ivLength ;
137
133
var encryptedContent = xpath . select ( "//*[local-name(.)='EncryptedData']/*[local-name(.)='CipherData']/*[local-name(.)='CipherValue']" , doc ) [ 0 ] ;
138
134
139
135
var encrypted = new Buffer ( encryptedContent . textContent , 'base64' ) ;
140
136
141
137
switch ( encryptionAlgorithm ) {
142
138
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 ) ) ;
146
140
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 ) ) ;
150
142
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 ) ) ;
154
144
default :
155
145
return callback ( new Error ( 'encryption algorithm ' + encryptionAlgorithm + ' not supported' ) ) ;
156
146
}
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' ) ;
173
147
} catch ( e ) {
174
148
return callback ( e ) ;
175
149
}
176
-
177
- callback ( null , decrypted ) ;
178
150
}
179
151
180
152
function decryptKeyInfo ( doc , options ) {
@@ -233,6 +205,24 @@ function encryptWithAlgorithm(algorithm, symmetricKey, ivLength, content, encodi
233
205
} ) ;
234
206
}
235
207
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
+
236
226
exports = module . exports = {
237
227
decrypt : decrypt ,
238
228
encrypt : encrypt ,
0 commit comments