Bluecrypt SSH to JWK in VanillaJS for Browsers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1 lines
2.4 KiB

(function(exports){"use strict";if(!exports.Enc){exports.Enc={}}if(!exports.SSH){exports.SSH={}}var Enc=exports.Enc;var SSH=exports.SSH;SSH.parse=function(ssh){ssh=SSH.parseBlock(ssh);ssh=SSH.parseElements(ssh);return SSH.parsePublicKey(ssh)};SSH.parseBlock=function(ssh){ssh=ssh.split(/\s+/g);return{type:ssh[0],bytes:Enc.base64ToBuf(ssh[1]),comment:ssh[2]}};SSH.parseElements=function(ssh){var buf=ssh.bytes;var fulllen=buf.byteLength||buf.length;var offset=buf.byteOffset||0;var i=0;var index=0;var dv=new DataView(buf.buffer.slice(offset,offset+fulllen));var els=[];var el;var len;while(index<fulllen){i+=1;if(i>15){throw new Error("15+ elements, probably not a public ssh key")}len=dv.getUint32(index,false);index+=4;el=buf.slice(index,index+len);if(0===el[0]){el=el.slice(1)}els.push(el);index+=len}if(fulllen!==index){throw new Error("invalid ssh public key length \n"+els.map(function(b){return Enc.bufToHex(b)}).join("\n"))}ssh.elements=els;return ssh};SSH.parsePublicKey=function(ssh){var els=ssh.elements;var typ=Enc.bufToBin(els[0]);var len;if(SSH.types.rsa===typ){ssh.jwk={kty:"RSA",n:Enc.bufToUrlBase64(els[2]),e:Enc.bufToUrlBase64(els[1])};return ssh}if(SSH.types.p256===typ){len=32;ssh.jwk={kty:"EC",crv:"P-256"}}else if(SSH.types.p384===typ){len=48;ssh.jwk={kty:"EC",crv:"P-384"}}else{throw new Error("Unsupported ssh public key type: "+Enc.bufToBin(els[0]))}var x=els[2].slice(1,1+len);var y=els[2].slice(1+len,1+len+len);if(0===x[0]){x=x.slice(1)}if(0===y[0]){y=y.slice(1)}ssh.jwk.x=Enc.bufToUrlBase64(x);ssh.jwk.y=Enc.bufToUrlBase64(y);return ssh};SSH.types={p256:"ecdsa-sha2-nistp256",p384:"ecdsa-sha2-nistp384",rsa:"ssh-rsa"};Enc.base64ToBuf=function(b64){return Enc.binToBuf(atob(b64))};Enc.binToBuf=function(bin){var arr=bin.split("").map(function(ch){return ch.charCodeAt(0)});return"undefined"!==typeof Uint8Array?new Uint8Array(arr):arr};Enc.bufToBase64=function(u8){var bin="";u8.forEach(function(i){bin+=String.fromCharCode(i)});return btoa(bin)};Enc.bufToBin=function(buf){var bin="";buf.forEach(function(ch){bin+=String.fromCharCode(ch)});return bin};Enc.bufToUrlBase64=function(u8){return Enc.bufToBase64(u8).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")};Enc.urlBase64ToBase64=function urlsafeBase64ToBase64(str){var r=str%4;if(2===r){str+="=="}else if(3===r){str+="="}return str.replace(/-/g,"+").replace(/_/g,"/")}})("undefined"!==typeof window?window:module.exports);