Improved _sign method to accept only object as parameter and changed comments inside

This commit is contained in:
alexandercerutti
2018-10-16 00:59:49 +02:00
parent 68cb8af7c8
commit 9ba64fc349

View File

@@ -465,59 +465,60 @@ class Pass {
* Generates the PKCS #7 cryptografic signature for the manifest file. * Generates the PKCS #7 cryptografic signature for the manifest file.
* *
* @method _sign * @method _sign
* @params {String|Object} manifest - Manifest content. * @params {Object} manifest - Manifest content.
* @returns {Buffer} * @returns {Buffer}
*/ */
_sign(manifest) { _sign(manifest) {
let signature = forge.pkcs7.createSignedData(); let signature = forge.pkcs7.createSignedData();
if (typeof manifest === "object") { signature.content = forge.util.createBuffer(JSON.stringify(manifest), "utf8");
signature.content = forge.util.createBuffer(JSON.stringify(manifest), "utf8");
} else if (typeof manifest === "string") {
signature.content = manifest;
} else {
throw new Error(errors.MANIFEST_TYPE.replace("%s", typeof manifest));
}
signature.addCertificate(this.Certificates.wwdr); signature.addCertificate(this.Certificates.wwdr);
signature.addCertificate(this.Certificates.signerCert); signature.addCertificate(this.Certificates.signerCert);
/**
* authenticatedAttributes belong to PKCS#9 standard.
* It requires at least 2 values:
* • content-type (which is a PKCS#7 oid) and
* • message-digest oid.
*
* Wallet requires a signingTime.
*/
signature.addSigner({ signature.addSigner({
key: this.Certificates.signerKey, key: this.Certificates.signerKey,
certificate: this.Certificates.signerCert, certificate: this.Certificates.signerCert,
digestAlgorithm: forge.pki.oids.sha1,
authenticatedAttributes: [{ authenticatedAttributes: [{
type: forge.pki.oids.contentType, type: forge.pki.oids.contentType,
value: forge.pki.oids.data value: forge.pki.oids.data
}, { }, {
type: forge.pki.oids.messageDigest, type: forge.pki.oids.messageDigest,
}, { }, {
// the value is autogenerated
type: forge.pki.oids.signingTime, type: forge.pki.oids.signingTime,
}] }]
}); });
signature.sign(); /**
* We are creating a detached signature because we don't need the signed content.
/* * Detached signature is a property of PKCS#7 cryptography standard.
* Signing creates in contentInfo a JSON object nested BER/TLV (X.690 standard) structure.
* Each object represents a component of ASN.1 (Abstract Syntax Notation)
* For a more complete reference, refer to: https://en.wikipedia.org/wiki/X.690#BER_encoding
*
* signature.contentInfo.type => SEQUENCE OF (16)
* signature.contentInfo.value[0].type => OBJECT IDENTIFIER (6)
* signature.contantInfo.value[1].type => END OF CONTENT (EOC - 0)
*
* EOC are only present only in constructed indefinite-length methods
* Since `signature.contentInfo.value[1].value` contains an object whose value contains the content we passed,
* we have to pop the whole object away to avoid signature content invalidation.
*
*/ */
signature.contentInfo.value.pop();
// Converting the JSON Structure into a DER (which is a subset of BER), ASN.1 valid structure signature.sign({ detached: true });
// Returning the buffer of the signature
/**
* Signature here is an ASN.1 valid structure (DER-compliant).
* Generating a non-detached signature, would have pushed inside signature.contentInfo
* (which has type 16, or "SEQUENCE", and is an array) a Context-Specific element, with the signed
* signed content as value.
*
* In fact the previous approach was to generating a detached signature and the pull away the generated
* content.
*
* That's what happens when you copy a fu****g line without understanding what it does.
* Well, nevermind, it was funny to study BER, DER, CER, ASN.1 and PKCS#7. You can learn a lot
* of beautiful things. ¯\_(ツ)_/¯
*/
return Buffer.from(forge.asn1.toDer(signature.toAsn1()).getBytes(), "binary"); return Buffer.from(forge.asn1.toDer(signature.toAsn1()).getBytes(), "binary");
} }