PeculiarVentures / webcrypto-core

A input validation layer for WebCrypto polyfills.
MIT License
28 stars 13 forks source link

SubtleCrypto fails to recognise some `CryptoKey`s #55

Open gnarea opened 2 years ago

gnarea commented 2 years ago

The following is failing for me:

https://github.com/PeculiarVentures/webcrypto-core/blob/22c0f0baeda86a22e9708eb831db015a3fceb827/src/subtle.ts#L244-L248

Error: Error during exporting public key: Key is not of type 'CryptoKey'

    at PublicKeyInfo.importKey (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/node_modules/pkijs/build/index.js:3935:19)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at Function.issue (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/src/lib/crypto_wrappers/x509/Certificate.ts:108:5)
    at PublicGatewayManager.generate (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.ts:40:32)
    at Object.<anonymous> (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.spec.ts:67:28)

But it shouldn't be (according to my debugger):

cryptokey-err


I think the issue is analogous to https://github.com/PeculiarVentures/asn1-schema/issues/71. Here some info on the dependency tree:

$ npm list webcrypto-core
@relaycorp/relaynet-internet-gateway@1.0.0 /home/gus/repos/relaynet-internet-gateway
└─┬ @relaycorp/relaynet-core@1.80.2
  ├─┬ @peculiar/webcrypto@1.4.0
  │ └── webcrypto-core@1.7.5  deduped
  └── webcrypto-core@1.7.5 

$ npm list @peculiar/webcrypto
@relaycorp/relaynet-internet-gateway@1.0.0 /home/gus/repos/relaynet-internet-gateway
└─┬ @relaycorp/relaynet-core@1.80.2
  └── @peculiar/webcrypto@1.4.0

The CryptoKeyPair is generated inside @relaycorp/relaynet-core, using @peculiar/webcrypto, and the resulting key pair is then passed to the root package (relaynet-internet-gateway). Then the root package tries to use that key pair to issue a self-signed certificate using @relaycorp/relaynet-core (which in turn uses PKI.js), but it fails with the error above.

Note that I tried skipping the key instanceof CryptoKey check above, but hit a new error from @peculiar/webcrypto:

Error: Error during exporting public key: Cannot get CryptoKey from secure storage

    at PublicKeyInfo.importKey (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/node_modules/pkijs/build/index.js:3935:19)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at Function.issue (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/src/lib/crypto_wrappers/x509/Certificate.ts:108:5)
    at PublicGatewayManager.generate (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.ts:40:32)
    at Object.<anonymous> (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.spec.ts:67:28)
microshine commented 2 years ago

@peculiar/webcrypto use WeakMap to protect private key data. Here is storage implementation. As you can see, getCryptoKey throws Cannot get CryptoKey from secure storage exception.

Sometimes I've got the similar problem with WebCrypto. To fix it, I use resolutions option in package.json for yarn. Try to use overrides option for npm.

One more thought, maybe it's possible to fix the problem by moving @peculiar/webcrypto into peerDependency

microshine commented 2 years ago

/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/node_modules/pkijs/build/index.js:3935:19

It's interesting. You've got node_modules folder for @relaycorp/relaynet-core.

I bet the problem is in module duplicates

gnarea commented 2 years ago

Hi @microshine! Thanks for looking into this.

What should I try setting overrides to in package.json? We're already using webcrypto-core@1.7.5 across the board.

I tried adding @peculiar/webcrypto to peerDependencies in @relaycorp/relaynet-core. That makes key instanceof CryptoKey work, but then I hit the WeakMap-related issue:

Error: Error during exporting public key: Key is not of type 'CryptoKey'

    at PublicKeyInfo.importKey (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/node_modules/pkijs/build/index.js:3935:19)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Function.issue (/home/gus/repos/relaynet-internet-gateway/node_modules/@relaycorp/relaynet-core/src/lib/crypto_wrappers/x509/Certificate.ts:108:5)
    at PublicGatewayManager.generate (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.ts:40:32)
    at Object.<anonymous> (/home/gus/repos/relaynet-internet-gateway/src/node/PublicGatewayManager.spec.ts:67:28)

I don't know why I'm hitting this issue, having seen the @peculiar/webcrypto implementation. It should work 🤔 I'll take another look at this tomorrow with fresh eyes.

microshine commented 2 years ago

Please look at your package-lock.json file

it uses 2 copies of @peculia/webcrypto

https://github.com/relaycorp/relaynet-internet-gateway/blob/master/package-lock.json#L1747 https://github.com/relaycorp/relaynet-internet-gateway/blob/master/package-lock.json#L11339

microshine commented 2 years ago

Looks I was wrong. It's the same dependency for @relaycorp/relaynet-core package.

One more thought. Try to remove package-lock.json and node_modules folder and reinstall dependencies.

The structure of node_modules has been changed

image
gnarea commented 2 years ago

Thanks @microshine!

I've now added @peculiar/webcrypto and webcrypto-core (for good measure) to @relaycorp/relaynet-core, and re-created package-lock.json in relaynet-internet-gateway. However, this last change has taken me back to the original problem of Key is not of type 'CryptoKey'.

Note that npm list still shows a single instance of @peculiar/webcrypto and multiple of webcrypto core (though they're all deduped):

$ npm list @peculiar/webcrypto
@relaycorp/relaynet-internet-gateway@1.0.0 /home/gus/repos/relaynet-internet-gateway
└─┬ @relaycorp/relaynet-core@1.81.2
  └── @peculiar/webcrypto@1.4.0

$ npm list webcrypto-core
@relaycorp/relaynet-internet-gateway@1.0.0 /home/gus/repos/relaynet-internet-gateway
├─┬ @relaycorp/awala-keystore-cloud@2.0.0
│ └── webcrypto-core@1.7.5
└─┬ @relaycorp/relaynet-core@1.81.2
  ├─┬ @peculiar/webcrypto@1.4.0
  │ └── webcrypto-core@1.7.5 deduped
  └── webcrypto-core@1.7.5 deduped

package-lock.json does appear to show two instances of @peculiar/webcrypto if I'm reading it right. That's still the case after deleting package-lock.json and node_modules, and running npm i again.