Skip to content

Commit

Permalink
fix(jwk): add validation for jwks
Browse files Browse the repository at this point in the history
  • Loading branch information
Atticus committed Mar 15, 2024
1 parent 997677d commit 5691c37
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ export default class Arweave {
attributes: Partial<CreateTransactionInterface>,
jwk?: JWKInterface | "use_wallet"
): Promise<Transaction> {

const isValidJWK = jwk && jwk !== "use_wallet" ? await this.validateJWK(jwk) : true;

if (!isValidJWK) {
throw new Error(`The JWK is not valid.`);
}

const transaction: Partial<CreateTransactionInterface> = {};

Object.assign(transaction, attributes);
Expand Down Expand Up @@ -216,4 +223,13 @@ export default class Arweave {
.post("/arql", query)
.then((response) => response.data || []);
}

public async validateJWK(jwk: JWKInterface): Promise<boolean> {
const transaction = await this.createTransaction({
data: "test",
});
await this.transactions.sign(transaction, jwk);

return await this.transactions.verify(transaction);
}
}
16 changes: 15 additions & 1 deletion src/common/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import CryptoInterface from "./lib/crypto/crypto-interface";
import { JWKInterface } from "./lib/wallet";
import * as ArweaveUtils from "./lib/utils";
import "arconnect";
import Transaction from "lib/transaction";
import Transactions from "transactions";
import Chunks from "chunks";
import Arweave from "./common";

export default class Wallets {
private api: Api;
Expand Down Expand Up @@ -66,13 +70,23 @@ export default class Wallets {
// @ts-ignore
return arweaveWallet.getActiveAddress();
} else {
// verify the JWK produces valid transactions
const isValid = await new Arweave(this.api.getConfig()).validateJWK(jwk);
if (!isValid) {
throw new Error("The JWK is not valid.");
}
return this.ownerToAddress(jwk.n);
}
}

public async ownerToAddress(owner: string): Promise<string> {
const buffer = await ArweaveUtils.b64UrlToBuffer(owner);
// RSA 4096 keys have an n length of 512 bytes. Validate JWK should handle this, so this is just a sanity check.
if (buffer.byteLength !== 512) {
throw new Error("Invalid JWK");
}
return ArweaveUtils.bufferTob64Url(
await this.crypto.hash(ArweaveUtils.b64UrlToBuffer(owner))
await this.crypto.hash(buffer)
);
}
}
11 changes: 11 additions & 0 deletions test/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,15 @@ describe("Wallets and keys", function () {
.to.be.a("string")
.and.equal("fOVzBRTBnyt4VrUUYadBH8yras_-jhgpmNgg-5b3vEw");
});

it("should throw on bad JWK", async function () {
const jwk = await arweave.wallets.generate();
jwk.n = jwk.n.slice(0, -1);
try {
await arweave.wallets.jwkToAddress(jwk);
} catch (e: any) {
expect(e).to.be.an("error");
expect(e.message).to.equal("The JWK is not valid.");
}
});
});

0 comments on commit 5691c37

Please sign in to comment.