[#190] Add isOwnerFromKey helper function in ACL
This function takes public key and returns true if owner id was produced by this key. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
a14bb6292b
commit
f0537b35c1
2 changed files with 25 additions and 22 deletions
|
@ -3,6 +3,7 @@ package acl
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
acl "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
|
@ -639,29 +640,17 @@ func isValidBearer(reqInfo requestInfo, st netmap.State) bool {
|
||||||
|
|
||||||
// 3. Then check if container owner signed this token.
|
// 3. Then check if container owner signed this token.
|
||||||
tokenIssuerKey := crypto.UnmarshalPublicKey(token.GetSignature().GetKey())
|
tokenIssuerKey := crypto.UnmarshalPublicKey(token.GetSignature().GetKey())
|
||||||
tokenIssuerWallet, err := owner.NEO3WalletFromPublicKey(tokenIssuerKey)
|
if !isOwnerFromKey(reqInfo.owner, tokenIssuerKey) {
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// here we compare `owner.ID -> wallet` with `wallet <- publicKey`
|
|
||||||
// consider making equal method on owner.ID structure
|
|
||||||
// we can compare .String() version of owners but don't think it is good idea
|
|
||||||
// binary comparison is better but MarshalBinary is more expensive
|
|
||||||
if !bytes.Equal(reqInfo.owner.ToV2().GetValue(), tokenIssuerWallet.Bytes()) {
|
|
||||||
// todo: in this case we can issue all owner keys from neofs.id and check once again
|
// todo: in this case we can issue all owner keys from neofs.id and check once again
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Then check if request sender has rights to use this token.
|
// 4. Then check if request sender has rights to use this token.
|
||||||
tokenOwnerField := token.GetBody().GetOwnerID()
|
tokenOwnerField := owner.NewIDFromV2(token.GetBody().GetOwnerID())
|
||||||
if tokenOwnerField != nil { // see bearer token owner field description
|
if tokenOwnerField != nil { // see bearer token owner field description
|
||||||
requestSenderKey := crypto.UnmarshalPublicKey(reqInfo.senderKey)
|
requestSenderKey := crypto.UnmarshalPublicKey(reqInfo.senderKey)
|
||||||
requestSenderWallet, err := owner.NEO3WalletFromPublicKey(requestSenderKey)
|
if !isOwnerFromKey(tokenOwnerField, requestSenderKey) {
|
||||||
if err != nil {
|
// todo: in this case we can issue all owner keys from neofs.id and check once again
|
||||||
return false
|
|
||||||
}
|
|
||||||
// the same issue as above
|
|
||||||
if !bytes.Equal(tokenOwnerField.GetValue(), requestSenderWallet.Bytes()) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,3 +666,20 @@ func isValidLifetime(lifetime *bearer.TokenLifetime, epoch uint64) bool {
|
||||||
// RFC 7519 sections 4.1.4, 4.1.5
|
// RFC 7519 sections 4.1.4, 4.1.5
|
||||||
return epoch >= lifetime.GetNbf() && epoch <= lifetime.GetExp()
|
return epoch >= lifetime.GetNbf() && epoch <= lifetime.GetExp()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isOwnerFromKey(id *owner.ID, key *ecdsa.PublicKey) bool {
|
||||||
|
if id == nil || key == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
wallet, err := owner.NEO3WalletFromPublicKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// here we compare `owner.ID -> wallet` with `wallet <- publicKey`
|
||||||
|
// consider making equal method on owner.ID structure
|
||||||
|
// we can compare .String() version of owners but don't think it is good idea
|
||||||
|
// binary comparison is better but MarshalBinary is more expensive
|
||||||
|
return bytes.Equal(id.ToV2().GetValue(), wallet.Bytes())
|
||||||
|
}
|
||||||
|
|
|
@ -201,15 +201,12 @@ func ownerFromToken(token *session.SessionToken) (*owner.ID, *ecdsa.PublicKey, e
|
||||||
|
|
||||||
// 2. Then check if session token owner issued the session token
|
// 2. Then check if session token owner issued the session token
|
||||||
tokenIssuerKey := crypto.UnmarshalPublicKey(token.GetSignature().GetKey())
|
tokenIssuerKey := crypto.UnmarshalPublicKey(token.GetSignature().GetKey())
|
||||||
tokenIssuerWallet, err := owner.NEO3WalletFromPublicKey(tokenIssuerKey)
|
tokenOwner := owner.NewIDFromV2(token.GetBody().GetOwnerID())
|
||||||
if err != nil {
|
|
||||||
return nil, nil, errors.Wrap(ErrMalformedRequest, "invalid token issuer key")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(token.GetBody().GetOwnerID().GetValue(), tokenIssuerWallet.Bytes()) {
|
if !isOwnerFromKey(tokenOwner, tokenIssuerKey) {
|
||||||
// todo: in this case we can issue all owner keys from neofs.id and check once again
|
// todo: in this case we can issue all owner keys from neofs.id and check once again
|
||||||
return nil, nil, errors.Wrap(ErrMalformedRequest, "invalid session token owner")
|
return nil, nil, errors.Wrap(ErrMalformedRequest, "invalid session token owner")
|
||||||
}
|
}
|
||||||
|
|
||||||
return owner.NewIDFromV2(token.GetBody().GetOwnerID()), tokenIssuerKey, nil
|
return tokenOwner, tokenIssuerKey, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue