diff --git a/src/pass.js b/src/pass.js index b71b09e..6d8bd6e 100644 --- a/src/pass.js +++ b/src/pass.js @@ -465,59 +465,60 @@ class Pass { * Generates the PKCS #7 cryptografic signature for the manifest file. * * @method _sign - * @params {String|Object} manifest - Manifest content. + * @params {Object} manifest - Manifest content. * @returns {Buffer} */ _sign(manifest) { let signature = forge.pkcs7.createSignedData(); - if (typeof manifest === "object") { - 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.content = forge.util.createBuffer(JSON.stringify(manifest), "utf8"); signature.addCertificate(this.Certificates.wwdr); 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({ key: this.Certificates.signerKey, certificate: this.Certificates.signerCert, - digestAlgorithm: forge.pki.oids.sha1, authenticatedAttributes: [{ type: forge.pki.oids.contentType, value: forge.pki.oids.data }, { type: forge.pki.oids.messageDigest, }, { - // the value is autogenerated type: forge.pki.oids.signingTime, }] }); - signature.sign(); - - /* - * 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. - * + /** + * We are creating a detached signature because we don't need the signed content. + * Detached signature is a property of PKCS#7 cryptography standard. */ - signature.contentInfo.value.pop(); - // Converting the JSON Structure into a DER (which is a subset of BER), ASN.1 valid structure - // Returning the buffer of the signature + signature.sign({ detached: true }); + + /** + * 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"); }