@@ -4,6 +4,9 @@
|
||||
package didkey
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -15,10 +18,8 @@ import (
|
||||
const (
|
||||
// KeyPrefix indicates a decentralized identifier that uses the key method
|
||||
KeyPrefix = "did:key"
|
||||
// MulticodecKindRSAPubKey IS NOT A REAL MULTICODEC PREFIX.
|
||||
// pulled from: https://github.com/w3c-ccg/lds-ed25519-2018/issues/3 because
|
||||
// it's only slighly better than picking a random available byte prefix
|
||||
MulticodecKindRSAPubKey = 0x5d
|
||||
// MulticodecKindRSAPubKey rsa-x509-pub https://github.com/multiformats/multicodec/pull/226
|
||||
MulticodecKindRSAPubKey = 0x1205
|
||||
// MulticodecKindEd25519PubKey ed25519-pub
|
||||
MulticodecKindEd25519PubKey = 0xed
|
||||
)
|
||||
@@ -28,6 +29,16 @@ type ID struct {
|
||||
crypto.PubKey
|
||||
}
|
||||
|
||||
// NewID constructs an Identifier from a public key
|
||||
func NewID(pub crypto.PubKey) (ID, error) {
|
||||
switch pub.Type() {
|
||||
case crypto.Ed25519, crypto.RSA:
|
||||
return ID{PubKey: pub}, nil
|
||||
default:
|
||||
return ID{}, fmt.Errorf("unsupported key type: %s", pub.Type())
|
||||
}
|
||||
}
|
||||
|
||||
// MulticodecType indicates the type for this multicodec
|
||||
func (id ID) MulticodecType() uint64 {
|
||||
switch id.Type() {
|
||||
@@ -61,6 +72,31 @@ func (id ID) String() string {
|
||||
return fmt.Sprintf("%s:%s", KeyPrefix, b58BKeyStr)
|
||||
}
|
||||
|
||||
// VerifyKey returns the backing implementation for a public key, one of:
|
||||
// *rsa.PublicKey, ed25519.PublicKey
|
||||
func (id ID) VerifyKey() (interface{}, error) {
|
||||
rawPubBytes, err := id.PubKey.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch id.PubKey.Type() {
|
||||
case crypto.RSA:
|
||||
verifyKeyiface, err := x509.ParsePKIXPublicKey(rawPubBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
verifyKey, ok := verifyKeyiface.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("public key is not an RSA key. got type: %T", verifyKeyiface)
|
||||
}
|
||||
return verifyKey, nil
|
||||
case crypto.Ed25519:
|
||||
return ed25519.PublicKey(rawPubBytes), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized Public Key type: %s", id.PubKey.Type())
|
||||
}
|
||||
}
|
||||
|
||||
// Parse turns a string into a key method ID
|
||||
func Parse(keystr string) (ID, error) {
|
||||
var id ID
|
||||
@@ -70,9 +106,13 @@ func Parse(keystr string) (ID, error) {
|
||||
|
||||
keystr = strings.TrimPrefix(keystr, KeyPrefix+":")
|
||||
|
||||
_, data, err := mb.Decode(keystr)
|
||||
enc, data, err := mb.Decode(keystr)
|
||||
if err != nil {
|
||||
return id, err
|
||||
return id, fmt.Errorf("decoding multibase: %w", err)
|
||||
}
|
||||
|
||||
if enc != mb.Base58BTC {
|
||||
return id, fmt.Errorf("unexpected multibase encoding: %s", mb.EncodingToStr[enc])
|
||||
}
|
||||
|
||||
keyType, n, err := varint.FromUvarint(data)
|
||||
|
||||
@@ -56,9 +56,9 @@ func Example() {
|
||||
panicIfError(err)
|
||||
|
||||
// Output:
|
||||
// cid of root UCAN: bafkreidhsvhlctwylgeibl2eeapdvbl3qm3mbqcqhxhvy4grmr25ji77hu
|
||||
// cid of root UCAN: bafkreih6guuxohv47s2e366l6jn6stlsukgoerkdvtsni3kxr4jjmkaf3y
|
||||
// scope of ucan attenuations must be less than it's parent
|
||||
// cid of derived UCAN: bafkreifglbwtr27fbzmv3uardlygvggr722fckusfvfyfsonwkroca7efu
|
||||
// cid of derived UCAN: bafkreihpk5474uoolkqrge3yk5uy2s7rarhn5xwxfoiobcy6ye7vfxetgm
|
||||
}
|
||||
|
||||
func panicIfError(err error) {
|
||||
|
||||
4
go.mod
4
go.mod
@@ -10,6 +10,6 @@ require (
|
||||
github.com/multiformats/go-multibase v0.0.3
|
||||
github.com/multiformats/go-multihash v0.0.14
|
||||
github.com/multiformats/go-varint v0.0.6
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
|
||||
)
|
||||
|
||||
12
go.sum
12
go.sum
@@ -82,8 +82,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -95,6 +95,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -105,10 +106,13 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
101
token.go
101
token.go
@@ -10,18 +10,18 @@ package ucan
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/libp2p/go-libp2p-core/crypto"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
"github.com/qri-io/ucan/didkey"
|
||||
)
|
||||
|
||||
// ErrInvalidToken indicates an access token is invalid
|
||||
@@ -125,12 +125,8 @@ type pkSource struct {
|
||||
issuerDID string
|
||||
signingMethod jwt.SigningMethod
|
||||
|
||||
verifyKey *rsa.PublicKey
|
||||
signKey *rsa.PrivateKey
|
||||
|
||||
ap AttenuationConstructorFunc
|
||||
resolver CIDBytesResolver
|
||||
store TokenStore
|
||||
verifyKey interface{} // one of: *rsa.PublicKey, *edsa.PublicKey
|
||||
signKey interface{} // one of: *rsa.PrivateKey,
|
||||
}
|
||||
|
||||
// assert pkSource implements tokens at compile time
|
||||
@@ -139,40 +135,50 @@ var _ Source = (*pkSource)(nil)
|
||||
// NewPrivKeySource creates an authentication interface backed by a single
|
||||
// private key. Intended for a node running as remote, or providing a public API
|
||||
func NewPrivKeySource(privKey crypto.PrivKey) (Source, error) {
|
||||
methodStr := ""
|
||||
keyType := privKey.Type()
|
||||
rawPrivBytes, err := privKey.Raw()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting private key bytes: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
methodStr = ""
|
||||
keyType = privKey.Type()
|
||||
signKey interface{}
|
||||
verifyKey interface{}
|
||||
)
|
||||
|
||||
switch keyType {
|
||||
case crypto.RSA:
|
||||
methodStr = "RS256"
|
||||
case crypto.Ed25519:
|
||||
methodStr = "EdDSA"
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported key type for token creation: %q", keyType)
|
||||
}
|
||||
|
||||
signingMethod := jwt.GetSigningMethod(methodStr)
|
||||
|
||||
rawPrivBytes, err := privKey.Raw()
|
||||
// TODO(b5) - detect if key is encoded as PEM block, here we're assuming it is
|
||||
signKey, err = x509.ParsePKCS1PrivateKey(rawPrivBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signKey, err := x509.ParsePKCS1PrivateKey(rawPrivBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawPubBytes, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("getting raw public key bytes: %w", err)
|
||||
}
|
||||
verifyKeyiface, err := x509.ParsePKIXPublicKey(rawPubBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("parsing public key bytes: %w", err)
|
||||
}
|
||||
verifyKey, ok := verifyKeyiface.(*rsa.PublicKey)
|
||||
var ok bool
|
||||
verifyKey, ok = verifyKeyiface.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("public key is not an RSA key. got type: %T", verifyKeyiface)
|
||||
}
|
||||
case crypto.Ed25519:
|
||||
methodStr = "EdDSA"
|
||||
signKey = ed25519.PrivateKey(rawPrivBytes)
|
||||
rawPubBytes, err := privKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting raw public key bytes: %w", err)
|
||||
}
|
||||
verifyKey = ed25519.PublicKey(rawPubBytes)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported key type for token creation: %q", keyType)
|
||||
}
|
||||
|
||||
issuerDID, err := DIDStringFromPublicKey(privKey.GetPublic())
|
||||
if err != nil {
|
||||
@@ -181,7 +187,7 @@ func NewPrivKeySource(privKey crypto.PrivKey) (Source, error) {
|
||||
|
||||
return &pkSource{
|
||||
pk: privKey,
|
||||
signingMethod: signingMethod,
|
||||
signingMethod: jwt.GetSigningMethod(methodStr),
|
||||
verifyKey: verifyKey,
|
||||
signKey: signKey,
|
||||
issuerDID: issuerDID,
|
||||
@@ -253,16 +259,16 @@ func (a *pkSource) newToken(subjectDID string, prf []Proof, att Attenuations, fc
|
||||
// DIDPubKeyResolver turns did:key Decentralized IDentifiers into a public key,
|
||||
// possibly using a network request
|
||||
type DIDPubKeyResolver interface {
|
||||
ResolveDIDKey(ctx context.Context, did string) (crypto.PubKey, error)
|
||||
ResolveDIDKey(ctx context.Context, did string) (didkey.ID, error)
|
||||
}
|
||||
|
||||
// DIDStringFromPublicKey creates a did:key identifier string from a public key
|
||||
func DIDStringFromPublicKey(pub crypto.PubKey) (string, error) {
|
||||
rawPubBytes, err := pub.Raw()
|
||||
id, err := didkey.NewID(pub)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("did:key:%s", base64.URLEncoding.EncodeToString(rawPubBytes)), nil
|
||||
return id.String(), nil
|
||||
}
|
||||
|
||||
// StringDIDPubKeyResolver implements the DIDPubKeyResolver interface without
|
||||
@@ -271,18 +277,8 @@ func DIDStringFromPublicKey(pub crypto.PubKey) (string, error) {
|
||||
type StringDIDPubKeyResolver struct{}
|
||||
|
||||
// ResolveDIDKey extracts a public key from a did:key string
|
||||
func (StringDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (crypto.PubKey, error) {
|
||||
// id, err := did.Parse(didStr)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("invalid DID: %w", err)
|
||||
// }
|
||||
|
||||
data, err := base64.URLEncoding.DecodeString(strings.TrimPrefix(didStr, "did:key:"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return crypto.UnmarshalRsaPublicKey(data)
|
||||
func (StringDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (didkey.ID, error) {
|
||||
return didkey.Parse(didStr)
|
||||
}
|
||||
|
||||
// TokenParser parses a raw string into a Token
|
||||
@@ -309,7 +305,7 @@ func (p *TokenParser) ParseAndVerify(ctx context.Context, raw string) (*Token, e
|
||||
func (p *TokenParser) parseAndVerify(ctx context.Context, raw string, child *Token) (*Token, error) {
|
||||
tok, err := jwt.Parse(raw, p.matchVerifyKeyFunc(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("parsing UCAN: %w", err)
|
||||
}
|
||||
|
||||
mc, ok := tok.Claims.(jwt.MapClaims)
|
||||
@@ -366,24 +362,11 @@ func (p *TokenParser) matchVerifyKeyFunc(ctx context.Context) func(tok *jwt.Toke
|
||||
return nil, fmt.Errorf(`"iss" claims key is required`)
|
||||
}
|
||||
|
||||
pubKey, err := p.didr.ResolveDIDKey(ctx, iss)
|
||||
id, err := p.didr.ResolveDIDKey(ctx, iss)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawPubBytes, err := pubKey.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
verifyKeyiface, err := x509.ParsePKIXPublicKey(rawPubBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
verifyKey, ok := verifyKeyiface.(*rsa.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("public key is not an RSA key. got type: %T", verifyKeyiface)
|
||||
}
|
||||
|
||||
return verifyKey, nil
|
||||
return id.VerifyKey()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestPrivKeySource(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expect := `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVjdiI6IjAuNC4wIn0.eyJpc3MiOiJkaWQ6a2V5Ok1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBb2FkUjRtY1U3QzBBbWg1bHRfM0hObVEyYVlDOEotYU5mNTJUNEtrLTBzbHh6LVc1LXhrREJ0NUR4RUZuSmVKNGJTMV9ZWkt3UkxKQjYzU0phcWZjMXhUTUFYMnJmcW44d3NwUmd2MEFReGU4RV9icGkzZTUyNnU2UU1VRjdYbDRKN2JkbVlZT0lCUDVCSk83eU1pX2pfU3FWaVdmOG82Y3BJTEF3dXpUNTY2X0ttUWFOclM5QmVNUHQ5NTJZUk1lejZlMFoycXR0aVRQS3hmalJ3b0VwRklldDVhZTFZY0p2VDBLQnJiZEYwNXhDc2F6RUoxSm52eUlSamNiUE9FYVljUjNPZnAxdW8ySTRKdVczQ2FKeHNqMU8yNnZyLWRUSzlqcGVFVTl5X1dUU1lNOUVsazBwZ0xZZ1M4ZHE4aTYwNDVnejByemU4QzV2YkZoSFZwa1ZRSURBUUFCIiwic3ViIjoiZGlkOmtleTpNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQW9hZFI0bWNVN0MwQW1oNWx0XzNITm1RMmFZQzhKLWFOZjUyVDRLay0wc2x4ei1XNS14a0RCdDVEeEVGbkplSjRiUzFfWVpLd1JMSkI2M1NKYXFmYzF4VE1BWDJyZnFuOHdzcFJndjBBUXhlOEVfYnBpM2U1MjZ1NlFNVUY3WGw0SjdiZG1ZWU9JQlA1QkpPN3lNaV9qX1NxVmlXZjhvNmNwSUxBd3V6VDU2Nl9LbVFhTnJTOUJlTVB0OTUyWVJNZXo2ZTBaMnF0dGlUUEt4ZmpSd29FcEZJZXQ1YWUxWWNKdlQwS0JyYmRGMDV4Q3NhekVKMUpudnlJUmpjYlBPRWFZY1IzT2ZwMXVvMkk0SnVXM0NhSnhzajFPMjZ2ci1kVEs5anBlRVU5eV9XVFNZTTlFbGswcGdMWWdTOGRxOGk2MDQ1Z3owcnplOEM1dmJGaEhWcGtWUUlEQVFBQiIsImF0dCI6W3siYXBpIjoiKiIsImNhcCI6IlNVUEVSX1VTRVIifSx7ImNhcCI6IlNVUEVSX1VTRVIiLCJkYXRhc2V0IjoiYjU6d29ybGRfYmFua19wb3B1bGF0aW9uOioifV19.Z32-i-pGAtPRsG0JW4ZS8-c17x3mX3kFrmZ0BYhyWk2JH4QMwXFRtkUl8xVQtrC3JigeQeaDiz-WTUSFqJIs5dunL1Xf_SXqq8SZ7NCh6u6OEo2L1BnQkwdO8kDsFoiF42byWDBwzHRog0N-pRXgMhlo8si6Pek4KAZokQ5F-8FuLb3MXXxc9-FnhGRsKgGt_bNWS322h5gXCaXJAzbdAHwGSlORCCJI4CrbWUHs03i4viun2Ht01JO-p4ySlut6YyQ_vW4NGNSAAXGeR-ggkB0B6TGgt695CxX1zgQKV7X6JZx-NF_J-OXCIWngCfr6VdRv1_ADce9s1ODEm2N7eA`
|
||||
expect := `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVjdiI6IjAuNC4wIn0.eyJpc3MiOiJkaWQ6a2V5OnoyTUd3NGdrODRVU290YVdmNEFrSjgzRGNucmZnR2FjZUY4NktRWFJZTWZRN3hxblVGRVREN3RGNGprTkd2QUV0dlZ6Rm5RdTkydEZ3ZkNyb2ZWZ0c2WnkyZVlKZURSckVVZ1c5WXZCazJXSHVUUnJFZ0FTZnBxR2tKUkdnR3FiNmNidjFxR2N2Nm1FSFF5YlR5M2JOeXFxd3VRWXA3c3BuSlFObVJhUGk0Z3F1czVEWnVOc2NRZjFSMXhCdVN6WHk1YnNCaFlSZzdFcDZmNkJad0U2cHZCamt5ellqWERVYlF2a0VpeG0zcHR3RTRnZ2VZU21oUXFxbU1ac1lwcG1lY1VFMjhuTTdFekx2Q3hRZEZ1QndXZ2U3QURVYzdxVGYxeXNpUzl1YXdOTnA1aER2aHl2cXRDaWg3a3FvTHVzTGVnd2pHZTJTcDhDcUZmdUNRNWgxdHh4WHozdEdtRGZEUDE3Nm15R1htc3R0eDV5MjVTOXpwejg1ZEc4WnRrRnZ4bXNjOFltaXZlRUMycWFkY2FrWEoiLCJzdWIiOiJkaWQ6a2V5OnoyTUd3NGdrODRVU290YVdmNEFrSjgzRGNucmZnR2FjZUY4NktRWFJZTWZRN3hxblVGRVREN3RGNGprTkd2QUV0dlZ6Rm5RdTkydEZ3ZkNyb2ZWZ0c2WnkyZVlKZURSckVVZ1c5WXZCazJXSHVUUnJFZ0FTZnBxR2tKUkdnR3FiNmNidjFxR2N2Nm1FSFF5YlR5M2JOeXFxd3VRWXA3c3BuSlFObVJhUGk0Z3F1czVEWnVOc2NRZjFSMXhCdVN6WHk1YnNCaFlSZzdFcDZmNkJad0U2cHZCamt5ellqWERVYlF2a0VpeG0zcHR3RTRnZ2VZU21oUXFxbU1ac1lwcG1lY1VFMjhuTTdFekx2Q3hRZEZ1QndXZ2U3QURVYzdxVGYxeXNpUzl1YXdOTnA1aER2aHl2cXRDaWg3a3FvTHVzTGVnd2pHZTJTcDhDcUZmdUNRNWgxdHh4WHozdEdtRGZEUDE3Nm15R1htc3R0eDV5MjVTOXpwejg1ZEc4WnRrRnZ4bXNjOFltaXZlRUMycWFkY2FrWEoiLCJhdHQiOlt7ImFwaSI6IioiLCJjYXAiOiJTVVBFUl9VU0VSIn0seyJjYXAiOiJTVVBFUl9VU0VSIiwiZGF0YXNldCI6ImI1OndvcmxkX2JhbmtfcG9wdWxhdGlvbjoqIn1dfQ.SwctK9sJpUtgyOSKN3BMI1BfNT_X6xxy5Oy6aTCvGvdj-vJIxsioz2Po3TlFxpmo9uSJ_nGoUTW7fr7Hc5m8qqrUFnPrtPXOnSNluExh9sh0aXY1ACGNoDknhbnsU_5nkEhDSTOMQ0Y0MoqvkV_Ti-7ZjISEuGukvl4-FFXZVGl6zY7ii8-J3RQu60cMbR4xK-VnlXcZUnhREr8JQtPKfBnmjIvbPclnaOdXLSACgEPXsAX4gekYAb2HR8CduHmaFWqAq_Th-QbqgQVmqUw-VIwtwuxxfxpc-PTNV4L0eDH5jO9i7jVzU3KaWM8NzQ2vux_zhscjBQFR2SmpQuGO7A`
|
||||
if expect != root.Raw {
|
||||
t.Errorf("token mismatch. expected: %q.\ngot: %q", expect, root.Raw)
|
||||
}
|
||||
@@ -77,7 +77,7 @@ func TestPrivKeySource(t *testing.T) {
|
||||
}
|
||||
|
||||
cidStr := mustCidString(t, derivedToken)
|
||||
expectCID := "bafkreifglbwtr27fbzmv3uardlygvggr722fckusfvfyfsonwkroca7efu"
|
||||
expectCID := "bafkreihpk5474uoolkqrge3yk5uy2s7rarhn5xwxfoiobcy6ye7vfxetgm"
|
||||
|
||||
if expectCID != cidStr {
|
||||
t.Errorf("derived token CID mismatch. expected: %q.\ngot: %q", expectCID, cidStr)
|
||||
@@ -90,6 +90,35 @@ func TestPrivKeySource(t *testing.T) {
|
||||
// }
|
||||
}
|
||||
|
||||
func TestED25519PrivKeySource(t *testing.T) {
|
||||
keyOne, _, err := crypto.GenerateKeyPair(crypto.Ed25519, 123)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
source, err := ucan.NewPrivKeySource(keyOne)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
subjectDID, err := ucan.DIDStringFromPublicKey(keyOne.GetPublic())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
zero := time.Time{}
|
||||
|
||||
// create a root UCAN
|
||||
origin, err := source.NewOriginToken(subjectDID, nil, nil, zero, zero)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if _, err = origin.CID(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenSource(t *testing.T) {
|
||||
// ucan_spec.AssertTokenSourceSpec(t, func(ctx context.Context) ucan.TokenSource {
|
||||
// source, err := ucan.NewPrivKeyTokenSource(peerInfo.PrivKey)
|
||||
@@ -101,7 +130,7 @@ func TestTokenSource(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTokenParse(t *testing.T) {
|
||||
raw := `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVjdiI6IjAuNC4wIn0.eyJpc3MiOiJkaWQ6a2V5Ok1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBb2FkUjRtY1U3QzBBbWg1bHRfM0hObVEyYVlDOEotYU5mNTJUNEtrLTBzbHh6LVc1LXhrREJ0NUR4RUZuSmVKNGJTMV9ZWkt3UkxKQjYzU0phcWZjMXhUTUFYMnJmcW44d3NwUmd2MEFReGU4RV9icGkzZTUyNnU2UU1VRjdYbDRKN2JkbVlZT0lCUDVCSk83eU1pX2pfU3FWaVdmOG82Y3BJTEF3dXpUNTY2X0ttUWFOclM5QmVNUHQ5NTJZUk1lejZlMFoycXR0aVRQS3hmalJ3b0VwRklldDVhZTFZY0p2VDBLQnJiZEYwNXhDc2F6RUoxSm52eUlSamNiUE9FYVljUjNPZnAxdW8ySTRKdVczQ2FKeHNqMU8yNnZyLWRUSzlqcGVFVTl5X1dUU1lNOUVsazBwZ0xZZ1M4ZHE4aTYwNDVnejByemU4QzV2YkZoSFZwa1ZRSURBUUFCIiwic3ViIjoiZGlkOmtleTpNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQW9hZFI0bWNVN0MwQW1oNWx0XzNITm1RMmFZQzhKLWFOZjUyVDRLay0wc2x4ei1XNS14a0RCdDVEeEVGbkplSjRiUzFfWVpLd1JMSkI2M1NKYXFmYzF4VE1BWDJyZnFuOHdzcFJndjBBUXhlOEVfYnBpM2U1MjZ1NlFNVUY3WGw0SjdiZG1ZWU9JQlA1QkpPN3lNaV9qX1NxVmlXZjhvNmNwSUxBd3V6VDU2Nl9LbVFhTnJTOUJlTVB0OTUyWVJNZXo2ZTBaMnF0dGlUUEt4ZmpSd29FcEZJZXQ1YWUxWWNKdlQwS0JyYmRGMDV4Q3NhekVKMUpudnlJUmpjYlBPRWFZY1IzT2ZwMXVvMkk0SnVXM0NhSnhzajFPMjZ2ci1kVEs5anBlRVU5eV9XVFNZTTlFbGswcGdMWWdTOGRxOGk2MDQ1Z3owcnplOEM1dmJGaEhWcGtWUUlEQVFBQiIsImF0dCI6W3siYXBpIjoiKiIsImNhcCI6IlNVUEVSX1VTRVIifSx7ImNhcCI6IlNVUEVSX1VTRVIiLCJkYXRhc2V0IjoiYjU6d29ybGRfYmFua19wb3B1bGF0aW9uOioifV19.Z32-i-pGAtPRsG0JW4ZS8-c17x3mX3kFrmZ0BYhyWk2JH4QMwXFRtkUl8xVQtrC3JigeQeaDiz-WTUSFqJIs5dunL1Xf_SXqq8SZ7NCh6u6OEo2L1BnQkwdO8kDsFoiF42byWDBwzHRog0N-pRXgMhlo8si6Pek4KAZokQ5F-8FuLb3MXXxc9-FnhGRsKgGt_bNWS322h5gXCaXJAzbdAHwGSlORCCJI4CrbWUHs03i4viun2Ht01JO-p4ySlut6YyQ_vW4NGNSAAXGeR-ggkB0B6TGgt695CxX1zgQKV7X6JZx-NF_J-OXCIWngCfr6VdRv1_ADce9s1ODEm2N7eA`
|
||||
raw := `eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInVjdiI6IjAuNC4wIn0.eyJpc3MiOiJkaWQ6a2V5OnoyTUd3NGdrODRVU290YVdmNEFrSjgzRGNucmZnR2FjZUY4NktRWFJZTWZRN3hxblVGRVREN3RGNGprTkd2QUV0dlZ6Rm5RdTkydEZ3ZkNyb2ZWZ0c2WnkyZVlKZURSckVVZ1c5WXZCazJXSHVUUnJFZ0FTZnBxR2tKUkdnR3FiNmNidjFxR2N2Nm1FSFF5YlR5M2JOeXFxd3VRWXA3c3BuSlFObVJhUGk0Z3F1czVEWnVOc2NRZjFSMXhCdVN6WHk1YnNCaFlSZzdFcDZmNkJad0U2cHZCamt5ellqWERVYlF2a0VpeG0zcHR3RTRnZ2VZU21oUXFxbU1ac1lwcG1lY1VFMjhuTTdFekx2Q3hRZEZ1QndXZ2U3QURVYzdxVGYxeXNpUzl1YXdOTnA1aER2aHl2cXRDaWg3a3FvTHVzTGVnd2pHZTJTcDhDcUZmdUNRNWgxdHh4WHozdEdtRGZEUDE3Nm15R1htc3R0eDV5MjVTOXpwejg1ZEc4WnRrRnZ4bXNjOFltaXZlRUMycWFkY2FrWEoiLCJzdWIiOiJkaWQ6a2V5OnoyTUd3NGdrODRVU290YVdmNEFrSjgzRGNucmZnR2FjZUY4NktRWFJZTWZRN3hxblVGRVREN3RGNGprTkd2QUV0dlZ6Rm5RdTkydEZ3ZkNyb2ZWZ0c2WnkyZVlKZURSckVVZ1c5WXZCazJXSHVUUnJFZ0FTZnBxR2tKUkdnR3FiNmNidjFxR2N2Nm1FSFF5YlR5M2JOeXFxd3VRWXA3c3BuSlFObVJhUGk0Z3F1czVEWnVOc2NRZjFSMXhCdVN6WHk1YnNCaFlSZzdFcDZmNkJad0U2cHZCamt5ellqWERVYlF2a0VpeG0zcHR3RTRnZ2VZU21oUXFxbU1ac1lwcG1lY1VFMjhuTTdFekx2Q3hRZEZ1QndXZ2U3QURVYzdxVGYxeXNpUzl1YXdOTnA1aER2aHl2cXRDaWg3a3FvTHVzTGVnd2pHZTJTcDhDcUZmdUNRNWgxdHh4WHozdEdtRGZEUDE3Nm15R1htc3R0eDV5MjVTOXpwejg1ZEc4WnRrRnZ4bXNjOFltaXZlRUMycWFkY2FrWEoiLCJhdHQiOlt7ImFwaSI6IioiLCJjYXAiOiJTVVBFUl9VU0VSIn0seyJjYXAiOiJTVVBFUl9VU0VSIiwiZGF0YXNldCI6ImI1OndvcmxkX2JhbmtfcG9wdWxhdGlvbjoqIn1dfQ.SwctK9sJpUtgyOSKN3BMI1BfNT_X6xxy5Oy6aTCvGvdj-vJIxsioz2Po3TlFxpmo9uSJ_nGoUTW7fr7Hc5m8qqrUFnPrtPXOnSNluExh9sh0aXY1ACGNoDknhbnsU_5nkEhDSTOMQ0Y0MoqvkV_Ti-7ZjISEuGukvl4-FFXZVGl6zY7ii8-J3RQu60cMbR4xK-VnlXcZUnhREr8JQtPKfBnmjIvbPclnaOdXLSACgEPXsAX4gekYAb2HR8CduHmaFWqAq_Th-QbqgQVmqUw-VIwtwuxxfxpc-PTNV4L0eDH5jO9i7jVzU3KaWM8NzQ2vux_zhscjBQFR2SmpQuGO7A`
|
||||
|
||||
caps := ucan.NewNestedCapabilities("SUPER_USER", "OVERWRITE", "SOFT_DELETE", "REVISE", "CREATE")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user