@@ -70,8 +70,63 @@ function pbes2EncryptFN(hmac, kw) {
70
70
return promise ;
71
71
} ;
72
72
73
- // NOTE: WebCrypto API missing until there's better support
74
- var webcrypto = null ;
73
+ var webcrypto = function ( key , pdata , props ) {
74
+ var salt = util . asBuffer ( props . p2s || new Buffer ( 0 ) , "base64url" ) ,
75
+ itrs = props . p2c || 0 ;
76
+
77
+ if ( 0 >= itrs ) {
78
+ return Promise . reject ( new Error ( "invalid iteration count" ) ) ;
79
+ }
80
+ if ( 8 > salt . length ) {
81
+ return Promise . reject ( new Error ( "salt too small" ) ) ;
82
+ }
83
+ salt = fixSalt ( hmac , kw , salt ) ;
84
+
85
+ var promise ;
86
+
87
+ // STEP 1: derive shared key
88
+ var hash = hmac . replace ( "HS" , "SHA-" ) ;
89
+ promise = Promise . resolve ( key ) ;
90
+ promise = promise . then ( function ( keyval ) {
91
+ return helpers . subtleCrypto . importKey ( "raw" , keyval , "PBKDF2" , false , [ "deriveKey" ] ) ;
92
+ } ) ;
93
+ promise = promise . then ( function ( key ) {
94
+ var mainAlgo = {
95
+ name : "PBKDF2" ,
96
+ salt : salt ,
97
+ iterations : itrs ,
98
+ hash : hash
99
+ } ;
100
+ var deriveAlgo = {
101
+ name : "AES-KW" ,
102
+ length : keyLen * 8
103
+ } ;
104
+
105
+ return helpers . subtleCrypto . deriveKey ( mainAlgo , key , deriveAlgo , true , [ "wrapKey" , "unwrapKey" ] ) ;
106
+ } ) ;
107
+ // STEP 2: encrypt cek
108
+ promise = promise . then ( function ( dk ) {
109
+ // assume subtleCrypto for keywrap
110
+ return Promise . all ( [
111
+ helpers . subtleCrypto . importKey ( "raw" , pdata , { name : "HMAC" , hash : "SHA-256" } , true , [ "sign" ] ) ,
112
+ dk
113
+ ] ) ;
114
+ } ) ;
115
+ promise = promise . then ( function ( keys ) {
116
+ return helpers . subtleCrypto . wrapKey ( "raw" ,
117
+ keys [ 0 ] , // key
118
+ keys [ 1 ] , // wrappingKey
119
+ "AES-KW" ) ;
120
+ } ) ;
121
+ promise = promise . then ( function ( result ) {
122
+ result = new Buffer ( result ) ;
123
+
124
+ return {
125
+ data : result
126
+ } ;
127
+ } ) ;
128
+ return promise ;
129
+ } ;
75
130
76
131
var nodejs = function ( key , pdata , props ) {
77
132
if ( 6 > helpers . nodeCrypto . pbkdf2 . length ) {
@@ -165,8 +220,55 @@ function pbes2DecryptFN(hmac, kw) {
165
220
return promise ;
166
221
} ;
167
222
168
- // NOTE: WebCrypto API missing until there's better support
169
- var webcrypto = null ;
223
+ var webcrypto = function ( key , cdata , props ) {
224
+ props = props || { } ;
225
+
226
+ var salt = util . asBuffer ( props . p2s || new Buffer ( 0 ) , "base64url" ) ,
227
+ itrs = props . p2c || 0 ;
228
+
229
+ if ( 0 >= itrs ) {
230
+ return Promise . reject ( new Error ( "invalid iteration count" ) ) ;
231
+ }
232
+
233
+ if ( 8 > salt . length ) {
234
+ return Promise . reject ( new Error ( "salt too small" ) ) ;
235
+ }
236
+ salt = fixSalt ( hmac , kw , salt ) ;
237
+
238
+ var hash = hmac . replace ( "HS" , "SHA-" ) ;
239
+ var promise ;
240
+ promise = Promise . resolve ( key ) ;
241
+ promise = promise . then ( function ( keyval ) {
242
+ return helpers . subtleCrypto . importKey ( "raw" , keyval , "PBKDF2" , false , [ "deriveKey" ] ) ;
243
+ } ) ;
244
+ promise = promise . then ( function ( key ) {
245
+ var mainAlgo = {
246
+ name : "PBKDF2" ,
247
+ salt : salt ,
248
+ iterations : itrs ,
249
+ hash : hash
250
+ } ;
251
+ var deriveAlgo = {
252
+ name : "AES-KW" ,
253
+ length : keyLen * 8
254
+ } ;
255
+
256
+ return helpers . subtleCrypto . deriveKey ( mainAlgo , key , deriveAlgo , true , [ "wrapKey" , "unwrapKey" ] ) ;
257
+ } ) ;
258
+ // STEP 2: decrypt cek
259
+ promise = promise . then ( function ( key ) {
260
+ return helpers . subtleCrypto . unwrapKey ( "raw" , cdata , key , "AES-KW" , { name : "HMAC" , hash : "SHA-256" } , true , [ "sign" ] ) ;
261
+ } ) ;
262
+ promise = promise . then ( function ( result ) {
263
+ // unwrapped CryptoKey -- extract raw
264
+ return helpers . subtleCrypto . exportKey ( "raw" , result ) ;
265
+ } ) ;
266
+ promise = promise . then ( function ( result ) {
267
+ result = new Buffer ( result ) ;
268
+ return result ;
269
+ } ) ;
270
+ return promise ;
271
+ } ;
170
272
171
273
var nodejs = function ( key , cdata , props ) {
172
274
if ( 6 > helpers . nodeCrypto . pbkdf2 . length ) {
0 commit comments