csr.min.js
4.36 KB
(function(){"use strict";var CSR=window.CSR={};var Enc=window.Encoding;var X509=window.X509;var Keypairs=window.Keypairs;var ASN1=window.ASN1;var PEM=window.PEM;var Asn1Packer=window.ASN1;var Asn1=ASN1.Any;var BitStr=ASN1.BitStr;var UInt=ASN1.UInt;CSR.csr=function(opts){return CSR._prepare(opts).then(function(opts){return CSR.create(opts).then(function(bytes){return CSR._encode(opts,bytes)})})};CSR._prepare=function(opts){return Promise.resolve().then(function(){opts=JSON.parse(JSON.stringify(opts));if(!opts){throw new Error("You must pass options with key and domains to rsacsr")}if(!Array.isArray(opts.domains)||0===opts.domains.length){new Error("You must pass options.domains as a non-empty array")}if(!opts.domains.every(function(d){if("string"===typeof d){return true}})){throw new Error("You must pass options.domains as strings")}if(opts.jwk){return opts}if(opts.key&&opts.key.kty){opts.jwk=opts.key;return opts}if(!opts.pem&&!opts.key){throw new Error("You must pass options.key as a JSON web key")}return Keypairs.import({pem:opts.pem||opts.key}).then(function(pair){opts.jwk=pair.private;return opts})})};CSR._encode=function(opts,bytes){if("der"===(opts.encoding||"").toLowerCase()){return bytes}return PEM.packBlock({type:"CERTIFICATE REQUEST",bytes:bytes})};CSR.create=function createCsr(opts){var hex=CSR.request({jwk:opts.jwk,domains:opts.domains,encoding:"hex"});return CSR._sign(opts.jwk,hex).then(function(csr){return Enc.hexToBuf(csr)})};CSR.request=function createCsrBody(opts){var asn1pub;if(/^EC/i.test(opts.jwk.kty)){asn1pub=X509.packCsrEcPublicKey(opts.jwk)}else{asn1pub=X509.packCsrRsaPublicKey(opts.jwk)}var hex=X509.packCsr(asn1pub,opts.domains);if("hex"===opts.encoding){return hex}return Enc.hexToBuf(hex)};CSR._sign=function csrEcSig(jwk,request){return Keypairs.sign({jwk:jwk,format:"x509"},Enc.hexToBuf(request)).then(function(sig){return CSR._toDer({request:request,signature:sig,kty:jwk.kty})})};CSR._toDer=function encode(opts){var sty;if(/^EC/i.test(opts.kty)){sty=Asn1("30",Asn1("06","2a8648ce3d040302"))}else{sty=Asn1("30",Asn1("06","2a864886f70d01010b"),Asn1("05"))}return Asn1("30",opts.request,sty,BitStr(Enc.bufToHex(opts.signature)))};X509.packCsr=function(asn1pubkey,domains){return Asn1("30",UInt("00"),Asn1("30",Asn1("31",Asn1("30",Asn1("06","550403"),Asn1("0c",Enc.strToHex(domains[0]))))),asn1pubkey,Asn1("a0",Asn1("30",Asn1("06","2a864886f70d01090e"),Asn1("31",Asn1("30",Asn1("30",Asn1("06","551d11"),Asn1("04",Asn1("30",domains.map(function(d){return Asn1("82",Enc.strToHex(d))}).join("")))))))))};CSR._info=function(der){if("string"===typeof der&&"-"===der[0]){der=PEM.parseBlock(der).bytes}if("string"===typeof der){der=Enc.base64ToBuf(der)}var c=Asn1Parser.parse({der:der,verbose:true,json:false});var kty;if(c.children.length!==3){throw new Error("doesn't look like a certificate request: expected 3 parts of header")}var sig=c.children[2];if(sig.children.length){sig=sig.children[0];sig=Asn1("30",UInt(Enc.bufToHex(sig.children[0].value)),UInt(Enc.bufToHex(sig.children[1].value)));sig=Enc.hexToBuf(sig);kty="EC"}else{sig=sig.value;kty="RSA"}var req=c.children[0];if(4!==req.children.length){throw new Error("doesn't look like a certificate request: expected 4 parts to request")}var sub=Enc.bufToStr(req.children[1].children[0].children[0].children[1].value);var pub;if("EC"===kty){pub=req.children[2].children[1].value.slice(1);pub={kty:kty,x:pub.slice(0,32),y:pub.slice(32)};while(0===pub.x[0]){pub.x=pub.x.slice(1)}while(0===pub.y[0]){pub.y=pub.y.slice(1)}if((pub.x.length||pub.x.byteLength)>48){pub.crv="P-521"}else if((pub.x.length||pub.x.byteLength)>32){pub.crv="P-384"}else{pub.crv="P-256"}pub.x=Enc.bufToUrlBase64(pub.x);pub.y=Enc.bufToUrlBase64(pub.y)}else{pub=req.children[2].children[1].children[0];pub={kty:kty,n:pub.children[0].value,e:pub.children[1].value};while(0===pub.n[0]){pub.n=pub.n.slice(1)}while(0===pub.e[0]){pub.e=pub.e.slice(1)}pub.n=Enc.bufToUrlBase64(pub.n);pub.e=Enc.bufToUrlBase64(pub.e)}var domains=req.children[3].children.filter(function(seq){if("2a864886f70d01090e"===Enc.bufToHex(seq.children[0].value)){return true}}).map(function(seq){return seq.children[1].children[0].children.filter(function(seq2){if("551d11"===Enc.bufToHex(seq2.children[0].value)){return true}}).map(function(seq2){return seq2.children[1].children[0].children.map(function(name){return Enc.bufToStr(name.value)})})[0]})[0];return{subject:sub,altnames:domains,jwk:pub,signature:sig}}})();