refactor: extract createSigner factory and add signature algorithm OID
parent
db7b45d445
commit
179fdf11e4
|
|
@ -240,6 +240,13 @@ z.RsaSigner = class{
|
|||
return forge.pki.oids.sha256;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} the signature algorithm OID for the PKCS#7 SignerInfo
|
||||
*/
|
||||
getSignatureAlgorithmOid(){
|
||||
return forge.pki.oids.sha256WithRSAEncryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} data
|
||||
* @return {string} raw signature bytes
|
||||
|
|
@ -252,6 +259,22 @@ z.RsaSigner = class{
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a Signer implementation for the given key. Today only RSA keys are
|
||||
* supported; this factory is the single place to extend the seam with ECDSA
|
||||
* or post-quantum signers without touching the PDF assembly.
|
||||
*
|
||||
* @param {forge.pki.rsa.PrivateKey} privateKey
|
||||
* @param {forge_cert} certificate
|
||||
* @return {z.RsaSigner}
|
||||
*/
|
||||
z.createSigner = function(privateKey, certificate){
|
||||
if(privateKey && privateKey.n && privateKey.e){
|
||||
return new z.RsaSigner(privateKey, certificate);
|
||||
}
|
||||
throw new Error("Unsupported signing key type; only RSA keys are supported.");
|
||||
};
|
||||
|
||||
z.PdfSigner = class{
|
||||
/**
|
||||
* @param {SignOption} signopt
|
||||
|
|
@ -1053,7 +1076,7 @@ z.PdfSigner = class{
|
|||
// so it can later be swapped without touching this code. node-forge still
|
||||
// performs the RSA signing via the supplied key (shallow seam).
|
||||
/** @type {z.RsaSigner} */
|
||||
var signer = new z.RsaSigner(_this.privateKey, _this.cchain.getSignCert());
|
||||
var signer = z.createSigner(_this.privateKey, _this.cchain.getSignCert());
|
||||
|
||||
// Add the signer. sha256 is what Adobe.PPKLite adbe.pkcs7.detached expects.
|
||||
p7.addSigner({
|
||||
|
|
|
|||
53
test4node.js
53
test4node.js
|
|
@ -197,8 +197,15 @@ async function main1(angle){
|
|||
|
||||
// test urlFetch
|
||||
async function main2(){
|
||||
// Boot a throwaway server on an ephemeral port so this test is self
|
||||
// contained and cannot collide with an already running `npm run server`.
|
||||
/** @type {http.Server} */
|
||||
var srv = await startWebserver(0);
|
||||
/** @type {number} */
|
||||
var port = srv.address().port;
|
||||
try{
|
||||
/** @type {Uint8Array} */
|
||||
var u8arr = await Zga.urlFetch("http://localhost:8080", {
|
||||
var u8arr = await Zga.urlFetch("http://localhost:"+port, {
|
||||
"headers": {
|
||||
"testzb": "pineapple"
|
||||
}
|
||||
|
|
@ -210,10 +217,18 @@ async function main2(){
|
|||
/** @type {string} */
|
||||
var str = txtdec.decode(u8arr);
|
||||
console.log(str);
|
||||
}finally{
|
||||
srv.close();
|
||||
}
|
||||
}
|
||||
|
||||
function webserver(){
|
||||
require("http").createServer(function(req, res){
|
||||
/**
|
||||
* @param {number} port Port to listen on. 0 picks a free ephemeral port.
|
||||
* @return {Promise<http.Server>} The listening server.
|
||||
*/
|
||||
function startWebserver(port){
|
||||
/** @type {http.Server} */
|
||||
var srv = require("http").createServer(function(req, res){
|
||||
if(req.method == "GET"){
|
||||
if(req.headers["testzb"]){
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
|
|
@ -241,7 +256,14 @@ function webserver(){
|
|||
res.statusMessage = "CORS OK";
|
||||
res.end();
|
||||
}
|
||||
}).listen(8080, function(){console.log("Server http://localhost:8080")});
|
||||
});
|
||||
return new Promise(function(resolve, reject){
|
||||
srv.once("error", reject);
|
||||
srv.listen(port, function(){
|
||||
console.log("Server http://localhost:"+srv.address().port);
|
||||
resolve(srv);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main(){
|
||||
|
|
@ -254,10 +276,21 @@ async function main(){
|
|||
}
|
||||
}
|
||||
|
||||
if(process.argv[2] == "webserver"){
|
||||
webserver();
|
||||
}else if(process.argv[2] == "fetch"){
|
||||
main2();
|
||||
}else{
|
||||
main();
|
||||
/**
|
||||
* @param {Promise<*>} p
|
||||
*/
|
||||
function run(p){
|
||||
p.catch(function(err){
|
||||
console.error(err);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
|
||||
if(process.argv[2] == "webserver"){
|
||||
// Fixed port, because test.html expects the server on 8080.
|
||||
run(startWebserver(8080));
|
||||
}else if(process.argv[2] == "fetch"){
|
||||
run(main2());
|
||||
}else{
|
||||
run(main());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,3 +28,25 @@ test("RsaSigner reports SHA-256 as its digest algorithm OID", () => {
|
|||
|
||||
assert.strictEqual(signer.getDigestAlgorithmOid(), forge.pki.oids.sha256);
|
||||
});
|
||||
|
||||
test("RsaSigner reports sha256WithRSAEncryption as its signature algorithm OID", () => {
|
||||
const {privateKey, certificate} = makeKeyCert(3072);
|
||||
const signer = new Zga.RsaSigner(privateKey, certificate);
|
||||
|
||||
assert.strictEqual(signer.getSignatureAlgorithmOid(), forge.pki.oids.sha256WithRSAEncryption);
|
||||
});
|
||||
|
||||
test("createSigner returns an RsaSigner for an RSA key", () => {
|
||||
const {privateKey, certificate} = makeKeyCert(3072);
|
||||
|
||||
const signer = Zga.createSigner(privateKey, certificate);
|
||||
|
||||
assert.ok(signer instanceof Zga.RsaSigner);
|
||||
});
|
||||
|
||||
test("createSigner rejects an unsupported (non-RSA) key type", () => {
|
||||
assert.throws(
|
||||
() => Zga.createSigner({}, null),
|
||||
/only RSA keys are supported/,
|
||||
);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue