diff --git a/dist/jose-commonjs.js b/dist/jose-commonjs.js index 5aeccc6..091a97b 100644 --- a/dist/jose-commonjs.js +++ b/dist/jose-commonjs.js @@ -1125,6 +1125,14 @@ Utils.isCryptoKey = function(rsa_key) { if (rsa_key.constructor.name == 'CryptoKey') { return true; } + + // In the presence of minifiers, relying on class names can be problematic, + // so let's also allow objects that have an 'algorithm' property. + if (rsa_key.hasOwnProperty('algorithm')) { + return true; + } + + return false; }; /*- diff --git a/dist/jose-testing.js b/dist/jose-testing.js index 041fb40..8ae6446 100644 --- a/dist/jose-testing.js +++ b/dist/jose-testing.js @@ -1128,6 +1128,14 @@ Utils.isCryptoKey = function(rsa_key) { if (rsa_key.constructor.name == 'CryptoKey') { return true; } + + // In the presence of minifiers, relying on class names can be problematic, + // so let's also allow objects that have an 'algorithm' property. + if (rsa_key.hasOwnProperty('algorithm')) { + return true; + } + + return false; }; /*- diff --git a/dist/jose.js b/dist/jose.js index cffd589..9fdaea6 100644 --- a/dist/jose.js +++ b/dist/jose.js @@ -1130,6 +1130,14 @@ Utils.isCryptoKey = function(rsa_key) { if (rsa_key.constructor.name == 'CryptoKey') { return true; } + + // In the presence of minifiers, relying on class names can be problematic, + // so let's also allow objects that have an 'algorithm' property. + if (rsa_key.hasOwnProperty('algorithm')) { + return true; + } + + return false; }; /*- diff --git a/dist/jose.min.js b/dist/jose.min.js index c46258f..8fee0fa 100644 --- a/dist/jose.min.js +++ b/dist/jose.min.js @@ -1 +1 @@ -!function(a,b,c,d,e){"use strict";b.subtle||(b.subtle=b.webkitSubtle);var f={},g={},h={};a.setCrypto=function(a){f.crypto=a},a.setCrypto(b),"function"!=typeof atob&&(atob=function(a){return new Buffer(a,"base64").toString("binary")}),"function"!=typeof btoa&&(btoa=function(a){var b;return b=a instanceof Buffer?a:new Buffer(a.toString(),"binary"),b.toString("base64")}),f.caniuse=function(){var a=!0;return a=a&&"function"==typeof c,a=a&&"function"==typeof c.reject,a=a&&"function"==typeof c.prototype.then,a=a&&"function"==typeof c.all,a=a&&"object"==typeof f.crypto,a=a&&"object"==typeof f.crypto.subtle,a=a&&"function"==typeof f.crypto.getRandomValues,a=a&&"function"==typeof f.crypto.subtle.importKey,a=a&&"function"==typeof f.crypto.subtle.generateKey,a=a&&"function"==typeof f.crypto.subtle.exportKey,a=a&&"function"==typeof f.crypto.subtle.wrapKey,a=a&&"function"==typeof f.crypto.subtle.unwrapKey,a=a&&"function"==typeof f.crypto.subtle.encrypt,a=a&&"function"==typeof f.crypto.subtle.decrypt,a=a&&"function"==typeof f.crypto.subtle.sign,a=a&&"function"==typeof ArrayBuffer,a=a&&("function"==typeof e||"object"==typeof e),a=a&&("function"==typeof Uint32Array||"object"==typeof Uint32Array),a=a&&"object"==typeof JSON,a=a&&"function"==typeof JSON.parse,a=a&&"function"==typeof JSON.stringify,a=a&&"function"==typeof atob,a=a&&"function"==typeof btoa},f.assert=function(a,b){if(!a)throw new d(b)},a.Jose=f,a.JoseJWE=g,a.JoseJWS=h;var i=function(){this.setKeyEncryptionAlgorithm("RSA-OAEP"),this.setContentEncryptionAlgorithm("A256GCM"),this.setContentSignAlgorithm("RS256")};f.WebCryptographer=i,i.prototype.setKeyEncryptionAlgorithm=function(a){this.key_encryption=l(a)},i.prototype.getKeyEncryptionAlgorithm=function(){return this.key_encryption.jwe_name},i.prototype.setContentEncryptionAlgorithm=function(a){this.content_encryption=l(a)},i.prototype.getContentEncryptionAlgorithm=function(){return this.content_encryption.jwe_name},i.prototype.setContentSignAlgorithm=function(a){this.content_sign=n(a)},i.prototype.getContentSignAlgorithm=function(){return this.content_sign.jwa_name},i.prototype.createIV=function(){var a=new e(new Array(this.content_encryption.iv_bytes));return f.crypto.getRandomValues(a)},i.prototype.createCek=function(){var a=j(this.content_encryption);return f.crypto.subtle.generateKey(a.id,!0,a.enc_op)},i.prototype.wrapCek=function(a,b){return f.crypto.subtle.wrapKey("raw",a,b,this.key_encryption.id)},i.prototype.unwrapCek=function(a,b){var c=j(this.content_encryption),d=this.content_encryption.specific_cek_bytes>0,e=this.key_encryption.id;return f.crypto.subtle.unwrapKey("raw",a,b,e,c.id,d,c.dec_op)};var j=function(a){var b=a.specific_cek_bytes;if(b){if(16==b)return{id:{name:"AES-CBC",length:128},enc_op:["encrypt"],dec_op:["decrypt"]};if(32==b)return{id:{name:"AES-CBC",length:256},enc_op:["encrypt"],dec_op:["decrypt"]};if(64==b)return{id:{name:"HMAC",hash:{name:"SHA-256"}},enc_op:["sign"],dec_op:["verify"]};if(128==b)return{id:{name:"HMAC",hash:{name:"SHA-384"}},enc_op:["sign"],dec_op:["verify"]};f.assert(!1,"getCekWorkaround: invalid len")}return{id:a.id,enc_op:["encrypt"],dec_op:["decrypt"]}};i.prototype.encrypt=function(a,b,e,g){var h=this.content_encryption;if(a.length!=h.iv_bytes)return c.reject(d("invalid IV length"));if(h.auth.aead){var i=h.auth.tag_bytes,j={name:h.id.name,iv:a,additionalData:b,tagLength:8*i};return e.then(function(a){return f.crypto.subtle.encrypt(j,a,g).then(function(a){var b=a.byteLength-i;return{cipher:a.slice(0,b),tag:a.slice(b)}})})}var l=k(h,e,["encrypt"]),n=l[0],o=l[1],p=o.then(function(b){var c={name:h.id.name,iv:a};return f.crypto.subtle.encrypt(c,b,g)}),q=p.then(function(c){return m(h,n,b,a,c)});return c.all([p,q]).then(function(a){var b=a[0],c=a[1];return{cipher:b,tag:c}})},i.prototype.decrypt=function(a,b,g,h,i){var j=function(a,b,g,h){return f.assert(g instanceof e,"compare: invalid input"),f.assert(h instanceof e,"compare: invalid input"),b.then(function(b){var i=f.crypto.subtle.sign(a.auth.id,b,g),j=f.crypto.subtle.sign(a.auth.id,b,h);return c.all([i,j]).then(function(a){var b=new e(a[0]),f=new e(a[1]);if(b.length!=f.length)throw new d("compare failed");for(var g=0;g0&&f.assert(!1,"convertRsaKey: Was expecting "+e.join()),"undefined"!=typeof a.kty&&f.assert("RSA"==a.kty,"convertRsaKey: expecting rsa_key['kty'] to be 'RSA'"),d.kty="RSA";try{n(a.alg),c=a.alg}catch(b){try{l(a.alg),c=a.alg}catch(a){f.assert(c,"convertRsaKey: expecting rsa_key['alg'] to have a valid value")}}d.alg=c;for(var g=function(a){return parseInt(a,16)},h=0;h0;if(!h)throw new d("No recipients defined. At least one is required to verify the JWS.");if(a.waiting_kid)throw new d("still generating key IDs");return b.forEach(function(b){var c=b.protected.kid;f&&(e[c]=f(c)),g.push(a.cryptographer.verify(b.aad,a.payload,b.signature,e[c],c).then(function(b){return b.verified&&(b.payload=q.Base64Url.decode(a.payload)),b}))}),c.all(g)}}(window,window.crypto,window.Promise,window.Error,window.Uint8Array); \ No newline at end of file +!function(a,b,c,d,e){"use strict";b.subtle||(b.subtle=b.webkitSubtle);var f={},g={},h={};a.setCrypto=function(a){f.crypto=a},a.setCrypto(b),"function"!=typeof atob&&(atob=function(a){return new Buffer(a,"base64").toString("binary")}),"function"!=typeof btoa&&(btoa=function(a){var b;return b=a instanceof Buffer?a:new Buffer(a.toString(),"binary"),b.toString("base64")}),f.caniuse=function(){var a=!0;return a=a&&"function"==typeof c,a=a&&"function"==typeof c.reject,a=a&&"function"==typeof c.prototype.then,a=a&&"function"==typeof c.all,a=a&&"object"==typeof f.crypto,a=a&&"object"==typeof f.crypto.subtle,a=a&&"function"==typeof f.crypto.getRandomValues,a=a&&"function"==typeof f.crypto.subtle.importKey,a=a&&"function"==typeof f.crypto.subtle.generateKey,a=a&&"function"==typeof f.crypto.subtle.exportKey,a=a&&"function"==typeof f.crypto.subtle.wrapKey,a=a&&"function"==typeof f.crypto.subtle.unwrapKey,a=a&&"function"==typeof f.crypto.subtle.encrypt,a=a&&"function"==typeof f.crypto.subtle.decrypt,a=a&&"function"==typeof f.crypto.subtle.sign,a=a&&"function"==typeof ArrayBuffer,a=a&&("function"==typeof e||"object"==typeof e),a=a&&("function"==typeof Uint32Array||"object"==typeof Uint32Array),a=a&&"object"==typeof JSON,a=a&&"function"==typeof JSON.parse,a=a&&"function"==typeof JSON.stringify,a=a&&"function"==typeof atob,a=a&&"function"==typeof btoa},f.assert=function(a,b){if(!a)throw new d(b)},a.Jose=f,a.JoseJWE=g,a.JoseJWS=h;var i=function(){this.setKeyEncryptionAlgorithm("RSA-OAEP"),this.setContentEncryptionAlgorithm("A256GCM"),this.setContentSignAlgorithm("RS256")};f.WebCryptographer=i,i.prototype.setKeyEncryptionAlgorithm=function(a){this.key_encryption=l(a)},i.prototype.getKeyEncryptionAlgorithm=function(){return this.key_encryption.jwe_name},i.prototype.setContentEncryptionAlgorithm=function(a){this.content_encryption=l(a)},i.prototype.getContentEncryptionAlgorithm=function(){return this.content_encryption.jwe_name},i.prototype.setContentSignAlgorithm=function(a){this.content_sign=n(a)},i.prototype.getContentSignAlgorithm=function(){return this.content_sign.jwa_name},i.prototype.createIV=function(){var a=new e(new Array(this.content_encryption.iv_bytes));return f.crypto.getRandomValues(a)},i.prototype.createCek=function(){var a=j(this.content_encryption);return f.crypto.subtle.generateKey(a.id,!0,a.enc_op)},i.prototype.wrapCek=function(a,b){return f.crypto.subtle.wrapKey("raw",a,b,this.key_encryption.id)},i.prototype.unwrapCek=function(a,b){var c=j(this.content_encryption),d=this.content_encryption.specific_cek_bytes>0,e=this.key_encryption.id;return f.crypto.subtle.unwrapKey("raw",a,b,e,c.id,d,c.dec_op)};var j=function(a){var b=a.specific_cek_bytes;if(b){if(16==b)return{id:{name:"AES-CBC",length:128},enc_op:["encrypt"],dec_op:["decrypt"]};if(32==b)return{id:{name:"AES-CBC",length:256},enc_op:["encrypt"],dec_op:["decrypt"]};if(64==b)return{id:{name:"HMAC",hash:{name:"SHA-256"}},enc_op:["sign"],dec_op:["verify"]};if(128==b)return{id:{name:"HMAC",hash:{name:"SHA-384"}},enc_op:["sign"],dec_op:["verify"]};f.assert(!1,"getCekWorkaround: invalid len")}return{id:a.id,enc_op:["encrypt"],dec_op:["decrypt"]}};i.prototype.encrypt=function(a,b,e,g){var h=this.content_encryption;if(a.length!=h.iv_bytes)return c.reject(d("invalid IV length"));if(h.auth.aead){var i=h.auth.tag_bytes,j={name:h.id.name,iv:a,additionalData:b,tagLength:8*i};return e.then(function(a){return f.crypto.subtle.encrypt(j,a,g).then(function(a){var b=a.byteLength-i;return{cipher:a.slice(0,b),tag:a.slice(b)}})})}var l=k(h,e,["encrypt"]),n=l[0],o=l[1],p=o.then(function(b){var c={name:h.id.name,iv:a};return f.crypto.subtle.encrypt(c,b,g)}),q=p.then(function(c){return m(h,n,b,a,c)});return c.all([p,q]).then(function(a){var b=a[0],c=a[1];return{cipher:b,tag:c}})},i.prototype.decrypt=function(a,b,g,h,i){var j=function(a,b,g,h){return f.assert(g instanceof e,"compare: invalid input"),f.assert(h instanceof e,"compare: invalid input"),b.then(function(b){var i=f.crypto.subtle.sign(a.auth.id,b,g),j=f.crypto.subtle.sign(a.auth.id,b,h);return c.all([i,j]).then(function(a){var b=new e(a[0]),f=new e(a[1]);if(b.length!=f.length)throw new d("compare failed");for(var g=0;g0&&f.assert(!1,"convertRsaKey: Was expecting "+e.join()),"undefined"!=typeof a.kty&&f.assert("RSA"==a.kty,"convertRsaKey: expecting rsa_key['kty'] to be 'RSA'"),d.kty="RSA";try{n(a.alg),c=a.alg}catch(b){try{l(a.alg),c=a.alg}catch(a){f.assert(c,"convertRsaKey: expecting rsa_key['alg'] to have a valid value")}}d.alg=c;for(var g=function(a){return parseInt(a,16)},h=0;h0;if(!h)throw new d("No recipients defined. At least one is required to verify the JWS.");if(a.waiting_kid)throw new d("still generating key IDs");return b.forEach(function(b){var c=b.protected.kid;f&&(e[c]=f(c)),g.push(a.cryptographer.verify(b.aad,a.payload,b.signature,e[c],c).then(function(b){return b.verified&&(b.payload=q.Base64Url.decode(a.payload)),b}))}),c.all(g)}}(window,window.crypto,window.Promise,window.Error,window.Uint8Array); \ No newline at end of file diff --git a/package.json b/package.json index cd26e74..eec75df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jose-jwe-jws", - "version": "0.1.2", + "version": "0.1.4", "description": "Library to encrypt and decrypt data in JSON Web Encryption (JWE) format and to sign data in JSON Web Signature (JWS) format. Leverages Browser's native web crypto API.", "keywords": [ "crypto",