forked from bluesky-social/atproto
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* scaffold package * kms working! * interface * normlize for low s * no der encoding in crypto * comments * rm kms tests * pr feedback
- Loading branch information
Showing
8 changed files
with
875 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# AWS KMS | ||
|
||
A DidableKeypair-compatible wrapper for AWS KMS. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "@atproto/aws-kms", | ||
"version": "0.0.1", | ||
"main": "src/index.ts", | ||
"license": "MIT", | ||
"scripts": { | ||
"start": "ts-node src/run.ts", | ||
"prettier": "prettier --check src/", | ||
"prettier:fix": "prettier --write src/", | ||
"lint": "eslint . --ext .ts,.tsx", | ||
"lint:fix": "yarn lint --fix", | ||
"verify": "run-p prettier lint", | ||
"verify:fix": "yarn prettier:fix && yarn lint:fix", | ||
"build": "esbuild src/index.ts --define:process.env.NODE_ENV=\\\"production\\\" --bundle --platform=node --sourcemap --outfile=dist/index.js", | ||
"postbuild": "tsc --build tsconfig.build.json" | ||
}, | ||
"dependencies": { | ||
"@atproto/crypto": "*", | ||
"@aws-sdk/client-kms": "^3.196.0", | ||
"@noble/secp256k1": "^1.7.0", | ||
"key-encoder": "^2.0.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import * as aws from '@aws-sdk/client-kms' | ||
import * as secp from '@noble/secp256k1' | ||
import * as crypto from '@atproto/crypto' | ||
import KeyEncoder from 'key-encoder' | ||
|
||
const keyEncoder = new KeyEncoder('secp256k1') | ||
|
||
export type KmsConfig = { keyId: string } & Omit< | ||
aws.KMSClientConfig, | ||
'apiVersion' | ||
> | ||
|
||
export class KmsKeypair implements crypto.DidableKey { | ||
jwtAlg = crypto.SECP256K1_JWT_ALG | ||
|
||
constructor( | ||
private client: aws.KMS, | ||
private keyId: string, | ||
private publicKey: Uint8Array, | ||
) {} | ||
|
||
static async load(cfg: KmsConfig) { | ||
const { keyId, ...rest } = cfg | ||
const client = new aws.KMS({ | ||
...rest, | ||
apiVersion: '2014-11-01', | ||
}) | ||
const res = await client.getPublicKey({ KeyId: keyId }) | ||
if (!res.PublicKey) { | ||
throw new Error('Could not find public key') | ||
} | ||
// public key comes back DER-encoded, so we translate it to raw 65 byte encoding | ||
const rawPublicKeyHex = keyEncoder.encodePublic( | ||
Buffer.from(res.PublicKey), | ||
'der', | ||
'raw', | ||
) | ||
const publicKey = secp.utils.hexToBytes(rawPublicKeyHex) | ||
return new KmsKeypair(client, keyId, publicKey) | ||
} | ||
|
||
did(): string { | ||
return crypto.formatDidKey(this.jwtAlg, this.publicKey) | ||
} | ||
|
||
async sign(msg: Uint8Array): Promise<Uint8Array> { | ||
const res = await this.client.sign({ | ||
KeyId: this.keyId, | ||
Message: msg, | ||
SigningAlgorithm: 'ECDSA_SHA_256', | ||
}) | ||
if (!res.Signature) { | ||
throw new Error('Could not get signature') | ||
} | ||
// signature comes back DER encoded & not-normalized | ||
// we translate to raw 64 byte encoding | ||
// we also normalize s as no more than 1/2 prime order to pass strict verification | ||
// (prevents duplicating a signature) | ||
// more: https://github.com/bitcoin-core/secp256k1/blob/a1102b12196ea27f44d6201de4d25926a2ae9640/include/secp256k1.h#L530-L534 | ||
const sig = secp.Signature.fromDER(res.Signature) | ||
const normalized = sig.normalizeS() | ||
return normalized.toCompactRawBytes() | ||
} | ||
} | ||
|
||
export default KmsKeypair |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"exclude": ["**/*.spec.ts", "**/*.test.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "./dist", // Your outDir, | ||
"emitDeclarationOnly": true | ||
}, | ||
"include": ["./src","__tests__/**/**.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.