UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

62 lines 4.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const sdk_1 = require("@bsv/sdk"); describe('CertificateLifeCycle tests', () => { jest.setTimeout(99999999); test('2a complete flow MasterCertificate and VerifiableCertificate', async () => { // Issuer beging with an un-encrypted (decrypted) raw certificate template: // The public keys of both the certifier (the authority issuing the certificate), // and the subject (who the certificate pertains to) are included in the certificate. const { cert: wcert, certifier, subject } = makeSampleCert('1'.repeat(64), '2'.repeat(64), '3'.repeat(64)); const cert = new sdk_1.Certificate(wcert.type, wcert.serialNumber, wcert.subject, wcert.certifier, wcert.revocationOutpoint, wcert.fields); // Next the certifier must encrypt the field values for privacy and sign the certificate // such that the values it contains can be attributed to the certifier through its public key. // Encryption is done with random symmetric keys and the keys are then encrypted by the certifier // such that each key can also be decrypted by the subject: const certifierWallet = new sdk_1.ProtoWallet(certifier); // encrypt the fields as the certifier for the subject const r1 = await sdk_1.MasterCertificate.createCertificateFields(certifierWallet, subject.toPublicKey().toString(), cert.fields); // sign the certificate with encrypted fields as the certifier const signedCert = new sdk_1.Certificate(wcert.type, wcert.serialNumber, wcert.subject, wcert.certifier, wcert.revocationOutpoint, r1.certificateFields); await signedCert.sign(certifierWallet); // The subject imports their copy of the new certificate: const subjectWallet = new sdk_1.ProtoWallet(subject); // The subject's imported certificate should verify expect(await signedCert.verify()).toBe(true); // Confirm subject can decrypt the certifier's copy of the cert: const r2 = await sdk_1.MasterCertificate.decryptFields(subjectWallet, r1.masterKeyring, signedCert.fields, signedCert.certifier); // Prepare to send certificate to third party veifier of the 'name' and 'email' fields. // The verifier must be able to confirm the signature on the original certificate's encrypted values. // And then use a keyRing that their public key will work to reveal decrypted values for 'name' and 'email' only. const verifier = sdk_1.PrivateKey.fromRandom(); // subject makes a keyring for the verifier const r3 = await sdk_1.MasterCertificate.createKeyringForVerifier(subjectWallet, certifier.toPublicKey().toString(), verifier.toPublicKey().toString(), signedCert.fields, ['name', 'email'], r1.masterKeyring, signedCert.serialNumber); // The verifier uses their own wallet to import the certificate, verify it, and decrypt their designated fields. const verifierWallet = new sdk_1.ProtoWallet(verifier); const veriCert = new sdk_1.VerifiableCertificate(signedCert.type, signedCert.serialNumber, signedCert.subject, signedCert.certifier, signedCert.revocationOutpoint, signedCert.fields, r3, signedCert.signature); const r4 = await veriCert.decryptFields(verifierWallet); expect(r4['name']).toBe('Alice'); expect(r4['email']).toBe('alice@example.com'); expect(r4['organization']).not.toBe('Example Corp'); }); }); function makeSampleCert(subjectRootKeyHex, certifierKeyHex, verifierKeyHex) { const subject = subjectRootKeyHex ? sdk_1.PrivateKey.fromString(subjectRootKeyHex) : sdk_1.PrivateKey.fromRandom(); const certifier = certifierKeyHex ? sdk_1.PrivateKey.fromString(certifierKeyHex) : sdk_1.PrivateKey.fromRandom(); const verifier = verifierKeyHex ? sdk_1.PrivateKey.fromString(verifierKeyHex) : sdk_1.PrivateKey.fromRandom(); const cert = { type: sdk_1.Utils.toBase64(new Array(32).fill(1)), serialNumber: sdk_1.Utils.toBase64(new Array(32).fill(2)), revocationOutpoint: 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef.1', subject: subject.toPublicKey().toString(), certifier: certifier.toPublicKey().toString(), fields: { name: 'Alice', email: 'alice@example.com', organization: 'Example Corp' }, signature: '' }; return { cert, subject, certifier }; } //# sourceMappingURL=CertificateLifeCycle.test.js.map