bip70: refactor error handling.
This commit is contained in:
parent
89ff0796c7
commit
dae6917c00
@ -154,18 +154,18 @@ PaymentRequest.prototype.getAlgorithm = function getAlgorithm() {
|
||||
var parts;
|
||||
|
||||
if (!this.pkiType)
|
||||
return;
|
||||
throw new Error('No PKI type available.');
|
||||
|
||||
parts = this.pkiType.split('+');
|
||||
|
||||
if (parts.length !== 2)
|
||||
return;
|
||||
throw new Error('Could not parse PKI algorithm.');
|
||||
|
||||
if (parts[0] !== 'x509')
|
||||
return;
|
||||
throw new Error('Unknown PKI type: ' + parts[0]);
|
||||
|
||||
if (parts[1] !== 'sha1' && parts[1] !== 'sha256')
|
||||
return;
|
||||
throw new Error('Unknown hash algorithm: ' + parts[1]);
|
||||
|
||||
return new Algorithm(parts[0], parts[1]);
|
||||
};
|
||||
@ -195,7 +195,6 @@ PaymentRequest.prototype.signatureData = function signatureData() {
|
||||
|
||||
PaymentRequest.prototype.signatureHash = function signatureHash() {
|
||||
var alg = this.getAlgorithm();
|
||||
assert(alg, 'No hash algorithm available.');
|
||||
return crypto.hash(alg.hash, this.signatureData());
|
||||
};
|
||||
|
||||
@ -208,8 +207,7 @@ PaymentRequest.prototype.setChain = function setChain(chain) {
|
||||
var bw = new ProtoWriter();
|
||||
var i, cert, pem;
|
||||
|
||||
if (!Array.isArray(chain))
|
||||
chain = [chain];
|
||||
assert(Array.isArray(chain), 'Chain must be an array.');
|
||||
|
||||
for (i = 0; i < chain.length; i++) {
|
||||
cert = chain[i];
|
||||
@ -261,8 +259,6 @@ PaymentRequest.prototype.sign = function sign(key, chain) {
|
||||
this.pkiType = 'x509+sha256';
|
||||
|
||||
alg = this.getAlgorithm();
|
||||
assert(alg, 'No hash algorithm available.');
|
||||
|
||||
msg = this.signatureData();
|
||||
chain = this.getChain();
|
||||
|
||||
@ -278,21 +274,26 @@ PaymentRequest.prototype.verify = function verify() {
|
||||
var alg, msg, sig, chain;
|
||||
|
||||
if (!this.pkiType || this.pkiType === 'none')
|
||||
return true;
|
||||
return false;
|
||||
|
||||
if (!this.signature)
|
||||
return false;
|
||||
|
||||
alg = this.getAlgorithm();
|
||||
|
||||
if (!alg)
|
||||
try {
|
||||
alg = this.getAlgorithm();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
msg = this.signatureData();
|
||||
sig = this.signature;
|
||||
chain = this.getChain();
|
||||
|
||||
return x509.verifySubject(alg.hash, msg, sig, chain);
|
||||
try {
|
||||
return x509.verifySubject(alg.hash, msg, sig, chain);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -302,9 +303,13 @@ PaymentRequest.prototype.verify = function verify() {
|
||||
|
||||
PaymentRequest.prototype.verifyChain = function verifyChain() {
|
||||
if (!this.pkiType || this.pkiType === 'none')
|
||||
return true;
|
||||
return false;
|
||||
|
||||
return x509.verifyChain(this.getChain());
|
||||
try {
|
||||
return x509.verifyChain(this.getChain());
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -316,18 +321,15 @@ PaymentRequest.prototype.getCA = function getCA() {
|
||||
var chain, root;
|
||||
|
||||
if (!this.pkiType || this.pkiType === 'none')
|
||||
return;
|
||||
throw new Error('No CA found (pkiType).');
|
||||
|
||||
chain = this.getChain();
|
||||
|
||||
if (chain.length === 0)
|
||||
return;
|
||||
throw new Error('No CA found (chain).');
|
||||
|
||||
root = x509.parse(chain[chain.length - 1]);
|
||||
|
||||
if (!root)
|
||||
return;
|
||||
|
||||
return new CA(root);
|
||||
};
|
||||
|
||||
|
||||
@ -154,7 +154,6 @@ x509.setTrust = function setTrust(certs) {
|
||||
assert(Buffer.isBuffer(cert), 'Certificates must be PEM or DER.');
|
||||
|
||||
cert = x509.parse(cert);
|
||||
assert(cert, 'Could not parse certificate.');
|
||||
|
||||
hash = crypto.sha256(cert.raw);
|
||||
hash = hash.toString('hex');
|
||||
@ -194,8 +193,13 @@ x509.setFingerprints = function setFingerprints(hashes) {
|
||||
*/
|
||||
|
||||
x509.getKeyAlgorithm = function getKeyAlgorithm(cert) {
|
||||
var alg = cert.tbs.pubkey.alg.alg;
|
||||
return x509.oid[alg];
|
||||
var oid = cert.tbs.pubkey.alg.alg;
|
||||
var alg = x509.oid[oid];
|
||||
|
||||
if (!alg)
|
||||
throw new Error('Unknown key algorithm: ' + oid);
|
||||
|
||||
return alg;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -205,8 +209,13 @@ x509.getKeyAlgorithm = function getKeyAlgorithm(cert) {
|
||||
*/
|
||||
|
||||
x509.getSigAlgorithm = function getSigAlgorithm(cert) {
|
||||
var alg = cert.sigAlg.alg;
|
||||
return x509.oid[alg];
|
||||
var oid = cert.sigAlg.alg;
|
||||
var alg = x509.oid[oid];
|
||||
|
||||
if (!alg || !alg.hash)
|
||||
throw new Error('Unknown signature algorithm: ' + oid);
|
||||
|
||||
return alg;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -216,18 +225,20 @@ x509.getSigAlgorithm = function getSigAlgorithm(cert) {
|
||||
*/
|
||||
|
||||
x509.getCurve = function getCurve(params) {
|
||||
var oid;
|
||||
|
||||
if (!params)
|
||||
return;
|
||||
var oid, curve;
|
||||
|
||||
try {
|
||||
oid = ASN1.parseOID(params);
|
||||
} catch (e) {
|
||||
return;
|
||||
throw new Error('Could not parse curve OID.');
|
||||
}
|
||||
|
||||
return x509.curves[oid];
|
||||
curve = x509.curves[oid];
|
||||
|
||||
if (!curve)
|
||||
throw new Error('Unknown ECDSA curve: ' + oid);
|
||||
|
||||
return curve;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -240,7 +251,7 @@ x509.parse = function parse(der) {
|
||||
try {
|
||||
return ASN1.parseCert(der);
|
||||
} catch (e) {
|
||||
;
|
||||
throw new Error('Could not parse DER certificate.');
|
||||
}
|
||||
};
|
||||
|
||||
@ -254,14 +265,15 @@ x509.getPublicKey = function getPublicKey(cert) {
|
||||
var alg = x509.getKeyAlgorithm(cert);
|
||||
var key, params, curve;
|
||||
|
||||
if (!alg)
|
||||
return;
|
||||
|
||||
key = cert.tbs.pubkey.pubkey;
|
||||
params = cert.tbs.pubkey.alg.params;
|
||||
|
||||
if (alg.key === 'ecdsa')
|
||||
if (alg.key === 'ecdsa') {
|
||||
if (!params)
|
||||
throw new Error('No curve selected for ECDSA (cert).');
|
||||
|
||||
curve = x509.getCurve(params);
|
||||
}
|
||||
|
||||
return {
|
||||
alg: alg.key,
|
||||
@ -298,8 +310,12 @@ x509.getSigningKey = function getSigningKey(key, chain) {
|
||||
if (typeof key === 'string') {
|
||||
key = PEM.decode(key);
|
||||
|
||||
if (key.alg === 'ecdsa')
|
||||
if (key.alg === 'ecdsa') {
|
||||
if (!key.params)
|
||||
throw new Error('No curve selected for ECDSA (key).');
|
||||
|
||||
curve = x509.getCurve(key.params);
|
||||
}
|
||||
|
||||
key = {
|
||||
alg: key.alg,
|
||||
@ -309,10 +325,7 @@ x509.getSigningKey = function getSigningKey(key, chain) {
|
||||
};
|
||||
} else {
|
||||
cert = x509.parse(chain[0]);
|
||||
assert(cert, 'Could not parse certificate.');
|
||||
|
||||
pub = x509.getPublicKey(cert);
|
||||
assert(pub, 'Certificate uses an unknown algorithm.');
|
||||
|
||||
key = {
|
||||
alg: pub.alg,
|
||||
@ -349,18 +362,11 @@ x509.getVerifyKey = function getVerifyKey(chain) {
|
||||
var cert, key;
|
||||
|
||||
if (chain.length === 0)
|
||||
return;
|
||||
throw new Error('No verify key available (cert chain).');
|
||||
|
||||
cert = x509.parse(chain[0]);
|
||||
|
||||
if (!cert)
|
||||
return;
|
||||
|
||||
key = x509.getPublicKey(cert);
|
||||
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
return key;
|
||||
};
|
||||
|
||||
@ -390,10 +396,6 @@ x509.parseChain = function parseChain(chain) {
|
||||
|
||||
for (i = 0; i < chain.length; i++) {
|
||||
cert = x509.parse(chain[i]);
|
||||
|
||||
if (!cert)
|
||||
return;
|
||||
|
||||
certs.push(cert);
|
||||
}
|
||||
|
||||
@ -458,13 +460,10 @@ x509.verifyChain = function verifyChain(certs) {
|
||||
var chain = x509.parseChain(certs);
|
||||
var i, child, parent, alg, key, sig, msg;
|
||||
|
||||
if (!chain)
|
||||
return false;
|
||||
|
||||
// Parse certificates and
|
||||
// check validity time.
|
||||
if (!x509.verifyTimes(chain))
|
||||
return false;
|
||||
throw new Error('Invalid certificate times.');
|
||||
|
||||
// Verify signatures.
|
||||
for (i = 1; i < chain.length; i++) {
|
||||
@ -472,23 +471,20 @@ x509.verifyChain = function verifyChain(certs) {
|
||||
parent = chain[i];
|
||||
|
||||
alg = x509.getSigAlgorithm(child);
|
||||
key = x509.getPublicKey(parent);
|
||||
msg = child.tbs.raw;
|
||||
sig = child.sig;
|
||||
key = x509.getPublicKey(parent);
|
||||
|
||||
if (!alg || !alg.hash)
|
||||
return false;
|
||||
|
||||
if (!key)
|
||||
return false;
|
||||
|
||||
if (!pk.verify(alg.hash, msg, sig, key))
|
||||
return false;
|
||||
throw new Error(alg.key + ' verification failed for chain.');
|
||||
}
|
||||
|
||||
// Make sure we trust one
|
||||
// of the certs in the chain.
|
||||
return x509.verifyTrust(chain);
|
||||
if (!x509.verifyTrust(chain))
|
||||
throw new Error('Certificate chain is untrusted.');
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user