This repository has been archived by the owner on Feb 27, 2023. It is now read-only.
/
jose-jwe.min.js
1 lines (1 loc) · 11.5 KB
/
jose-jwe.min.js
1
!function(){JoseJWE={},JoseJWE.caniuse=function(){var a=!0;return a=a&&"function"==typeof Promise,a=a&&"function"==typeof Promise.reject,a=a&&"function"==typeof Promise.prototype.then,a=a&&"function"==typeof Promise.all,a=a&&"object"==typeof crypto,a=a&&"object"==typeof crypto.subtle,a=a&&"function"==typeof crypto.getRandomValues,a=a&&"function"==typeof crypto.subtle.importKey,a=a&&"function"==typeof crypto.subtle.generateKey,a=a&&"function"==typeof crypto.subtle.exportKey,a=a&&"function"==typeof crypto.subtle.wrapKey,a=a&&"function"==typeof crypto.subtle.unwrapKey,a=a&&"function"==typeof crypto.subtle.encrypt,a=a&&"function"==typeof crypto.subtle.decrypt,a=a&&"function"==typeof crypto.subtle.sign,a=a&&"function"==typeof ArrayBuffer,a=a&&("function"==typeof Uint8Array||"object"==typeof Uint8Array),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},JoseJWE.assert=function(a,b){if(!a)throw new Error(b)},JoseJWE.WebCryptographer=function(){this.setKeyEncryptionAlgorithm("RSA-OAEP"),this.setContentEncryptionAlgorithm("A256GCM")},JoseJWE.WebCryptographer.prototype.setKeyEncryptionAlgorithm=function(a){this.key_encryption=d(a)},JoseJWE.WebCryptographer.prototype.getKeyEncryptionAlgorithm=function(){return this.key_encryption.jwe_name},JoseJWE.WebCryptographer.prototype.setContentEncryptionAlgorithm=function(a){this.content_encryption=d(a)},JoseJWE.WebCryptographer.prototype.getContentEncryptionAlgorithm=function(){return this.content_encryption.jwe_name},JoseJWE.WebCryptographer.prototype.createIV=function(){var a=new Uint8Array(new Array(this.content_encryption.iv_bytes)),b=crypto.getRandomValues(a);return b},JoseJWE.WebCryptographer.prototype.createCek=function(){var b=a(this.content_encryption);return crypto.subtle.generateKey(b.id,!0,b.enc_op)},JoseJWE.WebCryptographer.prototype.wrapCek=function(a,b){return crypto.subtle.wrapKey("raw",a,b,this.key_encryption.id)},JoseJWE.WebCryptographer.prototype.unwrapCek=function(b,c){var d=a(this.content_encryption),e=this.content_encryption.specific_cek_bytes>0,f=this.key_encryption.id;return crypto.subtle.unwrapKey("raw",b,c,f,d.id,e,d.dec_op)};var a=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"]};JoseJWE.assert(!1,"getCekWorkaround: invalid len")}return{id:a.id,enc_op:["encrypt"],dec_op:["decrypt"]}};JoseJWE.WebCryptographer.prototype.encrypt=function(a,d,e,f){var g=this.content_encryption;if(a.length!=g.iv_bytes)return Promise.reject(Error("invalid IV length"));if(g.auth.aead){var h=g.auth.tag_bytes,i={name:g.id.name,iv:a,additionalData:d,tagLength:8*h};return e.then(function(a){return crypto.subtle.encrypt(i,a,f).then(function(a){var b=a.byteLength-h;return{cipher:a.slice(0,b),tag:a.slice(b)}})})}var j=b(g,e,["encrypt"]),k=j[0],l=j[1],m=l.then(function(b){var c={name:g.id.name,iv:a};return crypto.subtle.encrypt(c,b,f)}),n=m.then(function(b){return c(g,k,d,a,b)});return Promise.all([m,n]).then(function(a){var b=a[0],c=a[1];return{cipher:b,tag:c}})},JoseJWE.WebCryptographer.prototype.decrypt=function(a,d,f,g,h){var i=function(a,b,c,d){return JoseJWE.assert(c instanceof Uint8Array,"compare: invalid input"),JoseJWE.assert(d instanceof Uint8Array,"compare: invalid input"),b.then(function(b){var e=crypto.subtle.sign(a.auth.id,b,c),f=crypto.subtle.sign(a.auth.id,b,d);return Promise.all([e,f]).then(function(a){var b=new Uint8Array(a[0]),c=new Uint8Array(a[1]);if(b.length!=c.length)throw new Error("compare failed");for(var d=0;d<b.length;d++)if(b[d]!=c[d])throw new Error("compare failed");return Promise.accept(null)})})};if(f.length!=this.content_encryption.iv_bytes)return Promise.reject(Error("decryptCiphertext: invalid IV"));var j=this.content_encryption;if(j.auth.aead){var k={name:j.id.name,iv:f,additionalData:d,tagLength:8*j.auth.tag_bytes};return a.then(function(a){var b=e.arrayBufferConcat(g,h);return crypto.subtle.decrypt(k,a,b)})}var l=b(j,a,["decrypt"]),m=l[0],n=l[1],o=c(j,m,d,f,g);return Promise.all([n,o]).then(function(a){var b=a[0],c=a[1];return i(j,m,new Uint8Array(c),h).then(function(){var a={name:j.id.name,iv:f};return crypto.subtle.decrypt(a,b,g)})["catch"](function(){return Promise.reject(Error("decryptCiphertext: MAC failed."))})})};var b=function(a,b,c){var d=b.then(function(a){return crypto.subtle.exportKey("raw",a)}),e=d.then(function(b){if(8*b.byteLength!=a.id.length+8*a.auth.key_bytes)return Promise.reject(Error("encryptPlainText: incorrect cek length"));var c=b.slice(0,a.auth.key_bytes);return crypto.subtle.importKey("raw",c,a.auth.id,!1,["sign"])}),f=d.then(function(b){if(8*b.byteLength!=a.id.length+8*a.auth.key_bytes)return Promise.reject(Error("encryptPlainText: incorrect cek length"));var d=b.slice(a.auth.key_bytes);return crypto.subtle.importKey("raw",d,a.id,!1,c)});return[e,f]},c=function(a,b,c,d,f){return b.then(function(b){var g=new Uint8Array(e.arrayFromInt32(8*c.length)),h=new Uint8Array(8);h.set(g,4);var i=e.arrayBufferConcat(c,d,f,h);return crypto.subtle.sign(a.auth.id,b,i).then(function(b){return b.slice(0,a.auth.truncated_bytes)})})},d=function(a){switch(a){case"RSA-OAEP":return{jwe_name:"RSA-OAEP",id:{name:"RSA-OAEP",hash:{name:"SHA-1"}}};case"RSA-OAEP-256":return{jwe_name:"RSA-OAEP-256",id:{name:"RSA-OAEP",hash:{name:"SHA-256"}}};case"A128KW":return{jwe_name:"A128KW",id:{name:"AES-KW",length:128}};case"A256KW":return{jwe_name:"A256KW",id:{name:"AES-KW",length:256}};case"A128CBC-HS256":return{jwe_name:"A128CBC-HS256",id:{name:"AES-CBC",length:128},iv_bytes:16,specific_cek_bytes:32,auth:{key_bytes:16,id:{name:"HMAC",hash:{name:"SHA-256"}},truncated_bytes:16}};case"A256CBC-HS512":return{jwe_name:"A256CBC-HS512",id:{name:"AES-CBC",length:256},iv_bytes:16,specific_cek_bytes:64,auth:{key_bytes:32,id:{name:"HMAC",hash:{name:"SHA-512"}},truncated_bytes:32}};case"A128GCM":return{jwe_name:"A128GCM",id:{name:"AES-GCM",length:128},iv_bytes:12,auth:{aead:!0,tag_bytes:16}};case"A256GCM":return{jwe_name:"A256GCM",id:{name:"AES-GCM",length:256},iv_bytes:12,auth:{aead:!0,tag_bytes:16}};default:throw Error("unsupported algorithm: "+a)}};JoseJWE.Utils={};var e={};JoseJWE.Utils.importRsaPublicKey=function(a){var b=e.convertRsaKey(a,["n","e"]),c=d("RSA-OAEP");return crypto.subtle.importKey("jwk",b,c.id,!1,["wrapKey"])},JoseJWE.Utils.importRsaPrivateKey=function(a){var b=e.convertRsaKey(a,["n","e","d","p","q","dp","dq","qi"]),c=d("RSA-OAEP");return crypto.subtle.importKey("jwk",b,c.id,!1,["unwrapKey"])},e.isString=function(a){return"string"==typeof a||a instanceof String},e.arrayish=function(a){return a instanceof Array?a:a instanceof Uint8Array?a:a instanceof ArrayBuffer?new Uint8Array(a):void JoseJWE.assert(!1,"arrayish: invalid input")},e.convertRsaKey=function(a,b){var c={},d=[];b.map(function(b){"undefined"==typeof a[b]&&d.push(b)}),d.length>0&&JoseJWE.assert(!1,"convertRsaKey: Was expecting "+d.join()),"undefined"!=typeof a.kty&&JoseJWE.assert("RSA"==a.kty,"convertRsaKey: expecting rsa_key['kty'] to be 'RSA'"),c.kty="RSA","undefined"!=typeof a.alg&&JoseJWE.assert("RSA-OAEP"==a.alg,"convertRsaKey: expecting rsa_key['alg'] to be 'RSA-OAEP'"),c.alg="RSA-OAEP";for(var f=function(a){return parseInt(a,16)},g=0;g<b.length;g++){var h=b[g],i=a[h];if("e"==h)"number"==typeof i&&(i=e.Base64Url.encodeArray(e.stripLeadingZeros(e.arrayFromInt32(i))));else if(/^([0-9a-fA-F]{2}:)+[0-9a-fA-F]{2}$/.test(i)){var j=i.split(":").map(f);i=e.Base64Url.encodeArray(e.stripLeadingZeros(j))}else"string"!=typeof i&&JoseJWE.assert(!1,"convertRsaKey: expecting rsa_key['"+h+"'] to be a string");c[h]=i}return c},e.arrayFromString=function(a){JoseJWE.assert(e.isString(a),"arrayFromString: invalid input");var b=a.split("").map(function(a){return a.charCodeAt(0)});return new Uint8Array(b)},e.stringFromArray=function(a){JoseJWE.assert(a instanceof ArrayBuffer,"stringFromArray: invalid input"),a=new Uint8Array(a);for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return b},e.stripLeadingZeros=function(a){a instanceof ArrayBuffer&&(a=new Uint8Array(a));for(var b=!0,c=[],d=0;d<a.length;d++)b&&0===a[d]||(b=!1,c.push(a[d]));return c},e.arrayFromInt32=function(a){JoseJWE.assert("number"==typeof a,"arrayFromInt32: invalid input"),JoseJWE.assert(a==a|0,"arrayFromInt32: out of range");for(var b=new Uint8Array(new Uint32Array([a]).buffer),c=new Uint8Array(4),d=0;4>d;d++)c[d]=b[3-d];return c.buffer},e.arrayBufferConcat=function(){for(var a=[],b=0,c=0;c<arguments.length;c++)a.push(e.arrayish(arguments[c])),b+=a[c].length;var d=new Uint8Array(b),f=0;for(c=0;c<arguments.length;c++)for(var g=0;g<a[c].length;g++)d[f++]=a[c][g];return JoseJWE.assert(f==b,"arrayBufferConcat: unexpected offset"),d},e.Base64Url={},e.Base64Url.encode=function(a){return JoseJWE.assert(e.isString(a),"Base64Url.encode: invalid input"),btoa(a).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},e.Base64Url.encodeArray=function(a){a=e.arrayish(a);for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return e.Base64Url.encode(b)},e.Base64Url.decode=function(a){return JoseJWE.assert(e.isString(a),"Base64Url.decode: invalid input"),atob(a.replace(/-/g,"+").replace(/_/g,"/"))},e.Base64Url.decodeArray=function(a){return JoseJWE.assert(e.isString(a),"Base64Url.decodeArray: invalid input"),e.arrayFromString(e.Base64Url.decode(a))},JoseJWE.Encrypter=function(a,b){this.cryptographer=a,this.key_promise=b,this.userHeaders={}},JoseJWE.Encrypter.prototype.addHeader=function(a,b){this.userHeaders[a]=b},JoseJWE.Encrypter.prototype.encrypt=function(a){var b=function(a,b){var c={};for(var d in this.userHeaders)c[d]=this.userHeaders[d];c.alg=this.cryptographer.getKeyEncryptionAlgorithm(),c.enc=this.cryptographer.getContentEncryptionAlgorithm();var f=e.Base64Url.encode(JSON.stringify(c)),g=this.cryptographer.createIV(),h=e.arrayFromString(f);return b=e.arrayFromString(b),this.cryptographer.encrypt(g,h,a,b).then(function(a){return a.header=f,a.iv=g,a})},c=this.cryptographer.createCek(),d=Promise.all([this.key_promise,c]).then(function(a){var b=a[0],c=a[1];return this.cryptographer.wrapCek(c,b)}.bind(this)),f=b.bind(this,c,a)();return Promise.all([d,f]).then(function(a){var b=a[0],c=a[1];return c.header+"."+e.Base64Url.encodeArray(b)+"."+e.Base64Url.encodeArray(c.iv)+"."+e.Base64Url.encodeArray(c.cipher)+"."+e.Base64Url.encodeArray(c.tag)})},JoseJWE.Decrypter=function(a,b){this.cryptographer=a,this.key_promise=b,this.headers={}},JoseJWE.Decrypter.prototype.getHeaders=function(){return this.headers},JoseJWE.Decrypter.prototype.decrypt=function(a){var b=a.split(".");if(5!=b.length)return Promise.reject(Error("decrypt: invalid input"));if(this.headers=JSON.parse(e.Base64Url.decode(b[0])),!this.headers.alg)return Promise.reject(Error("decrypt: missing alg"));if(!this.headers.enc)return Promise.reject(Error("decrypt: missing enc"));if(this.cryptographer.setKeyEncryptionAlgorithm(this.headers.alg),this.cryptographer.setContentEncryptionAlgorithm(this.headers.enc),this.headers.crit)return Promise.reject(Error("decrypt: crit is not supported"));var c=e.Base64Url.decodeArray(b[1]),d=this.key_promise.then(function(a){return this.cryptographer.unwrapCek(c,a)}.bind(this)),f=this.cryptographer.decrypt(d,e.arrayFromString(b[0]),e.Base64Url.decodeArray(b[2]),e.Base64Url.decodeArray(b[3]),e.Base64Url.decodeArray(b[4]));return f.then(e.stringFromArray)}}();