Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented manifest signatures #27

Merged
merged 6 commits into from
Feb 9, 2024
Merged

Implemented manifest signatures #27

merged 6 commits into from
Feb 9, 2024

Conversation

corrideat
Copy link
Member

@corrideat corrideat commented Feb 8, 2024

Closes issue #26

src/keygen.ts Outdated
Comment on lines 5 to 20
export const keygen = async (args: string[]) => {
await revokeNet()
const parsedArgs = flags.parse(args)
const key = cryptoKeygen(EDWARDS25519SHA512BATCH)
const textEncoder = new TextEncoder()
const result = textEncoder.encode(JSON.stringify({
version: '1.0.0',
pubkey: serializeKey(key, false),
privkey: serializeKey(key, true)
}))

if (parsedArgs['out']) {
await Deno.writeFile(parsedArgs['out'], result)
} else {
await Deno.stdout.write(result)
}
Copy link
Member

@taoeffect taoeffect Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request:

  • output 2 files, one for the public key (for verifying with chel latestState), and one for the private key for signing with chel manifest (like SSH)
  • remove the STDOUT. you can have a default filename based on the key type (make sure to output to STDOUT where this file is saved, and check to see if it already exists, in which case, just add a suffix like id_edssa.1.pub and id_edssa.1.priv) or something to that effect

Copy link
Member

@taoeffect taoeffect left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @corrideat!!

I left some feedback and also realized we need two tests for this:

  1. A test to verify that contracts are signed correctly using a new chel verifyContract command that takes a pubkey file and a manifest (can update one of the manifest files in test/data/)
  2. A test to verify that a modified contract (after it's been signed) fails a signature check (can use the test/data/mailbox.* files for this one)

* New verifySignature command
* Tests for validating signatures
* keygen command now outputs to two files
* manifest command now uses public key files instead of strings
src/keygen.ts Outdated
Comment on lines 24 to 28
await Deno.writeTextFile(outFile, result)
console.log(colors.green('wrote:'), outFile, colors.green('(secret)'))

await Deno.writeTextFile(pubOutFile, pubResult)
console.log(colors.green('wrote:'), pubOutFile, colors.green('(public)'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make the color for "(secret)" and "(public)" blue or grey?

Comment on lines 39 to 49
if (!internal) console.log(colors.green('signature ok'), '(verification not yet complete)')

const body = JSON.parse(manifest.body)
if (!Array.isArray(body.signingKeys)) throw new Error('Missing signingKeys in manifest')
if (body.signingKeys.every((k: string) => {
return keyId(k) !== id
})) {
throw new Error('The signing key is not listed in signingKeys')
}

if (!internal) console.log(colors.green('ok'), 'all checks passed')
Copy link
Member

@taoeffect taoeffect Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • If the keyfile isn't specified in the arguments, see if the signature passes one of the keys in the manifest
  • If the keyfile is specified, check if the signature passes that key only, and IF that key is not also specified in the manifest, then output a yellow bold console.warn message saying that the check passed the keyfile but that key wasn't found on in the manifest
    • alternatively, you can output a red console.error saying the signature is OK but the key isn't in the manifest
  • For errors that are not unexpected (as many of the ones are here), use the exit() function from utils.ts

In all cases only output one message. If the output is an error then call Deno.exit(1)

src/manifest.ts Outdated
key: "<which of the 'authors' keys was used to sign 'body'>",
signature: "<signature>"
keyId: keyId(signingKey),
value: sign(signingKey, serializedBody + head.manifestVersion)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you sign full head?

}
if (!manifest.signature.value) {
exit('Invalid manifest: missing signature value', internal)
}
Copy link
Member

@taoeffect taoeffect Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to load both contract files (slim — if it exists — and bundle) and verify the hash matches the hash that's in the manifest.

Copy link
Member

@taoeffect taoeffect left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect! 🎉🎉

@taoeffect taoeffect merged commit 258b232 into master Feb 9, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants