Skip to content

Commit

Permalink
fix web driver usage, browserify-buffer, use shim inside node runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
samantehrani committed Jan 18, 2025
1 parent 7220b7d commit 9484bba
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 62 deletions.
24 changes: 21 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"clean:bundle": "rimraf bundles",
"clean": "npm run clean:dist && npm run clean:package && npm run clean:bundle",
"prepublishOnly": "npm run clean && npm run build",
"test": "mocha --file test/shims.ts test/*.ts && echo \"NOW RUN => 'npm run test:web' <= \" ",
"test": "mocha --file src/node/shims.ts test/*.ts && echo \"NOW RUN => 'npm run test:web' <= \" ",
"test:web": "npm run bundle:web && webpack --config-name web-tests && opener test/web/web.html",
"prettier:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
"prettier:write": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
Expand Down
2 changes: 1 addition & 1 deletion src/common/lib/crypto/node-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class NodeCryptoDriver implements CryptoInterface {
.then(
pk => pk.verify({payload: data, signature, isDigest: false }),
error => {
console.log('Failed to recover EC Secp256k1 public key from signature and data!');
console.log(`Failed to recover EC Secp256k1 public key from signature and data! ${error}`);
return false;
}
)
Expand Down
80 changes: 24 additions & 56 deletions src/common/lib/crypto/webcrypto-driver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { JWKInterface, JWKPublicInterface } from "../wallet";
import CryptoInterface, { SignatureOptions } from "./crypto-interface";
import * as ArweaveUtils from "../utils";
import { PrivateKey, RSAPrivateKey, SECP256k1PublicKey, fromIdentifier } from "./keys";
import { b64UrlToBuffer } from "../../lib/utils";

export default class WebCryptoDriver implements CryptoInterface {
public readonly keyLength = 4096;
Expand Down Expand Up @@ -46,10 +48,16 @@ export default class WebCryptoDriver implements CryptoInterface {
}

public async sign(
jwk: JWKInterface,
jwk: JWKInterface | PrivateKey,
data: Uint8Array,
{ saltLength }: SignatureOptions = {}
): Promise<Uint8Array> {
if (jwk instanceof RSAPrivateKey) {
return jwk.sign({payload: data}, saltLength);
} else if (jwk instanceof PrivateKey) {
return jwk.sign({payload: data});
}

let signature = await this.driver.sign(
{
name: "RSA-PSS",
Expand All @@ -72,66 +80,26 @@ export default class WebCryptoDriver implements CryptoInterface {
}

public async verify(
publicModulus: string,
owner: string,
data: Uint8Array,
signature: Uint8Array
): Promise<boolean> {
const publicKey = {
kty: "RSA",
e: "AQAB",
n: publicModulus,
};

const key = await this.jwkToPublicCryptoKey(publicKey);
const digest = await this.driver.digest("SHA-256", data);

const salt0 = await this.driver.verify(
{
name: "RSA-PSS",
saltLength: 0,
},
key,
signature,
data
);

const salt32 = await this.driver.verify(
{
name: "RSA-PSS",
saltLength: 32,
},
key,
signature,
data
);

// saltN's salt-length is derived from a formula described here
// https://developer.mozilla.org/en-US/docs/Web/API/RsaPssParams
const saltLengthN =
Math.ceil(
((key.algorithm as RsaHashedKeyGenParams).modulusLength - 1) / 8
) -
digest.byteLength -
2;

const saltN = await this.driver.verify(
{
name: "RSA-PSS",
saltLength: saltLengthN,
},
key,
signature,
data
);

const result = salt0 || salt32 || saltN;

if (owner === "") {
return SECP256k1PublicKey.recover({payload: data, signature, isDigest: false})
.then(
pk => pk.verify({payload: data, signature, isDigest: false }),
error => {
console.log(`Failed to recover EC Secp256k1 public key from signature and data! ${error}`);
return false;
}
)
}
const identifier = b64UrlToBuffer(owner);
const pk = await fromIdentifier({identifier});
const result = await pk.verify({payload: data, signature});
if (!result) {
const details = {
algorithm: key.algorithm.name,
modulusLength: (key.algorithm as RsaHashedKeyAlgorithm).modulusLength,
keyUsages: key.usages,
saltLengthsAttempted: `0, 32, ${saltLengthN}`,
asymmetricKeyType: pk.type
};
console.warn(
"Transaction Verification Failed! \n",
Expand Down
1 change: 1 addition & 0 deletions src/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Arweave from "./common";
import { ApiConfig } from "./lib/api";
import "./shims";

Arweave.init = function (apiConfig: ApiConfig = {}): Arweave {
return new Arweave(apiConfig);
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion test/web/web.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
</script>
</body>

</html>
</html>
2 changes: 2 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,14 @@ config.webprod = {
process: require.resolve("process/browser"),
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
buffer: require.resolve('buffer/')
},
extensions: [".ts", ".js"],
},
plugins: [
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ['buffer', 'Buffer']
}),
],
optimization: {
Expand Down

0 comments on commit 9484bba

Please sign in to comment.