refactor: Support JwsVerificationKey2020 for DID public key #1538
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1538 +/- ##
==========================================
+ Coverage 91.32% 91.42% +0.09%
==========================================
Files 156 156
Lines 10633 10752 +119
==========================================
+ Hits 9711 9830 +119
+ Misses 518 517 -1
- Partials 404 405 +1
Continue to review full report at Codecov.
|
"math/big" | ||
|
||
"github.com/decred/dcrd/dcrec/secp256k1/v2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have you tried github.com/btcsuite ? I believe they have secp256k1 alg as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't. github.com/decred
was initially added by @sudeshrshetty but I think we can switch to github.com/btcsuite
.
switch pubKey.Curve { | ||
case "P-256": | ||
curve = elliptic.P256() | ||
keySize = 32 | ||
case "P-384": | ||
curve = elliptic.P384() | ||
keySize = 48 | ||
case "P-521": | ||
curve = elliptic.P521() | ||
keySize = 66 | ||
case "secp256k1": | ||
curve = secp256k1.S256() | ||
keySize = 32 | ||
default: | ||
return fmt.Errorf("ecdsa: unsupported elliptic curve '%s'", pubKey.Curve) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't belong to Verify()
create a separate function
probably create a struct keyInfo that has a curve and keySize if needed in more than one place
probably expose it to be used for Sign as well ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK! I will try to simplify it.
y *big.Int | ||
Kty string | ||
Crv string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no kid
needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's already there, inside embedded jose.JSONWebKey
. x
, y
, key type
, curve
are not copied from jose.rawJSONWebKey
to jose.JSONWebKey
as a result of unmarshalling. That's why I had to add them to JWK
struct to support secp256k1
properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there seems to be duplication of fields with JSONWebKey then.. it's better to remove duplicate fields
pkg/doc/did/doc.go
Outdated
|
||
Value []byte | ||
|
||
Algorithm string `json:"-"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we need to show Alg, Curve & KeyType in exported did.Doc.PublicKey? Why can't we just decode public key internally and stick to old structure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can at least make it hidden, why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those new fields are made private, thank you @sudeshrshetty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, but what is the use of those private fields?
As I can see we are setting it from jwk instance but they are not being read anywhere afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
usually Curve
is exposed (like in ecdsa.PublicKey)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why clients should care about curve? For key type based logics - they should be able to figure out using public key type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For JsonWebSignature2020
, it's not enough to have only type
value of the public key. Look at the example:
"publicKey": [
{
"id": "did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A",
"type": "JwsVerificationKey2020",
"controller": "did:example:123",
"publicKeyJwk": {
"crv": "Ed25519",
"x": "VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ",
"kty": "OKP",
"kid": "_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"
}
},
{
"id": "did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A",
"type": "JwsVerificationKey2020",
"controller": "did:example:123",
"publicKeyJwk": {
"crv": "secp256k1",
"x": "Z4Y3NNOxv0J6tCgqOBFnHnaZhJF6LdulT7z8A-2D5_8",
"y": "i5a2NtJoUKXkLm6q8nOEu9WOkso1Ag6FTUT6k_LMnGk",
"kty": "EC",
"kid": "4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"
}
}
]
The type
is the same and is JwsVerificationKey2020
.
We can't deduce is it Ed25519
or secp256k1
etc. We need to extract extra information from publicKeyJwk
.
That's the problem solved in this PR.
604d9ad
to
ce99590
Compare
pkg/doc/jose/jwk.go
Outdated
// if kty="EC" and Crv="secp256k1", then handle differently | ||
return btcPublicKey(key.X, key.Y) | ||
if jwk.Y == nil { | ||
return nil, fmt.Errorf("missed y value in EC key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed there are many detailed error messages returned like the above line.
If these messages reveal key details, then it's a security vulnerability. Please review all the returned errors in this document and only return generic messages to the user (or probably log detailed error messages in debug
mode only).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I changed the detailed error messages to a single generic invalid JWK
.
pkg/doc/did/doc.go
Outdated
|
||
Value []byte | ||
|
||
algorithm string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would seem like it could be a publicKeyJWK sub struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, we can just add publicKeyJwk
field of *jose.JWK
type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will also update verifier.PublicKey
struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
Curve: elliptic.P521(), | ||
KeySize: p521KeySize, | ||
} | ||
case "secp256k1": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about X25519 / Ed25519?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed #1556.
closes hyperledger-archives#1527, hyperledger-archives#1513 Signed-off-by: Dmitriy Kinoshenko <dkinoshenko@gmail.com>
For linked data signatures with
JwsVerificationKey2020
type, it's not enough information to make signature verification based on the public key bytes and a type (JwsVerificationKey2020). We need to know additionally what signature algorithm (and/or curve) was used - e.g.ES256
orEdDSA
.In the case of DID documents, we can read this information from the public key if it's defined as
publicKeyJwk
.As a result, we extend
PublicKey
struct withCurve
,Alg
andKeyType
fields and use them in the signature verifier implementations (e.g. inPublicKeyVerifierEC
).closes #1527, #1513
Signed-off-by: Dmitriy Kinoshenko dkinoshenko@gmail.com