rasha.js/lib/rasha.js

113 行
3.5 KiB
JavaScript
Raw 通常表示 履歴

2018-11-21 23:47:41 +00:00
'use strict';
var RSA = module.exports;
2018-11-22 07:39:43 +00:00
var SSH = require('./ssh.js');
2018-11-22 09:09:02 +00:00
var PEM = require('./pem.js');
var x509 = require('./x509.js');
var ASN1 = require('./asn1.js');
2018-11-22 08:46:20 +00:00
var Enc = require('./encoding.js');
2018-11-22 07:39:43 +00:00
2018-11-22 08:46:20 +00:00
/*global Promise*/
RSA.parse = function parseRsa(opts) {
return Promise.resolve().then(function () {
if (!opts || !opts.pem || 'string' !== typeof opts.pem) {
throw new Error("must pass { pem: pem } as a string");
}
if (0 === opts.pem.indexOf('ssh-rsa ')) {
return SSH.parse(opts.pem);
}
var pem = opts.pem;
var block = PEM.parseBlock(pem);
//var hex = toHex(u8);
2018-11-22 09:36:21 +00:00
var jwk = { kty: 'RSA', n: null, e: null };
2018-11-22 09:09:02 +00:00
var asn1 = ASN1.parse(block.der);
var meta = x509.guess(block.der, asn1);
2018-11-22 08:46:20 +00:00
2018-11-22 09:09:02 +00:00
if ('pkcs1' === meta.format) {
2018-11-22 08:46:20 +00:00
jwk = RSA.parsePkcs1(block.der, asn1, jwk);
} else {
jwk = RSA.parsePkcs8(block.der, asn1, jwk);
}
return jwk;
});
};
RSA.toJwk = RSA.import = RSA.parse;
2018-11-22 07:39:43 +00:00
/*
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
*/
2018-11-22 08:46:20 +00:00
RSA.parsePkcs1 = function parseRsaPkcs1(buf, asn1, jwk) {
if (!asn1.children.every(function(el) {
return 0x02 === el.type;
})) {
throw new Error("not an RSA PKCS#1 public or private key (not all ints)");
}
2018-11-22 07:39:43 +00:00
2018-11-22 08:46:20 +00:00
if (2 === asn1.children.length) {
2018-11-22 07:39:43 +00:00
2018-11-22 08:46:20 +00:00
jwk.n = Enc.bufToUrlBase64(asn1.children[0].value);
jwk.e = Enc.bufToUrlBase64(asn1.children[1].value);
return jwk;
} else if (asn1.children.length >= 9) {
// the standard allows for "otherPrimeInfos", hence at least 9
jwk.n = Enc.bufToUrlBase64(asn1.children[1].value);
jwk.e = Enc.bufToUrlBase64(asn1.children[2].value);
jwk.d = Enc.bufToUrlBase64(asn1.children[3].value);
jwk.p = Enc.bufToUrlBase64(asn1.children[4].value);
jwk.q = Enc.bufToUrlBase64(asn1.children[5].value);
jwk.dp = Enc.bufToUrlBase64(asn1.children[6].value);
jwk.dq = Enc.bufToUrlBase64(asn1.children[7].value);
jwk.qi = Enc.bufToUrlBase64(asn1.children[8].value);
return jwk;
2018-11-22 09:09:02 +00:00
2018-11-22 08:46:20 +00:00
} else {
throw new Error("not an RSA PKCS#1 public or private key (wrong number of ints)");
}
};
2018-11-22 09:09:02 +00:00
2018-11-22 08:46:20 +00:00
RSA.parsePkcs8 = function parseRsaPkcs8(buf, asn1, jwk) {
2018-11-22 09:36:21 +00:00
if (2 === asn1.children.length
&& 0x03 === asn1.children[1].type
&& 0x30 === asn1.children[1].value[0]) {
asn1 = ASN1.parse(asn1.children[1].value);
jwk.n = Enc.bufToUrlBase64(asn1.children[0].value);
jwk.e = Enc.bufToUrlBase64(asn1.children[1].value);
} else if (3 === asn1.children.length
&& 0x04 === asn1.children[2].type
&& 0x30 === asn1.children[2].children[0].type
&& 0x02 === asn1.children[2].children[0].children[0].type) {
asn1 = asn1.children[2].children[0];
jwk.n = Enc.bufToUrlBase64(asn1.children[1].value);
jwk.e = Enc.bufToUrlBase64(asn1.children[2].value);
jwk.d = Enc.bufToUrlBase64(asn1.children[3].value);
jwk.p = Enc.bufToUrlBase64(asn1.children[4].value);
jwk.q = Enc.bufToUrlBase64(asn1.children[5].value);
jwk.dp = Enc.bufToUrlBase64(asn1.children[6].value);
jwk.dq = Enc.bufToUrlBase64(asn1.children[7].value);
jwk.qi = Enc.bufToUrlBase64(asn1.children[8].value);
} else {
throw new Error("not an RSA PKCS#8 public or private key (wrong format)");
}
2018-11-22 09:09:02 +00:00
return jwk;
2018-11-22 07:39:43 +00:00
};