Skip to content

Commit

Permalink
Add verification helper.
Browse files Browse the repository at this point in the history
- Reduce duplicate code.
- Small cleanups.
- Add note about deprecated OID alias.
  • Loading branch information
davidlehn committed Jan 7, 2022
1 parent cbf53ba commit 2f38758
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 101 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ Forge ChangeLog
links](https://github.com/digitalbazaar/forge/issues/825).

### Changed
- [x509]: Reduce duplicate code with a helper function to create a signature
digest given an signature algorithm OID.
- [x509]: Reduce duplicate code. Add helper function to create a signature
digest given an signature algorithm OID. Add helper function to verify
signatures.

## 1.1.0 - 2022-01-06

Expand Down
168 changes: 69 additions & 99 deletions lib/x509.js
Original file line number Diff line number Diff line change
Expand Up @@ -700,24 +700,19 @@ var _readSignatureParameters = function(oid, obj, fillDefaults) {
var _createSignatureDigest = function(options) {
switch(oids[options.signatureOid]) {
case 'sha1WithRSAEncryption':
// depreacted alias
case 'sha1WithRSASignature':
return forge.md.sha1.create();
break;
case 'md5WithRSAEncryption':
return forge.md.md5.create();
break;
case 'sha256WithRSAEncryption':
return forge.md.sha256.create();
break;
case 'sha384WithRSAEncryption':
return forge.md.sha384.create();
break;
case 'sha512WithRSAEncryption':
return forge.md.sha512.create();
break;
case 'RSASSA-PSS':
return forge.md.sha256.create();
break;
default:
var error = new Error(
'Could not compute ' + options.type + ' digest. ' +
Expand All @@ -727,6 +722,68 @@ var _createSignatureDigest = function(options) {
}
};

/**
* Verify signature on certificate or CSR.
*
* @param options:
* certificate the certificate or CSR to verify.
* md the signature digest.
* signature the signature
* @return a created md instance. throws if unknown oid.
*/
var _verifySignature = function(options) {
var cert = options.certificate;
var scheme;

switch(cert.signatureOid) {
case oids.sha1WithRSAEncryption:
// depreacted alias
case oids.sha1WithRSASignature:
/* use PKCS#1 v1.5 padding scheme */
break;
case oids['RSASSA-PSS']:
var hash, mgf;

/* initialize mgf */
hash = oids[cert.signatureParameters.mgf.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
var error = new Error('Unsupported MGF hash function.');
error.oid = cert.signatureParameters.mgf.hash.algorithmOid;
error.name = hash;
throw error;
}

mgf = oids[cert.signatureParameters.mgf.algorithmOid];
if(mgf === undefined || forge.mgf[mgf] === undefined) {
var error = new Error('Unsupported MGF function.');
error.oid = cert.signatureParameters.mgf.algorithmOid;
error.name = mgf;
throw error;
}

mgf = forge.mgf[mgf].create(forge.md[hash].create());

/* initialize hash function */
hash = oids[cert.signatureParameters.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
var error = new Error('Unsupported RSASSA-PSS hash function.');
error.oid = cert.signatureParameters.hash.algorithmOid;
error.name = hash;
throw error;
}

scheme = forge.pss.create(
forge.md[hash].create(), mgf, cert.signatureParameters.saltLength
);
break;
}

// verify signature on cert using public key
return cert.publicKey.verify(
options.md.digest().getBytes(), options.signature, scheme
);
};

/**
* Converts an X.509 certificate from PEM format.
*
Expand Down Expand Up @@ -1127,53 +1184,9 @@ pki.createCertificate = function() {
}

if(md !== null) {
var scheme;

switch(child.signatureOid) {
case oids.sha1WithRSAEncryption:
case oids.sha1WithRSASignature:
scheme = undefined; /* use PKCS#1 v1.5 padding scheme */
break;
case oids['RSASSA-PSS']:
var hash, mgf;

/* initialize mgf */
hash = oids[child.signatureParameters.mgf.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
var error = new Error('Unsupported MGF hash function.');
error.oid = child.signatureParameters.mgf.hash.algorithmOid;
error.name = hash;
throw error;
}

mgf = oids[child.signatureParameters.mgf.algorithmOid];
if(mgf === undefined || forge.mgf[mgf] === undefined) {
var error = new Error('Unsupported MGF function.');
error.oid = child.signatureParameters.mgf.algorithmOid;
error.name = mgf;
throw error;
}

mgf = forge.mgf[mgf].create(forge.md[hash].create());

/* initialize hash function */
hash = oids[child.signatureParameters.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
throw {
message: 'Unsupported RSASSA-PSS hash function.',
oid: child.signatureParameters.hash.algorithmOid,
name: hash
};
}

scheme = forge.pss.create(forge.md[hash].create(), mgf,
child.signatureParameters.saltLength);
break;
}

// verify signature on cert using public key
rval = cert.publicKey.verify(
md.digest().getBytes(), child.signature, scheme);
rval = _verifySignature({
certificate: cert, md: md, signature: child.signature
});
}

return rval;
Expand Down Expand Up @@ -1826,52 +1839,9 @@ pki.createCertificationRequest = function() {
}

if(md !== null) {
var scheme;

switch(csr.signatureOid) {
case oids.sha1WithRSAEncryption:
case oids.sha1WithRSASignature:
/* use PKCS#1 v1.5 padding scheme */
break;
case oids['RSASSA-PSS']:
var hash, mgf;

/* initialize mgf */
hash = oids[csr.signatureParameters.mgf.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
var error = new Error('Unsupported MGF hash function.');
error.oid = csr.signatureParameters.mgf.hash.algorithmOid;
error.name = hash;
throw error;
}

mgf = oids[csr.signatureParameters.mgf.algorithmOid];
if(mgf === undefined || forge.mgf[mgf] === undefined) {
var error = new Error('Unsupported MGF function.');
error.oid = csr.signatureParameters.mgf.algorithmOid;
error.name = mgf;
throw error;
}

mgf = forge.mgf[mgf].create(forge.md[hash].create());

/* initialize hash function */
hash = oids[csr.signatureParameters.hash.algorithmOid];
if(hash === undefined || forge.md[hash] === undefined) {
var error = new Error('Unsupported RSASSA-PSS hash function.');
error.oid = csr.signatureParameters.hash.algorithmOid;
error.name = hash;
throw error;
}

scheme = forge.pss.create(forge.md[hash].create(), mgf,
csr.signatureParameters.saltLength);
break;
}

// verify signature on csr using its public key
rval = csr.publicKey.verify(
md.digest().getBytes(), csr.signature, scheme);
rval = _verifySignature({
certificate: csr, md: md, signature: csr.signature
});
}

return rval;
Expand Down

0 comments on commit 2f38758

Please sign in to comment.