celo-org / celo-org/developer-tooling

changeKeystorePassphrase silently drops blspublickey from validator keystores

Open Beginner friendly
#793 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
44
Forks
36
PR merge metrics
No merged PRs in 30d

Description

## Summary

`KeystoreBase.changeKeystorePassphrase` destroys any non-standard top-level field in a V3 keystore. Celo validator keystores generated by geth carry a `blspublickey` field, so changing such a keystore's passphrase silently loses it.

## Cause

`packages/sdk/keystores/src/keystore-base.ts` re-encrypts by decrypting the private key and building a **fresh** V3 object. That object only ever contains `version`, `id`, `address` and `crypto`, so everything else in the original file is dropped:

```
in : {address, blspublickey, crypto, id, version}
out: {address, crypto, id, version}
^^^^^^^^^^^^ silently lost
```

There is no error and no warning — the write succeeds and the field is simply gone.

## Reproduce

`GETH_GEN_KEYSTORE1` in `packages/sdk/keystores/src/test-constants.ts` is a real geth-generated fixture containing a `blspublickey`. Persist it, call `changeKeystorePassphrase`, then re-read the raw entry: the field is absent.

## Not a regression

This predates the removal of `ethereumjs-wallet` (#792). That library's `toV3` had exactly the same behaviour, so the migration neither introduced nor worsened it. It was left alone there deliberately to keep that PR strictly behaviour-neutral and easy to review.

## Suggested fix

Preserve unknown top-level fields across re-encryption — spread the parsed original and overwrite only `crypto` (and `id`), rather than constructing the object from scratch. Add a regression test using the `GETH_GEN_KEYSTORE1` fixture asserting `blspublickey` survives a passphrase change.

Worth deciding at the same time whether `importPrivateKey` should be able to *write* such fields, or whether preservation on re-encryption is the whole scope.

## Impact

Limited. `@celo/keystores` has no consumers inside this monorepo — celocli never reads or writes keystore files — so this only affects external npm consumers of the package who manage geth-generated validator keystores.

Contributor guide

Open the contributing guide

Research direction

Start in packages/sdk/keystores/src/keystore-base.ts at changeKeystorePassphrase and inspect how the fresh V3 object is built. Use GETH_GEN_KEYSTORE1 from packages/sdk/keystores/src/test-constants.ts to reproduce the passphrase change, then add a regression test showing that blspublickey remains present after re-encryption.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.