Created
July 1, 2023 16:25
-
-
Save cmjunior/91e4fcfac27328a1da77849b93b515b3 to your computer and use it in GitHub Desktop.
Code where I convert the Fortify certificate to the correct format.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var el = document.createElement('peculiar-fortify-certificates'); | |
el.debug = true; | |
el.filters = { | |
onlyWithPrivateKey: true | |
}; | |
el.addEventListener('cancel', function() { | |
alert('"cancel" callback'); | |
}); | |
el.addEventListener('continue', function(event) { | |
continueHandler(event, modifiedPdfBuffer); | |
}); | |
document.getElementsByTagName('section')[0].prepend(el); | |
}; | |
async function continueHandler(event, pdfBuffer) { | |
// Here I get the fortify certificate | |
var provider = await event.detail.server.getCrypto(event.detail.providerId); | |
provider.sign = provider.subtle.sign.bind(provider.subtle); | |
pkijs.setEngine( | |
"newEngine", | |
provider, | |
new pkijs.CryptoEngine({ | |
name: "", | |
crypto: provider, | |
subtle: provider.subtle, | |
}) | |
); | |
var cert = await provider.certStorage.getItem(event.detail.certificateId); | |
var privateKey = await provider.keyStorage.getItem(event.detail.privateKeyId); | |
var certRawData = await provider.certStorage.exportCert('raw', cert); | |
var pkiCert = new pkijs.Certificate({ | |
schema: asn1js.fromBER(certRawData).result, | |
}); | |
const hashBuffer = await provider.subtle.digest('SHA-256', pdf); | |
const signedAttr = []; | |
signedAttr.push(new pkijs.Attribute({ | |
type: "1.2.840.113549.1.9.3",// contentType (PKCS #9) | |
values: [ | |
new asn1js.ObjectIdentifier({ value: "1.2.840.113549.1.7.1" })// data (PKCS #7) | |
] | |
})); // contentType | |
signedAttr.push(new pkijs.Attribute({ | |
type: "1.2.840.113549.1.9.5",// signingTime (PKCS #9) | |
values: [ | |
new asn1js.UTCTime({ valueDate: new Date() }) | |
] | |
})); // signingTime | |
signedAttr.push(new pkijs.Attribute({ | |
type: "1.2.840.113549.1.9.4",// messageDigest (PKCS #9) | |
values: [ | |
new asn1js.OctetString({ valueHex: hashBuffer }) | |
] | |
})); // messageDigest | |
var signedData = new pkijs.SignedData({ | |
version: 1, | |
digestAlgorithms: [ | |
new pkijs.AlgorithmIdentifier({ | |
algorithmId: "1.3.14.3.2.26", | |
algorithmParams: new asn1js.Null() | |
}), | |
], | |
encapContentInfo: new pkijs.EncapsulatedContentInfo({ | |
eContentType: "1.2.840.113549.1.7.1", // "data" content type | |
}), | |
signerInfos: [ | |
new pkijs.SignerInfo({ | |
version: 1, | |
sid: new pkijs.IssuerAndSerialNumber({ | |
issuer: pkiCert.issuer, | |
serialNumber: pkiCert.serialNumber, | |
}), | |
digestAlgorithm: new pkijs.AlgorithmIdentifier({algorithmId: "1.3.14.3.2.26", algorithmParams: new asn1js.Null()}), | |
signatureAlgorithm: new pkijs.AlgorithmIdentifier({algorithmId: "1.2.840.113549.1.1.5", algorithmParams: new asn1js.Null()}), | |
signedAttrs: new pkijs.SignedAndUnsignedAttributes({ | |
type: "0", | |
attributes: signedAttr, | |
}), | |
}), | |
], | |
certificates: [pkiCert], | |
}); | |
await signedData.sign(privateKey, 0, 'SHA-256', pdf); | |
const cms = new pkijs.ContentInfo({ | |
contentType: "1.2.840.113549.1.7.2", | |
content: signedData.toSchema(true), | |
}); | |
const result = cms.toSchema().toBER(false); | |
let stringSignature = Array.prototype.map.call(new Uint8Array(result), x => (`00${x.toString(16)}`).slice(-2)).join(''); | |
let lenSignature = result.byteLength; | |
if ( (placeholderLength / 2) - lenSignature > 0 ) { | |
stringSignature += Buffer | |
.from(String.fromCharCode(0).repeat((placeholderLength / 2) - lenSignature)) | |
.toString('hex'); | |
}; | |
let output = Buffer.concat([ | |
pdf.slice(0, byteRange[1]), | |
Buffer.from(`<${stringSignature}>`), | |
pdf.slice(byteRange[1]) | |
]); | |
const a = document.createElement('a'); | |
const blob = new Blob([output], { type: 'application/pdf' }); | |
a.href = URL.createObjectURL(blob); | |
a.download = 'pdf-signed.pdf'; | |
a.click(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@cmjunior
Thanks for the code, I still getting problem in getting the /ByteRange of a pdf, could you please provide more details about the process of reading the pdf as buffer