crypto,all: allow to choose which crypto key algo are allowed - #46
crypto,all: allow to choose which crypto key algo are allowed#46MichaelMure wants to merge 6 commits into
Conversation
662854b to
345e151
Compare
There was a problem hiding this comment.
Pull request overview
This PR refactors public-key decoding to be policy-driven via a pluggable crypto.KeySet, allowing callers to control which key algorithms (and for RSA, modulus sizes) are permitted during DID resolution. It replaces the previous “decode everything” approach (crypto/_allkeys) with opt-in registration (including a crypto/all convenience package) and wires the policy into did:key and did:plc resolution paths.
Changes:
- Introduces
crypto.KeySet/crypto.KeyType, an initially-emptycrypto.DefaultKeySet, and acrypto/allside-effect import to register all supported algorithms. - Adds
did.WithKeySet(...)and updatesdid:key+did:plcresolution to decode public keys through the selected key set (movingdid:keyvalidation from parse-time toDocument()). - Switches RSA
publicKeyMultibaseencoding/decoding to PKCS#1 RSAPublicKey DER (from prior PKIX/X.509 encoding).
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| verifiers/did-web/web.go | Documents that did:web does not apply WithKeySet during resolution. |
| verifiers/did-plc/plc.go | Decodes did:plc embedded did:key public keys via the resolution KeySet. |
| verifiers/did-plc/plc_test.go | Updates tests to opt into all algorithms via crypto/all. |
| verifiers/did-plc/document_test.go | Adds coverage verifying WithKeySet enforcement during did:plc resolution. |
| verifiers/did-key/key.go | Defers key decoding to Document() using the resolution KeySet; parse no longer decodes/validates keys. |
| verifiers/did-key/key_test.go | Updates tests for new did:key behavior and adds WithKeySet coverage. |
| verifiers/_methods/multikey/multikey.go | Switches Multikey JSON decoding to use crypto.PublicKeyFromMultibase (DefaultKeySet-governed). |
| options.go | Adds ResolutionOpts.keySet, accessor KeySet(), and did.WithKeySet(...). |
| document/document_test.go | Ensures tests register algorithms via crypto/all. |
| did_test.go | Adds WithKeySet tests and registers algorithms via crypto/all. |
| crypto/x25519/key.go | Adds x25519.KeyType() for KeySet registration. |
| crypto/secp256k1/key.go | Adds secp256k1.KeyType() for KeySet registration. |
| crypto/rsa/public.go | Changes RSA multibase decode/encode to PKCS#1 RSAPublicKey DER. |
| crypto/rsa/key.go | Adds rsa.KeyType(sizes...) to encode RSA size policy into a KeySet. |
| crypto/p521/key.go | Adds p521.KeyType() for KeySet registration. |
| crypto/p384/key.go | Adds p384.KeyType() for KeySet registration. |
| crypto/p256/key.go | Adds p256.KeyType() for KeySet registration. |
| crypto/keyset.go | Introduces KeySet, KeyType, DefaultKeySet, and helper decode APIs. |
| crypto/keyset_test.go | Adds tests for algorithm restriction and RSA size policy enforcement. |
| crypto/ed25519/key.go | Adds ed25519.KeyType() for KeySet registration. |
| crypto/all/all.go | Adds a kitchen-sink side-effect import to register all algorithms into DefaultKeySet. |
| crypto/_allkeys/allkeys.go | Removes the previous monolithic “all algorithms” decoder. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
345e151 to
b6ba90a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 57 out of 57 changed files in this pull request and generated 4 comments.
Suppressed comments (1)
verifiers/_methods/secp256k1/RecoveryMethod2020_test.go:193
RecoveryMethod2020no longer implementsjson.Unmarshaler, so both calls in this test silently leavevmas a zero value; the second call returns nil and makes the assertion fail. Exercise the new policy-aware factory instead.
963a47e to
9ce6a27
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9ce6a27. Configure here.
9ce6a27 to
d383061
Compare
d383061 to
7f735f9
Compare
4f22107 to
478ec68
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 63 out of 63 changed files in this pull request and generated 5 comments.
Suppressed comments (6)
crypto/x25519/public.go:42
- A typed-nil
*ecdh.PublicKeypasses the assertion and panics onk.Curve(). Since this API processes caller-provided key objects, report it as malformed input rather than crashing.
k, ok := key.(*ecdh.PublicKey)
if !ok || k.Curve() != ecdh.X25519() {
return nil, false, nil
}
return &PublicKey{k: k}, true, nil
crypto/secp256k1/public.go:65
- A typed-nil
*secp256k1.PublicKeyis accepted and wrapped withk == nil; subsequent operations such as serialization or verification will panic. Reject this malformed key during wrapping.
k, ok := key.(*secp256k1.PublicKey)
if !ok {
return nil, false, nil
}
return &PublicKey{k: k}, true, nil
crypto/keypolicy.go:204
Matchesis an extensibility callback and is called while holdingkp.mu.RLock. If it registers or otherwise needs the policy's write lock,Acceptsdeadlocks. Iterate over a snapshot so callbacks run without an internal lock held.
kp.mu.RLock()
defer kp.mu.RUnlock()
for _, kt := range kp.byCode {
if kt.Matches != nil && kt.Matches(key) {
return true
crypto/p256/public.go:64
- A malformed
*ecdsa.PublicKeyon P-256 can panic here: typed-nil keys dereferencek.Curve, and nil coordinates dereferencek.X/k.Y.KeyPolicy.WrapPublicKeyaccepts caller-provided objects and promises malformed keys as errors, so validate these fields before using them.
if !ok || k.Curve != elliptic.P256() {
return nil, false, nil
}
pub, err := PublicKeyFromXY(k.X.Bytes(), k.Y.Bytes())
return pub, true, err
crypto/p384/public.go:64
- A malformed
*ecdsa.PublicKeyon P-384 can panic here: typed-nil keys dereferencek.Curve, and nil coordinates dereferencek.X/k.Y. Return a malformed-key error through the wrapper instead of allowing caller input to crash the process.
if !ok || k.Curve != elliptic.P384() {
return nil, false, nil
}
pub, err := PublicKeyFromXY(k.X.Bytes(), k.Y.Bytes())
return pub, true, err
crypto/p521/public.go:64
- A malformed
*ecdsa.PublicKeyon P-521 can panic here: typed-nil keys dereferencek.Curve, and nil coordinates dereferencek.X/k.Y. Validate the object soKeyPolicy.WrapPublicKeycan classify it asErrInvalidKey.
if !ok || k.Curve != elliptic.P521() {
return nil, false, nil
}
pub, err := PublicKeyFromXY(k.X.Bytes(), k.Y.Bytes())
return pub, true, err
478ec68 to
d41b7e8
Compare

Note
High Risk
This is a breaking API and default-behavior change (empty default policy, new required imports, and stricter JSON decoding paths) across all DID resolution and crypto entry points.
Overview
This PR introduces an explicit crypto key acceptance policy so callers control which algorithms (and RSA sizes) are used when decoding keys from multibase, JWK, DID documents, and verification methods.
KeyPolicy and registration: New
crypto.KeyPolicy/KeyTyperegistry replaces the oldcrypto/_allkeyshelper.DefaultKeyPolicynow starts empty; apps register algorithms withcrypto.Register(...), blank-importcrypto/allfor tests/tools, or passdid.WithKeyPolicy(...)per resolution. Eachcrypto/<algo>package exposesKeyType()(plus JWK helpers andWrapPublicKeywhere needed).Parsing and security behavior: JWK and verification-method JSON no longer decode keys without a policy—direct
json.Unmarshalon verification methods fails withErrDirectUnmarshal; useNew*FromJSONor the_methodsregistry (importverifiers/_methods/allfor everything). Document parsing anddid:web/did:plc/did:keyresolution thread the policy through; policy rejections returnErrKeyNotAccepted(distinct from malformeddid:keysyntax). Ed25519-derived X25519 key agreement entries are omitted when X25519 is not allowed.Other notable changes: RSA
publicKeyMultibaseencoding/decoding aligns with did:key (PKCS#1 DER); RSA wrapping copies keys to avoid mutable-modulus issues.Reviewed by Cursor Bugbot for commit d41b7e8. Bugbot is set up for automated code reviews on this repo. Configure here.