Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 3x 3x 3x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import { getPublicKey } from 'micro-stacks/crypto';
import { publicKeyToBase58Address, verifyECDSA, decryptContent } from 'micro-stacks/crypto';
import { SignatureVerificationError } from '../gaia/errors';
import { getGaiaAddress } from './getters';
import type { GaiaHubConfig } from '../gaia/types';
import type { SignedCipherObject } from 'micro-stacks/crypto';
/**
* Handle signature verification and decryption for contents which are
* expected to be signed and encrypted. This works for single and
* multiplayer reads. In the case of multiplayer reads, it uses the
* gaia address for verification of the claimed public key.
*
* @private
*/
export async function handleSignedEncryptedContents(options: {
path: string;
storedContents: string;
app: string;
privateKey?: string;
username?: string;
zoneFileLookupURL?: string;
gaiaHubConfig: GaiaHubConfig;
}): Promise<string | Uint8Array> {
const { path, storedContents, app, privateKey, username, zoneFileLookupURL, gaiaHubConfig } =
options;
const appPrivateKey = privateKey;
const appPublicKey = appPrivateKey ? getPublicKey(appPrivateKey, true) : null;
let address: string | null = null;
if (username || gaiaHubConfig) {
address = await getGaiaAddress({
app,
username,
zoneFileLookupURL,
gaiaHubConfig,
});
} else IEif (appPublicKey) {
address = publicKeyToBase58Address(appPublicKey);
}
Iif (!address) {
throw new SignatureVerificationError(
'Failed to get gaia address for verification of: ' + `${path}`
);
}
let signedCipherObject: SignedCipherObject;
try {
signedCipherObject = JSON.parse(storedContents);
} catch (err) {
if (err instanceof SyntaxError) {
throw new Error(
'Failed to parse encrypted, signed content JSON. The content may not ' +
'be encrypted. If using getFile, try passing' +
' { verify: false, decrypt: false }.'
);
} else {
throw err;
}
}
const signature = signedCipherObject.signature;
const signerPublicKey = signedCipherObject.publicKey;
const cipherText = signedCipherObject.cipherText;
const signerAddress = publicKeyToBase58Address(signerPublicKey);
Iif (!signerPublicKey || !cipherText || !signature) {
throw new SignatureVerificationError(
'Failed to get signature verification data from file:' + ` ${path}`
);
} else Iif (signerAddress !== address) {
throw new SignatureVerificationError(
`Signer pubkey address (${signerAddress}) doesn't` + ` match gaia address (${address})`
);
}
const verified = verifyECDSA({
signature,
contents: cipherText,
publicKey: signerPublicKey,
});
Iif (!verified)
throw new SignatureVerificationError(
'Contents do not match ECDSA signature in file:' + ` ${path}`
);
Iif (!privateKey) throw Error('Private key needs to be passed in order to decrypt content');
const decryptOpt = { privateKey };
return decryptContent(cipherText, decryptOpt);
}
|