ACLState refactoring
This commit is contained in:
parent
2273c94cf4
commit
5baa6dc856
@ -1,13 +0,0 @@
|
||||
package aclrecordproto
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys/symmetric"
|
||||
)
|
||||
|
||||
func AclReadKeyDerive(signKey []byte, encKey []byte) (*crypto.AESKey, error) {
|
||||
concBuf := make([]byte, 0, len(signKey)+len(encKey))
|
||||
concBuf = append(concBuf, signKey...)
|
||||
concBuf = append(concBuf, encKey...)
|
||||
return symmetric.DeriveFromBytes(concBuf)
|
||||
}
|
||||
@ -247,12 +247,11 @@ func (m *AclRecord) GetTimestamp() int64 {
|
||||
}
|
||||
|
||||
type AclRoot struct {
|
||||
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
|
||||
EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
|
||||
DerivationScheme string `protobuf:"bytes,4,opt,name=derivationScheme,proto3" json:"derivationScheme,omitempty"`
|
||||
CurrentReadKeyHash uint64 `protobuf:"varint,5,opt,name=currentReadKeyHash,proto3" json:"currentReadKeyHash,omitempty"`
|
||||
Timestamp int64 `protobuf:"varint,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,omitempty"`
|
||||
EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
|
||||
DerivationScheme string `protobuf:"bytes,4,opt,name=derivationScheme,proto3" json:"derivationScheme,omitempty"`
|
||||
Timestamp int64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
}
|
||||
|
||||
func (m *AclRoot) Reset() { *m = AclRoot{} }
|
||||
@ -316,13 +315,6 @@ func (m *AclRoot) GetDerivationScheme() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *AclRoot) GetCurrentReadKeyHash() uint64 {
|
||||
if m != nil {
|
||||
return m.CurrentReadKeyHash
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *AclRoot) GetTimestamp() int64 {
|
||||
if m != nil {
|
||||
return m.Timestamp
|
||||
@ -733,10 +725,9 @@ func (m *AclUserInvite) GetPermissions() AclUserPermissions {
|
||||
|
||||
type AclUserJoin struct {
|
||||
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryptionKey,proto3" json:"encryptionKey,omitempty"`
|
||||
AcceptSignature []byte `protobuf:"bytes,3,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"`
|
||||
AcceptPubKey []byte `protobuf:"bytes,4,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"`
|
||||
EncryptedReadKeys [][]byte `protobuf:"bytes,5,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
||||
AcceptSignature []byte `protobuf:"bytes,2,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"`
|
||||
AcceptPubKey []byte `protobuf:"bytes,3,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"`
|
||||
EncryptedReadKeys [][]byte `protobuf:"bytes,4,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
|
||||
}
|
||||
|
||||
func (m *AclUserJoin) Reset() { *m = AclUserJoin{} }
|
||||
@ -779,13 +770,6 @@ func (m *AclUserJoin) GetIdentity() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AclUserJoin) GetEncryptionKey() []byte {
|
||||
if m != nil {
|
||||
return m.EncryptionKey
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AclUserJoin) GetAcceptSignature() []byte {
|
||||
if m != nil {
|
||||
return m.AcceptSignature
|
||||
@ -1152,66 +1136,64 @@ func init() {
|
||||
}
|
||||
|
||||
var fileDescriptor_c8e9f754f34e929b = []byte{
|
||||
// 943 bytes of a gzipped FileDescriptorProto
|
||||
// 907 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4f, 0x6f, 0x1b, 0x45,
|
||||
0x14, 0xf7, 0xda, 0x49, 0x1c, 0x3f, 0xbb, 0x89, 0x33, 0x40, 0xbb, 0x8a, 0x8a, 0x15, 0xad, 0x40,
|
||||
0x8a, 0xaa, 0xca, 0x11, 0x06, 0x29, 0x55, 0x84, 0xa8, 0xdc, 0x52, 0x64, 0xb7, 0x42, 0xaa, 0x26,
|
||||
0x40, 0x51, 0x39, 0x4d, 0x66, 0x47, 0xf1, 0xd0, 0xf5, 0xee, 0x6a, 0x66, 0x6c, 0xe4, 0x4f, 0x01,
|
||||
0x37, 0xae, 0x1c, 0xf9, 0x28, 0x48, 0x5c, 0x72, 0x41, 0xe2, 0x88, 0x12, 0xf1, 0x11, 0xb8, 0xa3,
|
||||
0x99, 0xd9, 0xff, 0xeb, 0x58, 0x70, 0x80, 0x43, 0xe2, 0x9d, 0xf7, 0x7e, 0xef, 0xcd, 0xef, 0xfd,
|
||||
0xe6, 0xcd, 0xdb, 0x85, 0x8f, 0x69, 0x34, 0x9f, 0x47, 0xa1, 0x8c, 0x09, 0x65, 0x27, 0xd1, 0xc5,
|
||||
0xb7, 0x8c, 0xaa, 0x13, 0x42, 0x03, 0xfd, 0x27, 0x18, 0x8d, 0x84, 0x1f, 0x8b, 0x48, 0x45, 0x27,
|
||||
0xe6, 0xbf, 0xcc, 0xad, 0x43, 0x63, 0x40, 0x9d, 0xcc, 0xe0, 0xfd, 0xe4, 0x40, 0x0f, 0x93, 0xef,
|
||||
0xc6, 0x34, 0xc0, 0xc6, 0x80, 0x5c, 0x68, 0xc7, 0x64, 0x15, 0x44, 0xc4, 0x77, 0x9d, 0x23, 0xe7,
|
||||
0xb8, 0x87, 0xd3, 0x25, 0xba, 0x0f, 0x1d, 0xc9, 0x2f, 0x43, 0xa2, 0x16, 0x82, 0xb9, 0x4d, 0xe3,
|
||||
0xcb, 0x0d, 0xe8, 0x01, 0xf4, 0x09, 0xa5, 0x2c, 0x56, 0x91, 0x98, 0xfa, 0x2c, 0x54, 0x5c, 0xad,
|
||||
0xdc, 0x96, 0x01, 0xd5, 0xec, 0xe8, 0x21, 0x1c, 0xa4, 0xb6, 0xf3, 0x2c, 0xe3, 0x96, 0x01, 0xd7,
|
||||
0x1d, 0xde, 0x27, 0x80, 0x8a, 0x0c, 0x5f, 0x71, 0x35, 0x9b, 0x6e, 0xe2, 0xb9, 0x07, 0x4d, 0xee,
|
||||
0x1b, 0x82, 0x1d, 0xdc, 0xe4, 0xbe, 0xf7, 0xbd, 0x03, 0x9d, 0xbc, 0xbe, 0xbb, 0xb0, 0x13, 0x0b,
|
||||
0xb6, 0x9c, 0xda, 0xb0, 0x0e, 0x4e, 0x56, 0xe8, 0x10, 0x76, 0x79, 0xca, 0xdb, 0x16, 0x97, 0xad,
|
||||
0x11, 0x82, 0x2d, 0x9f, 0x28, 0x92, 0xd4, 0x63, 0x9e, 0xb5, 0x1a, 0x82, 0x11, 0xff, 0x05, 0x5b,
|
||||
0x4d, 0x7d, 0xc3, 0xbd, 0x83, 0x73, 0x83, 0xf6, 0x2a, 0x3e, 0x67, 0x52, 0x91, 0x79, 0xec, 0x6e,
|
||||
0x1f, 0x39, 0xc7, 0x2d, 0x9c, 0x1b, 0xbc, 0x3f, 0x1d, 0x68, 0x6b, 0x46, 0x51, 0xa4, 0x4a, 0xfb,
|
||||
0x3a, 0x95, 0x7d, 0x5d, 0x68, 0x9b, 0x13, 0x9e, 0xa6, 0xe5, 0xa4, 0x4b, 0xad, 0x36, 0x0b, 0xa9,
|
||||
0x58, 0xc5, 0x8a, 0xf9, 0xd8, 0xee, 0x9a, 0xaa, 0x5d, 0xb5, 0x6b, 0xac, 0xcf, 0x04, 0x5f, 0x12,
|
||||
0xc5, 0xa3, 0xf0, 0x9c, 0xce, 0xd8, 0x9c, 0x25, 0x84, 0x6b, 0x76, 0x34, 0x04, 0x44, 0x17, 0x42,
|
||||
0xb0, 0x50, 0x25, 0xd1, 0x13, 0x22, 0x67, 0xa6, 0x80, 0x2d, 0xbc, 0xc6, 0x53, 0xae, 0x73, 0xa7,
|
||||
0x5a, 0xe7, 0x6f, 0x4d, 0xd8, 0x1f, 0xd3, 0xe0, 0x69, 0x14, 0x2a, 0x16, 0xaa, 0xaf, 0x48, 0xb0,
|
||||
0x60, 0xe8, 0x03, 0x68, 0x2f, 0x24, 0x13, 0x63, 0xdf, 0x1e, 0x40, 0x77, 0xf4, 0xce, 0x30, 0x6f,
|
||||
0xcf, 0x31, 0x0d, 0xbe, 0xb4, 0xce, 0x49, 0x03, 0xa7, 0x38, 0x74, 0x06, 0xa0, 0x1f, 0x31, 0x9b,
|
||||
0x47, 0x4b, 0xdb, 0x79, 0xdd, 0x91, 0x5b, 0x8f, 0xb2, 0xfe, 0x49, 0x03, 0x17, 0xd0, 0xe8, 0x6b,
|
||||
0x78, 0x5b, 0xaf, 0x5e, 0x32, 0x31, 0xe7, 0x52, 0xf2, 0x28, 0x7c, 0x3a, 0x23, 0xe1, 0x25, 0x33,
|
||||
0x62, 0x75, 0x47, 0x5e, 0x3d, 0x4b, 0x15, 0x39, 0x69, 0xe0, 0xb5, 0x19, 0x52, 0x56, 0xd3, 0x70,
|
||||
0xc9, 0x95, 0x15, 0x74, 0x2d, 0x2b, 0xeb, 0x4f, 0x59, 0xd9, 0x15, 0xfa, 0x08, 0x76, 0xf5, 0xea,
|
||||
0x79, 0xc4, 0x43, 0x23, 0x6e, 0x77, 0x74, 0xb7, 0x1e, 0xa9, 0xbd, 0x93, 0x06, 0xce, 0x90, 0x4f,
|
||||
0xda, 0xb0, 0xbd, 0xd4, 0x1a, 0x7a, 0xcf, 0x4c, 0xfb, 0x7c, 0xaa, 0xdb, 0xf0, 0x0c, 0x80, 0x64,
|
||||
0x0a, 0xbb, 0xce, 0x51, 0xeb, 0xb8, 0x3b, 0x3a, 0x2c, 0xe7, 0x2a, 0xca, 0x8f, 0x0b, 0x68, 0xef,
|
||||
0x2f, 0x07, 0x76, 0xc7, 0x34, 0x38, 0x57, 0x44, 0x31, 0x34, 0x00, 0xc8, 0xda, 0x57, 0x9a, 0x44,
|
||||
0x1d, 0x5c, 0xb0, 0xa0, 0x53, 0x5b, 0xae, 0x01, 0x4b, 0xb7, 0x69, 0x36, 0xba, 0x57, 0x27, 0x6d,
|
||||
0xfc, 0xb8, 0x00, 0x45, 0x67, 0xd0, 0xe6, 0xa6, 0x6a, 0xe9, 0xb6, 0x4c, 0xd4, 0x51, 0x39, 0xca,
|
||||
0xc0, 0x86, 0x56, 0x18, 0xf9, 0x2c, 0x54, 0x62, 0x85, 0xd3, 0x80, 0xc3, 0x2f, 0xa0, 0x57, 0x74,
|
||||
0xa0, 0x3e, 0xb4, 0xde, 0xb0, 0x55, 0x72, 0x73, 0xf5, 0x23, 0x1a, 0x26, 0x9a, 0xdc, 0xde, 0x16,
|
||||
0x36, 0x01, 0xb6, 0xb0, 0xb3, 0xe6, 0x23, 0xc7, 0x7b, 0x03, 0xbd, 0x22, 0xdb, 0x8d, 0x57, 0xf0,
|
||||
0x31, 0x74, 0xe3, 0xec, 0xe4, 0xa5, 0xd9, 0x65, 0x6f, 0xf4, 0xee, 0xa6, 0xb6, 0x91, 0xb8, 0x18,
|
||||
0xe1, 0xfd, 0xe8, 0x00, 0xe4, 0x6d, 0xbd, 0x71, 0xaf, 0x87, 0x70, 0x50, 0xbd, 0xbc, 0x56, 0xe9,
|
||||
0x1e, 0xae, 0x3b, 0xaa, 0xcc, 0x5a, 0xff, 0x9a, 0xd9, 0xcf, 0x0e, 0xdc, 0x29, 0x69, 0x84, 0x8e,
|
||||
0x61, 0xdf, 0x8e, 0xdf, 0x97, 0x8b, 0x8b, 0x80, 0xd3, 0x17, 0x2c, 0xe5, 0x58, 0x35, 0xff, 0xdf,
|
||||
0x54, 0x7f, 0x75, 0xa0, 0x5b, 0xb8, 0x15, 0x1b, 0x55, 0x7c, 0x0f, 0xee, 0x24, 0x0c, 0x78, 0x14,
|
||||
0xea, 0x12, 0xec, 0x34, 0x2f, 0x1b, 0xf3, 0x52, 0xf3, 0x17, 0x50, 0xab, 0x58, 0x6a, 0x66, 0x46,
|
||||
0x1e, 0xf4, 0xb2, 0xea, 0x75, 0x3a, 0xfb, 0x9e, 0x2a, 0xd9, 0xd6, 0xcb, 0xb1, 0x7d, 0x8b, 0x1c,
|
||||
0x9e, 0xcc, 0x74, 0x4f, 0x86, 0xd4, 0xa6, 0x72, 0x3e, 0x83, 0xfd, 0xe4, 0x16, 0x62, 0x16, 0x07,
|
||||
0x84, 0x66, 0x97, 0xef, 0x7e, 0x59, 0x3f, 0x5c, 0x02, 0xe1, 0x6a, 0x90, 0xf7, 0x0d, 0x1c, 0xd4,
|
||||
0x50, 0x1b, 0x37, 0x5e, 0xf7, 0x8a, 0x69, 0xae, 0x7f, 0xc5, 0x78, 0x4b, 0xb8, 0x77, 0xcb, 0xf8,
|
||||
0xfc, 0x6f, 0x2f, 0xd7, 0x73, 0xd8, 0xd3, 0x13, 0x64, 0x15, 0xd2, 0xcf, 0x99, 0x94, 0xe4, 0x92,
|
||||
0xa1, 0x47, 0xd0, 0xa6, 0xd9, 0x30, 0xd4, 0x13, 0x61, 0x50, 0x99, 0x36, 0xab, 0x90, 0x96, 0x06,
|
||||
0x62, 0x0a, 0xf7, 0x5e, 0xc3, 0x5b, 0x6b, 0xfc, 0x66, 0xc0, 0xfa, 0xbe, 0xfd, 0x78, 0x90, 0x49,
|
||||
0xce, 0xca, 0x94, 0x19, 0x67, 0x7e, 0x3d, 0xe6, 0x73, 0x74, 0x3e, 0xb0, 0x27, 0xe6, 0xc4, 0x73,
|
||||
0x1c, 0x3a, 0x85, 0xb6, 0xc8, 0x52, 0xea, 0xd3, 0x2c, 0x56, 0x5d, 0xff, 0xda, 0xc1, 0x29, 0xfa,
|
||||
0xc1, 0x29, 0xa0, 0xba, 0x28, 0xa8, 0x03, 0xdb, 0x63, 0x7f, 0xce, 0xc3, 0x7e, 0x03, 0x01, 0xec,
|
||||
0xbc, 0x12, 0x5c, 0x31, 0xd1, 0x77, 0xf4, 0xb3, 0x3e, 0x21, 0x26, 0xfa, 0xcd, 0x27, 0x8f, 0x7f,
|
||||
0xb9, 0x1e, 0x38, 0x57, 0xd7, 0x03, 0xe7, 0x8f, 0xeb, 0x81, 0xf3, 0xc3, 0xcd, 0xa0, 0x71, 0x75,
|
||||
0x33, 0x68, 0xfc, 0x7e, 0x33, 0x68, 0xbc, 0x7e, 0xff, 0x1f, 0x7d, 0x4b, 0x5e, 0xec, 0x98, 0x9f,
|
||||
0x0f, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xca, 0x88, 0xea, 0x1c, 0x7b, 0x0a, 0x00, 0x00,
|
||||
0x14, 0xf7, 0xd8, 0x49, 0x1c, 0x3f, 0x9b, 0xc4, 0x19, 0xa0, 0x5d, 0x45, 0xc5, 0x8a, 0x56, 0x42,
|
||||
0x8a, 0xaa, 0x2a, 0x11, 0x06, 0x29, 0x55, 0x84, 0xa8, 0xdc, 0x52, 0x64, 0xb7, 0x42, 0xaa, 0x26,
|
||||
0x40, 0x51, 0x39, 0x4d, 0x66, 0x47, 0xc9, 0xd0, 0xf5, 0xee, 0x6a, 0x66, 0x6c, 0xe4, 0x4f, 0x01,
|
||||
0x37, 0xae, 0x5c, 0x90, 0xf8, 0x02, 0x7c, 0x07, 0x8e, 0xb9, 0x20, 0x71, 0x44, 0xc9, 0x67, 0xe0,
|
||||
0x8e, 0x66, 0xc6, 0xfb, 0xdf, 0x31, 0x70, 0xa0, 0x87, 0xc4, 0x3b, 0xef, 0xfd, 0xe6, 0xcd, 0xef,
|
||||
0xfd, 0xe6, 0xbd, 0xb7, 0x0b, 0x1f, 0xb3, 0x78, 0x3a, 0x8d, 0x23, 0x95, 0x50, 0xc6, 0x8f, 0xe3,
|
||||
0xf3, 0x6f, 0x39, 0xd3, 0xc7, 0x94, 0x85, 0xe6, 0x4f, 0x72, 0x16, 0xcb, 0x20, 0x91, 0xb1, 0x8e,
|
||||
0x8f, 0xed, 0x7f, 0x95, 0x5b, 0x8f, 0xac, 0x01, 0x77, 0x32, 0x83, 0xff, 0x13, 0x82, 0x1e, 0xa1,
|
||||
0xdf, 0x8d, 0x58, 0x48, 0xac, 0x01, 0x7b, 0xd0, 0x4e, 0xe8, 0x22, 0x8c, 0x69, 0xe0, 0xa1, 0x03,
|
||||
0x74, 0xd8, 0x23, 0xe9, 0x12, 0xdf, 0x83, 0x8e, 0x12, 0x17, 0x11, 0xd5, 0x33, 0xc9, 0xbd, 0xa6,
|
||||
0xf5, 0xe5, 0x06, 0x7c, 0x1f, 0xfa, 0x94, 0x31, 0x9e, 0xe8, 0x58, 0x4e, 0x02, 0x1e, 0x69, 0xa1,
|
||||
0x17, 0x5e, 0xcb, 0x82, 0x6a, 0x76, 0xfc, 0x00, 0xf6, 0x52, 0xdb, 0x59, 0x16, 0x71, 0xc3, 0x82,
|
||||
0xeb, 0x0e, 0xff, 0x13, 0xc0, 0x45, 0x86, 0x2f, 0x85, 0xbe, 0x9c, 0xac, 0xe3, 0xb9, 0x03, 0x4d,
|
||||
0x11, 0x58, 0x82, 0x1d, 0xd2, 0x14, 0x81, 0xff, 0x3d, 0x82, 0x4e, 0x9e, 0xdf, 0x1d, 0xd8, 0x4a,
|
||||
0x24, 0x9f, 0x4f, 0xdc, 0xb6, 0x0e, 0x59, 0xae, 0xf0, 0x3e, 0x6c, 0x8b, 0x94, 0xb7, 0x4b, 0x2e,
|
||||
0x5b, 0x63, 0x0c, 0x1b, 0x01, 0xd5, 0x74, 0x99, 0x8f, 0x7d, 0x36, 0x6a, 0x48, 0x4e, 0x83, 0xe7,
|
||||
0x7c, 0x31, 0x09, 0x2c, 0xf7, 0x0e, 0xc9, 0x0d, 0xc6, 0xab, 0xc5, 0x94, 0x2b, 0x4d, 0xa7, 0x89,
|
||||
0xb7, 0x79, 0x80, 0x0e, 0x5b, 0x24, 0x37, 0xf8, 0xbf, 0x22, 0x68, 0x1b, 0x46, 0x71, 0xac, 0x4b,
|
||||
0xe7, 0xa2, 0xca, 0xb9, 0x1e, 0xb4, 0xed, 0x0d, 0x4f, 0xd2, 0x74, 0xd2, 0xa5, 0x51, 0x9b, 0x47,
|
||||
0x4c, 0x2e, 0x12, 0xcd, 0x03, 0xe2, 0x4e, 0x4d, 0xd5, 0xae, 0xda, 0x0d, 0x36, 0xe0, 0x52, 0xcc,
|
||||
0xa9, 0x16, 0x71, 0x74, 0xc6, 0x2e, 0xf9, 0x94, 0x2f, 0x09, 0xd7, 0xec, 0xff, 0xc0, 0xfb, 0xf7,
|
||||
0x26, 0xec, 0x8e, 0x58, 0xf8, 0x24, 0x8e, 0x34, 0x8f, 0xf4, 0x57, 0x34, 0x9c, 0x71, 0xfc, 0x01,
|
||||
0xb4, 0x67, 0x8a, 0xcb, 0x51, 0xe0, 0x04, 0xed, 0x0e, 0xdf, 0x3d, 0xca, 0xcb, 0x6d, 0xc4, 0xc2,
|
||||
0x2f, 0x9d, 0x73, 0xdc, 0x20, 0x29, 0x0e, 0x9f, 0x02, 0x98, 0x47, 0xc2, 0xa7, 0xf1, 0xdc, 0x55,
|
||||
0x52, 0x77, 0xe8, 0xd5, 0x77, 0x39, 0xff, 0xb8, 0x41, 0x0a, 0x68, 0xfc, 0x35, 0xbc, 0x63, 0x56,
|
||||
0x2f, 0xb8, 0x9c, 0x0a, 0xa5, 0x44, 0x1c, 0x3d, 0xb9, 0xa4, 0xd1, 0x05, 0xb7, 0xc9, 0x77, 0x87,
|
||||
0x7e, 0x3d, 0x4a, 0x15, 0x39, 0x6e, 0x90, 0x95, 0x11, 0x52, 0x56, 0x93, 0x68, 0x2e, 0xb4, 0x13,
|
||||
0x68, 0x25, 0x2b, 0xe7, 0x4f, 0x59, 0xb9, 0x15, 0xfe, 0x08, 0xb6, 0xcd, 0xea, 0x59, 0x2c, 0x22,
|
||||
0xab, 0x5a, 0x77, 0x78, 0xa7, 0xbe, 0xd3, 0x78, 0xc7, 0x0d, 0x92, 0x21, 0x1f, 0xb7, 0x61, 0x73,
|
||||
0x6e, 0x34, 0xf4, 0x9f, 0xda, 0x72, 0xf8, 0xd4, 0x94, 0xd5, 0x29, 0x00, 0xcd, 0x14, 0xf6, 0xd0,
|
||||
0x41, 0xeb, 0xb0, 0x3b, 0xdc, 0x2f, 0xc7, 0x2a, 0xca, 0x4f, 0x0a, 0x68, 0xff, 0x2f, 0x04, 0xdb,
|
||||
0x23, 0x16, 0x9e, 0x69, 0xaa, 0x39, 0x1e, 0x00, 0x64, 0xe5, 0xa8, 0x6c, 0xa0, 0x0e, 0x29, 0x58,
|
||||
0xf0, 0x89, 0x4b, 0xd7, 0x82, 0x95, 0xd7, 0xb4, 0x07, 0xdd, 0xad, 0x93, 0xb6, 0x7e, 0x52, 0x80,
|
||||
0xe2, 0x53, 0x68, 0x0b, 0x9b, 0xb5, 0xf2, 0x5a, 0x76, 0xd7, 0x41, 0x79, 0x97, 0x85, 0x1d, 0x39,
|
||||
0x61, 0xd4, 0xd3, 0x48, 0xcb, 0x05, 0x49, 0x37, 0xec, 0x7f, 0x01, 0xbd, 0xa2, 0x03, 0xf7, 0xa1,
|
||||
0xf5, 0x9a, 0x2f, 0x96, 0x9d, 0x68, 0x1e, 0xf1, 0xd1, 0x52, 0x93, 0xdb, 0xcb, 0xc2, 0x05, 0x20,
|
||||
0x0e, 0x76, 0xda, 0x7c, 0x88, 0xfc, 0xd7, 0xd0, 0x2b, 0xb2, 0x5d, 0xdb, 0x52, 0x8f, 0xa0, 0x9b,
|
||||
0x64, 0x37, 0xaf, 0xec, 0x29, 0x3b, 0xc3, 0xf7, 0xd6, 0x95, 0x8d, 0x22, 0xc5, 0x1d, 0xfe, 0x8f,
|
||||
0x08, 0x20, 0x2f, 0xeb, 0xb5, 0x67, 0x3d, 0x80, 0xbd, 0x6a, 0x33, 0x3a, 0xa5, 0x7b, 0xa4, 0xee,
|
||||
0xa8, 0x32, 0x6b, 0xfd, 0x67, 0x66, 0xbf, 0x20, 0x78, 0xab, 0xa4, 0x11, 0x3e, 0x84, 0x5d, 0x37,
|
||||
0x4e, 0x5f, 0xcc, 0xce, 0x43, 0xc1, 0x9e, 0xf3, 0x94, 0x63, 0xd5, 0xfc, 0xa6, 0xa9, 0xfe, 0x8c,
|
||||
0xa0, 0x5b, 0xe8, 0x8a, 0xb5, 0x2a, 0x66, 0x49, 0x9c, 0x55, 0x5e, 0x3e, 0x55, 0x33, 0xf6, 0xa1,
|
||||
0x97, 0xe5, 0x95, 0x0f, 0xc4, 0x92, 0x6d, 0x75, 0xa2, 0x1b, 0xb7, 0x24, 0xea, 0xab, 0x4c, 0xd1,
|
||||
0xe5, 0xf8, 0x59, 0x47, 0xf4, 0x33, 0xd8, 0x5d, 0xf6, 0x17, 0xe1, 0x49, 0x48, 0x59, 0xd6, 0x56,
|
||||
0xf7, 0xca, 0xca, 0x90, 0x12, 0x88, 0x54, 0x37, 0xf9, 0xdf, 0xc0, 0x5e, 0x0d, 0xb5, 0xf6, 0xe0,
|
||||
0x55, 0x2f, 0x83, 0xe6, 0xea, 0x97, 0x81, 0x3f, 0x87, 0xbb, 0xb7, 0x0c, 0xc6, 0xff, 0xb7, 0x6d,
|
||||
0x9e, 0xc1, 0x8e, 0x99, 0x0d, 0x8b, 0x88, 0x7d, 0xce, 0x95, 0xa2, 0x17, 0x1c, 0x3f, 0x84, 0x36,
|
||||
0xcb, 0xc6, 0x9c, 0xe9, 0xf5, 0x41, 0x65, 0x8e, 0x2c, 0x22, 0x56, 0x1a, 0x75, 0x29, 0xdc, 0x7f,
|
||||
0x05, 0x6f, 0xaf, 0xf0, 0xdb, 0xd1, 0x19, 0x04, 0xee, 0x35, 0xaf, 0x96, 0x31, 0x2b, 0xf3, 0x63,
|
||||
0x94, 0xf9, 0xcd, 0x00, 0xcf, 0xd1, 0xf9, 0x28, 0x1e, 0xdb, 0x1b, 0xcf, 0x71, 0xf8, 0x04, 0xda,
|
||||
0x32, 0x0b, 0x69, 0x6e, 0xb3, 0x98, 0x75, 0xfd, 0xbb, 0x84, 0xa4, 0xe8, 0xfb, 0x27, 0x80, 0xeb,
|
||||
0xa2, 0xe0, 0x0e, 0x6c, 0x8e, 0x82, 0xa9, 0x88, 0xfa, 0x0d, 0x0c, 0xb0, 0xf5, 0x52, 0x0a, 0xcd,
|
||||
0x65, 0x1f, 0x99, 0x67, 0x73, 0x43, 0x5c, 0xf6, 0x9b, 0x8f, 0x1f, 0xfd, 0x76, 0x3d, 0x40, 0x57,
|
||||
0xd7, 0x03, 0xf4, 0xe7, 0xf5, 0x00, 0xfd, 0x70, 0x33, 0x68, 0x5c, 0xdd, 0x0c, 0x1a, 0x7f, 0xdc,
|
||||
0x0c, 0x1a, 0xaf, 0xde, 0xff, 0x57, 0x5f, 0x7d, 0xe7, 0x5b, 0xf6, 0xe7, 0xc3, 0xbf, 0x03, 0x00,
|
||||
0x00, 0xff, 0xff, 0x34, 0xb4, 0xa5, 0x8e, 0x25, 0x0a, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *RawAclRecord) Marshal() (dAtA []byte, err error) {
|
||||
@ -1381,11 +1363,6 @@ func (m *AclRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
if m.Timestamp != 0 {
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp))
|
||||
i--
|
||||
dAtA[i] = 0x30
|
||||
}
|
||||
if m.CurrentReadKeyHash != 0 {
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(m.CurrentReadKeyHash))
|
||||
i--
|
||||
dAtA[i] = 0x28
|
||||
}
|
||||
if len(m.DerivationScheme) > 0 {
|
||||
@ -1814,7 +1791,7 @@ func (m *AclUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
copy(dAtA[i:], m.EncryptedReadKeys[iNdEx])
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx])))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
dAtA[i] = 0x22
|
||||
}
|
||||
}
|
||||
if len(m.AcceptPubKey) > 0 {
|
||||
@ -1822,20 +1799,13 @@ func (m *AclUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
copy(dAtA[i:], m.AcceptPubKey)
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptPubKey)))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.AcceptSignature) > 0 {
|
||||
i -= len(m.AcceptSignature)
|
||||
copy(dAtA[i:], m.AcceptSignature)
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptSignature)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.EncryptionKey) > 0 {
|
||||
i -= len(m.EncryptionKey)
|
||||
copy(dAtA[i:], m.EncryptionKey)
|
||||
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptionKey)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.Identity) > 0 {
|
||||
@ -2192,9 +2162,6 @@ func (m *AclRoot) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovAclrecord(uint64(l))
|
||||
}
|
||||
if m.CurrentReadKeyHash != 0 {
|
||||
n += 1 + sovAclrecord(uint64(m.CurrentReadKeyHash))
|
||||
}
|
||||
if m.Timestamp != 0 {
|
||||
n += 1 + sovAclrecord(uint64(m.Timestamp))
|
||||
}
|
||||
@ -2392,10 +2359,6 @@ func (m *AclUserJoin) Size() (n int) {
|
||||
if l > 0 {
|
||||
n += 1 + l + sovAclrecord(uint64(l))
|
||||
}
|
||||
l = len(m.EncryptionKey)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovAclrecord(uint64(l))
|
||||
}
|
||||
l = len(m.AcceptSignature)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovAclrecord(uint64(l))
|
||||
@ -3188,25 +3151,6 @@ func (m *AclRoot) Unmarshal(dAtA []byte) error {
|
||||
m.DerivationScheme = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field CurrentReadKeyHash", wireType)
|
||||
}
|
||||
m.CurrentReadKeyHash = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAclrecord
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.CurrentReadKeyHash |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType)
|
||||
}
|
||||
@ -4237,40 +4181,6 @@ func (m *AclUserJoin) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field EncryptionKey", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowAclrecord
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthAclrecord
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthAclrecord
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.EncryptionKey = append(m.EncryptionKey[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.EncryptionKey == nil {
|
||||
m.EncryptionKey = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AcceptSignature", wireType)
|
||||
}
|
||||
@ -4304,7 +4214,7 @@ func (m *AclUserJoin) Unmarshal(dAtA []byte) error {
|
||||
m.AcceptSignature = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AcceptPubKey", wireType)
|
||||
}
|
||||
@ -4338,7 +4248,7 @@ func (m *AclUserJoin) Unmarshal(dAtA []byte) error {
|
||||
m.AcceptPubKey = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType)
|
||||
}
|
||||
|
||||
@ -27,8 +27,7 @@ message AclRoot {
|
||||
string spaceId = 2;
|
||||
bytes encryptedReadKey = 3;
|
||||
string derivationScheme = 4;
|
||||
uint64 currentReadKeyHash = 5;
|
||||
int64 timestamp = 6;
|
||||
int64 timestamp = 5;
|
||||
}
|
||||
|
||||
message AclContentValue {
|
||||
|
||||
@ -2,129 +2,131 @@ package list
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/util/cidutil"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"time"
|
||||
)
|
||||
|
||||
// remove interface
|
||||
type AclRecordBuilder interface {
|
||||
ConvertFromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error)
|
||||
BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error)
|
||||
FromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error)
|
||||
}
|
||||
|
||||
type aclRecordBuilder struct {
|
||||
id string
|
||||
keychain *keychain.Keychain
|
||||
id string
|
||||
keyStorage crypto.KeyStorage
|
||||
}
|
||||
|
||||
func newAclRecordBuilder(id string, keychain *keychain.Keychain) AclRecordBuilder {
|
||||
func newAclRecordBuilder(id string, keyStorage crypto.KeyStorage) AclRecordBuilder {
|
||||
return &aclRecordBuilder{
|
||||
id: id,
|
||||
keychain: keychain,
|
||||
id: id,
|
||||
keyStorage: keyStorage,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error) {
|
||||
acceptPrivKey, err := crypto.NewSigningEd25519PrivKeyFromBytes(acceptPrivKeyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
acceptPubKeyBytes, err := acceptPrivKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
encSymKey, err := crypto.UnmarshallAESKey(encSymKeyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// TODO: update with new logic
|
||||
//func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error) {
|
||||
// acceptPrivKey, err := crypto.NewSigningEd25519PrivKeyFromBytes(acceptPrivKeyBytes)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// acceptPubKeyBytes, err := acceptPrivKey.GetPublic().Raw()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// encSymKey, err := crypto.UnmarshallAESKey(encSymKeyBytes)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// invite, err := state.Invite(acceptPubKeyBytes)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// encPrivKey, signPrivKey := state.UserKeys()
|
||||
// var symKeys [][]byte
|
||||
// for _, rk := range invite.EncryptedReadKeys {
|
||||
// dec, err := encSymKey.Decrypt(rk)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// newEnc, err := encPrivKey.GetPublic().Encrypt(dec)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// symKeys = append(symKeys, newEnc)
|
||||
// }
|
||||
// idSignature, err := acceptPrivKey.Sign(state.Identity())
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// encPubKeyBytes, err := encPrivKey.GetPublic().Raw()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// userJoin := &aclrecordproto.AclUserJoin{
|
||||
// Identity: state.Identity(),
|
||||
// EncryptionKey: encPubKeyBytes,
|
||||
// AcceptSignature: idSignature,
|
||||
// AcceptPubKey: acceptPubKeyBytes,
|
||||
// EncryptedReadKeys: symKeys,
|
||||
// }
|
||||
// aclData := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{
|
||||
// {Value: &aclrecordproto.AclContentValue_UserJoin{UserJoin: userJoin}},
|
||||
// }}
|
||||
// marshalledJoin, err := aclData.Marshal()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// aclRecord := &aclrecordproto.AclRecord{
|
||||
// PrevId: state.LastRecordId(),
|
||||
// Identity: state.Identity(),
|
||||
// Data: marshalledJoin,
|
||||
// CurrentReadKeyHash: state.CurrentReadKeyId(),
|
||||
// Timestamp: time.Now().Unix(),
|
||||
// }
|
||||
// marshalledRecord, err := aclRecord.Marshal()
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// recSignature, err := signPrivKey.Sign(marshalledRecord)
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
// rec = &aclrecordproto.RawAclRecord{
|
||||
// Payload: marshalledRecord,
|
||||
// Signature: recSignature,
|
||||
// }
|
||||
// return
|
||||
//}
|
||||
|
||||
invite, err := state.Invite(acceptPubKeyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
encPrivKey, signPrivKey := state.UserKeys()
|
||||
var symKeys [][]byte
|
||||
for _, rk := range invite.EncryptedReadKeys {
|
||||
dec, err := encSymKey.Decrypt(rk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newEnc, err := encPrivKey.GetPublic().Encrypt(dec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
symKeys = append(symKeys, newEnc)
|
||||
}
|
||||
idSignature, err := acceptPrivKey.Sign(state.Identity())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
encPubKeyBytes, err := encPrivKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
userJoin := &aclrecordproto.AclUserJoin{
|
||||
Identity: state.Identity(),
|
||||
EncryptionKey: encPubKeyBytes,
|
||||
AcceptSignature: idSignature,
|
||||
AcceptPubKey: acceptPubKeyBytes,
|
||||
EncryptedReadKeys: symKeys,
|
||||
}
|
||||
aclData := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{
|
||||
{Value: &aclrecordproto.AclContentValue_UserJoin{UserJoin: userJoin}},
|
||||
}}
|
||||
marshalledJoin, err := aclData.Marshal()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
aclRecord := &aclrecordproto.AclRecord{
|
||||
PrevId: state.LastRecordId(),
|
||||
Identity: state.Identity(),
|
||||
Data: marshalledJoin,
|
||||
CurrentReadKeyHash: state.CurrentReadKeyHash(),
|
||||
Timestamp: time.Now().Unix(),
|
||||
}
|
||||
marshalledRecord, err := aclRecord.Marshal()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
recSignature, err := signPrivKey.Sign(marshalledRecord)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rec = &aclrecordproto.RawAclRecord{
|
||||
Payload: marshalledRecord,
|
||||
Signature: recSignature,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (a *aclRecordBuilder) ConvertFromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) {
|
||||
rawRec := &aclrecordproto.RawAclRecord{}
|
||||
func (a *aclRecordBuilder) FromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) {
|
||||
var (
|
||||
rawRec = &aclrecordproto.RawAclRecord{}
|
||||
pubKey crypto.PubKey
|
||||
)
|
||||
err = proto.Unmarshal(rawIdRecord.Payload, rawRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if rawIdRecord.Id == a.id {
|
||||
aclRoot := &aclrecordproto.AclRoot{}
|
||||
err = proto.Unmarshal(rawRec.Payload, aclRoot)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pubKey, err = a.keyStorage.PubKeyFromProto(aclRoot.Identity)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rec = &AclRecord{
|
||||
Id: rawIdRecord.Id,
|
||||
CurrentReadKeyHash: aclRoot.CurrentReadKeyHash,
|
||||
Timestamp: aclRoot.Timestamp,
|
||||
Signature: rawRec.Signature,
|
||||
Identity: aclRoot.Identity,
|
||||
Model: aclRoot,
|
||||
Id: rawIdRecord.Id,
|
||||
ReadKeyId: rawIdRecord.Id,
|
||||
Timestamp: aclRoot.Timestamp,
|
||||
Signature: rawRec.Signature,
|
||||
Identity: pubKey,
|
||||
Model: aclRoot,
|
||||
}
|
||||
} else {
|
||||
aclRecord := &aclrecordproto.AclRecord{}
|
||||
@ -132,34 +134,31 @@ func (a *aclRecordBuilder) ConvertFromRaw(rawIdRecord *aclrecordproto.RawAclReco
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
pubKey, err = a.keyStorage.PubKeyFromProto(aclRecord.Identity)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
rec = &AclRecord{
|
||||
Id: rawIdRecord.Id,
|
||||
PrevId: aclRecord.PrevId,
|
||||
CurrentReadKeyHash: aclRecord.CurrentReadKeyHash,
|
||||
Timestamp: aclRecord.Timestamp,
|
||||
Data: aclRecord.Data,
|
||||
Signature: rawRec.Signature,
|
||||
Identity: aclRecord.Identity,
|
||||
Id: rawIdRecord.Id,
|
||||
PrevId: aclRecord.PrevId,
|
||||
ReadKeyId: aclRecord.ReadKeyId,
|
||||
Timestamp: aclRecord.Timestamp,
|
||||
Data: aclRecord.Data,
|
||||
Signature: rawRec.Signature,
|
||||
Identity: pubKey,
|
||||
}
|
||||
}
|
||||
|
||||
err = verifyRaw(a.keychain, rawRec, rawIdRecord, rec.Identity)
|
||||
err = verifyRaw(pubKey, rawRec, rawIdRecord)
|
||||
return
|
||||
}
|
||||
|
||||
func verifyRaw(
|
||||
keychain *keychain.Keychain,
|
||||
pubKey crypto.PubKey,
|
||||
rawRec *aclrecordproto.RawAclRecord,
|
||||
recWithId *aclrecordproto.RawAclRecordWithId,
|
||||
identity []byte) (err error) {
|
||||
identityKey, err := keychain.GetOrAdd(string(identity))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
recWithId *aclrecordproto.RawAclRecordWithId) (err error) {
|
||||
// verifying signature
|
||||
res, err := identityKey.Verify(rawRec.Payload, rawRec.Signature)
|
||||
res, err := pubKey.Verify(rawRec.Payload, rawRec.Signature)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,18 +1,13 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
|
||||
"github.com/anytypeio/any-sync/app/logger"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"github.com/anytypeio/any-sync/util/keys"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/encryptionkey"
|
||||
"github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
@ -36,86 +31,80 @@ var (
|
||||
)
|
||||
|
||||
type UserPermissionPair struct {
|
||||
Identity string
|
||||
Identity crypto.PubKey
|
||||
Permission aclrecordproto.AclUserPermissions
|
||||
}
|
||||
|
||||
type AclState struct {
|
||||
id string
|
||||
currentReadKeyHash uint64
|
||||
userReadKeys map[uint64]*crypto.AESKey
|
||||
userStates map[string]*aclrecordproto.AclUserState
|
||||
userInvites map[string]*aclrecordproto.AclUserInvite
|
||||
encryptionKey encryptionkey.PrivKey
|
||||
signingKey signingkey.PrivKey
|
||||
totalReadKeys int
|
||||
id string
|
||||
currentReadKeyId string
|
||||
userReadKeys map[string]crypto.SymKey
|
||||
userStates map[string]AclUserState
|
||||
statesAtRecord map[string][]AclUserState
|
||||
//userInvites map[string]*aclrecordproto.AclUserInvite
|
||||
key crypto.PrivKey
|
||||
pubKey crypto.PubKey
|
||||
keyStore crypto.KeyStorage
|
||||
totalReadKeys int
|
||||
|
||||
identity string
|
||||
permissionsAtRecord map[string][]UserPermissionPair
|
||||
lastRecordId string
|
||||
lastRecordId string
|
||||
|
||||
keychain *keychain.Keychain
|
||||
}
|
||||
|
||||
func newAclStateWithKeys(
|
||||
id string,
|
||||
signingKey signingkey.PrivKey,
|
||||
encryptionKey encryptionkey.PrivKey) (*AclState, error) {
|
||||
identity, err := signingKey.GetPublic().Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key crypto.PrivKey) (*AclState, error) {
|
||||
return &AclState{
|
||||
id: id,
|
||||
identity: string(identity),
|
||||
signingKey: signingKey,
|
||||
encryptionKey: encryptionKey,
|
||||
userReadKeys: make(map[uint64]*crypto.AESKey),
|
||||
userStates: make(map[string]*aclrecordproto.AclUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
id: id,
|
||||
key: key,
|
||||
pubKey: key.GetPublic(),
|
||||
userReadKeys: make(map[string]crypto.SymKey),
|
||||
userStates: make(map[string]AclUserState),
|
||||
statesAtRecord: make(map[string][]AclUserState),
|
||||
//userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func newAclState(id string) *AclState {
|
||||
return &AclState{
|
||||
id: id,
|
||||
userReadKeys: make(map[uint64]*crypto.AESKey),
|
||||
userStates: make(map[string]*aclrecordproto.AclUserState),
|
||||
userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
permissionsAtRecord: make(map[string][]UserPermissionPair),
|
||||
id: id,
|
||||
userReadKeys: make(map[string]crypto.SymKey),
|
||||
userStates: make(map[string]AclUserState),
|
||||
statesAtRecord: make(map[string][]AclUserState),
|
||||
//userInvites: make(map[string]*aclrecordproto.AclUserInvite),
|
||||
}
|
||||
}
|
||||
|
||||
func (st *AclState) CurrentReadKeyHash() uint64 {
|
||||
return st.currentReadKeyHash
|
||||
func (st *AclState) CurrentReadKeyId() string {
|
||||
return st.currentReadKeyId
|
||||
}
|
||||
|
||||
func (st *AclState) CurrentReadKey() (*crypto.AESKey, error) {
|
||||
key, exists := st.userReadKeys[st.currentReadKeyHash]
|
||||
func (st *AclState) CurrentReadKey() (crypto.SymKey, error) {
|
||||
key, exists := st.userReadKeys[st.currentReadKeyId]
|
||||
if !exists {
|
||||
return nil, ErrNoReadKey
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (st *AclState) UserReadKeys() map[uint64]*crypto.AESKey {
|
||||
func (st *AclState) UserReadKeys() map[string]crypto.SymKey {
|
||||
return st.userReadKeys
|
||||
}
|
||||
|
||||
func (st *AclState) PermissionsAtRecord(id string, identity string) (UserPermissionPair, error) {
|
||||
permissions, ok := st.permissionsAtRecord[id]
|
||||
func (st *AclState) StateAtRecord(id string, pubKey crypto.PubKey) (AclUserState, error) {
|
||||
userState, ok := st.statesAtRecord[id]
|
||||
if !ok {
|
||||
log.Errorf("missing record at id %s", id)
|
||||
return UserPermissionPair{}, ErrNoSuchRecord
|
||||
return AclUserState{}, ErrNoSuchRecord
|
||||
}
|
||||
|
||||
for _, perm := range permissions {
|
||||
if perm.Identity == identity {
|
||||
for _, perm := range userState {
|
||||
if perm.PubKey.Equals(pubKey) {
|
||||
return perm, nil
|
||||
}
|
||||
}
|
||||
return UserPermissionPair{}, ErrNoSuchUser
|
||||
return AclUserState{}, ErrNoSuchUser
|
||||
}
|
||||
|
||||
func (st *AclState) applyRecord(record *AclRecord) (err error) {
|
||||
@ -129,24 +118,18 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) {
|
||||
return
|
||||
}
|
||||
if record.Id == st.id {
|
||||
root, ok := record.Model.(*aclrecordproto.AclRoot)
|
||||
if !ok {
|
||||
return ErrIncorrectRoot
|
||||
}
|
||||
err = st.applyRoot(root)
|
||||
err = st.applyRoot(record)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
st.permissionsAtRecord[record.Id] = []UserPermissionPair{
|
||||
{Identity: string(root.Identity), Permission: aclrecordproto.AclUserPermissions_Admin},
|
||||
st.statesAtRecord[record.Id] = []AclUserState{
|
||||
{PubKey: record.Identity, Permissions: aclrecordproto.AclUserPermissions_Admin},
|
||||
}
|
||||
return
|
||||
}
|
||||
aclData := &aclrecordproto.AclData{}
|
||||
|
||||
if record.Model != nil {
|
||||
aclData = record.Model.(*aclrecordproto.AclData)
|
||||
} else {
|
||||
if record.Model == nil {
|
||||
aclData := &aclrecordproto.AclData{}
|
||||
err = proto.Unmarshal(record.Data, aclData)
|
||||
if err != nil {
|
||||
return
|
||||
@ -154,109 +137,96 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) {
|
||||
record.Model = aclData
|
||||
}
|
||||
|
||||
err = st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity)
|
||||
err = st.applyChangeData(record)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// getting all permissions for users at record
|
||||
var permissions []UserPermissionPair
|
||||
// getting all states for users at record
|
||||
var states []AclUserState
|
||||
for _, state := range st.userStates {
|
||||
permission := UserPermissionPair{
|
||||
Identity: string(state.Identity),
|
||||
Permission: state.Permissions,
|
||||
}
|
||||
permissions = append(permissions, permission)
|
||||
states = append(states, state)
|
||||
}
|
||||
|
||||
st.permissionsAtRecord[record.Id] = permissions
|
||||
st.statesAtRecord[record.Id] = states
|
||||
return
|
||||
}
|
||||
|
||||
func (st *AclState) applyRoot(root *aclrecordproto.AclRoot) (err error) {
|
||||
if st.signingKey != nil && st.encryptionKey != nil && st.identity == string(root.Identity) {
|
||||
err = st.saveReadKeyFromRoot(root)
|
||||
func (st *AclState) applyRoot(record *AclRecord) (err error) {
|
||||
if st.key != nil && st.pubKey.Equals(record.Identity) {
|
||||
err = st.saveReadKeyFromRoot(record)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// adding user to the list
|
||||
userState := &aclrecordproto.AclUserState{
|
||||
Identity: root.Identity,
|
||||
EncryptionKey: root.EncryptionKey,
|
||||
Permissions: aclrecordproto.AclUserPermissions_Admin,
|
||||
userState := AclUserState{
|
||||
PubKey: record.Identity,
|
||||
Permissions: aclrecordproto.AclUserPermissions_Admin,
|
||||
}
|
||||
st.currentReadKeyHash = root.CurrentReadKeyHash
|
||||
st.userStates[string(root.Identity)] = userState
|
||||
st.currentReadKeyId = record.ReadKeyId
|
||||
st.userStates[mapKeyFromPubKey(record.Identity)] = userState
|
||||
st.totalReadKeys++
|
||||
return
|
||||
}
|
||||
|
||||
func (st *AclState) saveReadKeyFromRoot(root *aclrecordproto.AclRoot) (err error) {
|
||||
var readKey *crypto.AESKey
|
||||
func (st *AclState) saveReadKeyFromRoot(record *AclRecord) (err error) {
|
||||
var readKey crypto.SymKey
|
||||
root, ok := record.Model.(*aclrecordproto.AclRoot)
|
||||
if !ok {
|
||||
return ErrIncorrectRoot
|
||||
}
|
||||
if len(root.GetDerivationScheme()) != 0 {
|
||||
var encPrivKey []byte
|
||||
encPrivKey, err = st.encryptionKey.Raw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var signPrivKey []byte
|
||||
signPrivKey, err = st.signingKey.Raw()
|
||||
var keyBytes []byte
|
||||
keyBytes, err = st.key.Raw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
readKey, err = aclrecordproto.AclReadKeyDerive(signPrivKey, encPrivKey)
|
||||
readKey, err = crypto.DeriveAccountSymmetric(keyBytes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
readKey, _, err = st.decryptReadKeyAndHash(root.EncryptedReadKey)
|
||||
readKey, err = st.decryptReadKey(root.EncryptedReadKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
hasher := fnv.New64()
|
||||
_, err = hasher.Write(readKey.Bytes())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if hasher.Sum64() != root.CurrentReadKeyHash {
|
||||
return ErrIncorrectRoot
|
||||
}
|
||||
st.userReadKeys[root.CurrentReadKeyHash] = readKey
|
||||
|
||||
st.userReadKeys[record.Id] = readKey
|
||||
return
|
||||
}
|
||||
|
||||
func (st *AclState) applyChangeData(changeData *aclrecordproto.AclData, hash uint64, identity []byte) (err error) {
|
||||
func (st *AclState) applyChangeData(record *AclRecord) (err error) {
|
||||
defer func() {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if hash != st.currentReadKeyHash {
|
||||
if record.ReadKeyId != st.currentReadKeyId {
|
||||
st.totalReadKeys++
|
||||
st.currentReadKeyHash = hash
|
||||
st.currentReadKeyId = record.ReadKeyId
|
||||
}
|
||||
}()
|
||||
|
||||
if !st.isUserJoin(changeData) {
|
||||
model := record.Model.(*aclrecordproto.AclData)
|
||||
if !st.isUserJoin(model) {
|
||||
// we check signature when we add this to the List, so no need to do it here
|
||||
if _, exists := st.userStates[string(identity)]; !exists {
|
||||
if _, exists := st.userStates[mapKeyFromPubKey(record.Identity)]; !exists {
|
||||
err = ErrNoSuchUser
|
||||
return
|
||||
}
|
||||
|
||||
if !st.HasPermission(identity, aclrecordproto.AclUserPermissions_Admin) {
|
||||
err = fmt.Errorf("user %s must have admin permissions", identity)
|
||||
// only Admins can do non-user join changes
|
||||
if !st.HasPermission(record.Identity, aclrecordproto.AclUserPermissions_Admin) {
|
||||
// TODO: add string encoding
|
||||
err = fmt.Errorf("user %s must have admin permissions", record.Identity.String())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, ch := range changeData.GetAclContent() {
|
||||
if err = st.applyChangeContent(ch); err != nil {
|
||||
for _, ch := range model.GetAclContent() {
|
||||
if err = st.applyChangeContent(ch, record.Id); err != nil {
|
||||
log.Info("error while applying changes: %v; ignore", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
@ -265,26 +235,29 @@ func (st *AclState) applyChangeData(changeData *aclrecordproto.AclData, hash uin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue) error {
|
||||
func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recordId string) error {
|
||||
switch {
|
||||
case ch.GetUserPermissionChange() != nil:
|
||||
return st.applyUserPermissionChange(ch.GetUserPermissionChange())
|
||||
return st.applyUserPermissionChange(ch.GetUserPermissionChange(), recordId)
|
||||
case ch.GetUserAdd() != nil:
|
||||
return st.applyUserAdd(ch.GetUserAdd())
|
||||
return st.applyUserAdd(ch.GetUserAdd(), recordId)
|
||||
case ch.GetUserRemove() != nil:
|
||||
return st.applyUserRemove(ch.GetUserRemove())
|
||||
return st.applyUserRemove(ch.GetUserRemove(), recordId)
|
||||
case ch.GetUserInvite() != nil:
|
||||
return st.applyUserInvite(ch.GetUserInvite())
|
||||
return st.applyUserInvite(ch.GetUserInvite(), recordId)
|
||||
case ch.GetUserJoin() != nil:
|
||||
return st.applyUserJoin(ch.GetUserJoin())
|
||||
return st.applyUserJoin(ch.GetUserJoin(), recordId)
|
||||
default:
|
||||
return fmt.Errorf("unexpected change type: %v", ch)
|
||||
}
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissionChange) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
state, exists := st.userStates[chIdentity]
|
||||
func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissionChange, recordId string) error {
|
||||
chIdentity, err := st.keyStore.PubKeyFromProto(ch.Identity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state, exists := st.userStates[mapKeyFromPubKey(chIdentity)]
|
||||
if !exists {
|
||||
return ErrNoSuchUser
|
||||
}
|
||||
@ -293,131 +266,132 @@ func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissi
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserInvite(ch *aclrecordproto.AclUserInvite) error {
|
||||
st.userInvites[string(ch.AcceptPublicKey)] = ch
|
||||
func (st *AclState) applyUserInvite(ch *aclrecordproto.AclUserInvite, recordId string) error {
|
||||
//acceptPubKey, err := st.keyStore.PubKeyFromProto(ch.AcceptPublicKey)
|
||||
//if err != nil {
|
||||
// return nil
|
||||
//}
|
||||
//st.userInvites[string(ch.AcceptPublicKey)] = ch
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserJoin(ch *aclrecordproto.AclUserJoin) error {
|
||||
invite, exists := st.userInvites[string(ch.AcceptPubKey)]
|
||||
if !exists {
|
||||
return fmt.Errorf("no such invite with such public key %s", keys.EncodeBytesToString(ch.AcceptPubKey))
|
||||
}
|
||||
chIdentity := string(ch.Identity)
|
||||
func (st *AclState) applyUserJoin(ch *aclrecordproto.AclUserJoin, recordId string) error {
|
||||
//invite, exists := st.userInvites[string(ch.AcceptPubKey)]
|
||||
//if !exists {
|
||||
// // TODO: change key to use same encoding
|
||||
// return fmt.Errorf("no such invite with such public key %s", keys.EncodeBytesToString(ch.AcceptPubKey))
|
||||
//}
|
||||
//chIdentity := string(ch.Identity)
|
||||
//if _, exists = st.userStates[chIdentity]; exists {
|
||||
// return ErrUserAlreadyExists
|
||||
//}
|
||||
//
|
||||
//// validating signature
|
||||
//signature := ch.GetAcceptSignature()
|
||||
//verificationKey, err := crypto.UnmarshalEd25519PublicKeyProto(invite.AcceptPublicKey)
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
|
||||
//}
|
||||
//
|
||||
//// TODO: intuitively we need to sign not only the identity but a more complicated payload
|
||||
//res, err := verificationKey.Verify(ch.Identity, signature)
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("verification returned error: %w", err)
|
||||
//}
|
||||
//if !res {
|
||||
// return ErrInvalidSignature
|
||||
//}
|
||||
//
|
||||
//// if ourselves -> we need to decrypt the read keys
|
||||
//if st.identity == chIdentity {
|
||||
// for _, key := range ch.EncryptedReadKeys {
|
||||
// key, err := st.decryptReadKey(key)
|
||||
// if err != nil {
|
||||
// return ErrFailedToDecrypt
|
||||
// }
|
||||
//
|
||||
// st.userReadKeys[recordId] = key
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// adding user to the list
|
||||
//userState := &aclrecordproto.AclUserState{
|
||||
// Identity: ch.Identity,
|
||||
// Permissions: invite.Permissions,
|
||||
//}
|
||||
//st.userStates[chIdentity] = userState
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, exists = st.userStates[chIdentity]; exists {
|
||||
return ErrUserAlreadyExists
|
||||
}
|
||||
func (st *AclState) applyUserAdd(ch *aclrecordproto.AclUserAdd, recordId string) error {
|
||||
//chIdentity := string(ch.Identity)
|
||||
//if _, exists := st.userStates[chIdentity]; exists {
|
||||
// return ErrUserAlreadyExists
|
||||
//}
|
||||
//
|
||||
//st.userStates[chIdentity] = &aclrecordproto.AclUserState{
|
||||
// Identity: ch.Identity,
|
||||
// EncryptionKey: ch.EncryptionKey,
|
||||
// Permissions: ch.Permissions,
|
||||
//}
|
||||
//
|
||||
//if chIdentity == st.identity {
|
||||
// for _, key := range ch.EncryptedReadKeys {
|
||||
// key, hash, err := st.decryptReadKey(key)
|
||||
// if err != nil {
|
||||
// return ErrFailedToDecrypt
|
||||
// }
|
||||
//
|
||||
// st.userReadKeys[hash] = key
|
||||
// }
|
||||
//}
|
||||
|
||||
// validating signature
|
||||
signature := ch.GetAcceptSignature()
|
||||
verificationKey, err := crypto.NewSigningEd25519PubKeyFromBytes(invite.AcceptPublicKey)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove, recordId string) error {
|
||||
//chIdentity := string(ch.Identity)
|
||||
//if chIdentity == st.identity {
|
||||
// return ErrDocumentForbidden
|
||||
//}
|
||||
//
|
||||
//if _, exists := st.userStates[chIdentity]; !exists {
|
||||
// return ErrNoSuchUser
|
||||
//}
|
||||
//
|
||||
//delete(st.userStates, chIdentity)
|
||||
//
|
||||
//for _, replace := range ch.ReadKeyReplaces {
|
||||
// repIdentity := string(replace.Identity)
|
||||
// // if this is our identity then we have to decrypt the key
|
||||
// if repIdentity == st.identity {
|
||||
// key, hash, err := st.decryptReadKey(replace.EncryptedReadKey)
|
||||
// if err != nil {
|
||||
// return ErrFailedToDecrypt
|
||||
// }
|
||||
//
|
||||
// st.userReadKeys[hash] = key
|
||||
// break
|
||||
// }
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) decryptReadKey(msg []byte) (crypto.SymKey, error) {
|
||||
decrypted, err := st.key.Decrypt(msg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
|
||||
}
|
||||
|
||||
res, err := verificationKey.Verify(ch.Identity, signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("verification returned error: %w", err)
|
||||
}
|
||||
if !res {
|
||||
return ErrInvalidSignature
|
||||
}
|
||||
|
||||
// if ourselves -> we need to decrypt the read keys
|
||||
if st.identity == chIdentity {
|
||||
for _, key := range ch.EncryptedReadKeys {
|
||||
key, hash, err := st.decryptReadKeyAndHash(key)
|
||||
if err != nil {
|
||||
return ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
st.userReadKeys[hash] = key
|
||||
}
|
||||
}
|
||||
|
||||
// adding user to the list
|
||||
userState := &aclrecordproto.AclUserState{
|
||||
Identity: ch.Identity,
|
||||
EncryptionKey: ch.EncryptionKey,
|
||||
Permissions: invite.Permissions,
|
||||
}
|
||||
st.userStates[chIdentity] = userState
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserAdd(ch *aclrecordproto.AclUserAdd) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
if _, exists := st.userStates[chIdentity]; exists {
|
||||
return ErrUserAlreadyExists
|
||||
}
|
||||
|
||||
st.userStates[chIdentity] = &aclrecordproto.AclUserState{
|
||||
Identity: ch.Identity,
|
||||
EncryptionKey: ch.EncryptionKey,
|
||||
Permissions: ch.Permissions,
|
||||
}
|
||||
|
||||
if chIdentity == st.identity {
|
||||
for _, key := range ch.EncryptedReadKeys {
|
||||
key, hash, err := st.decryptReadKeyAndHash(key)
|
||||
if err != nil {
|
||||
return ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
st.userReadKeys[hash] = key
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove) error {
|
||||
chIdentity := string(ch.Identity)
|
||||
if chIdentity == st.identity {
|
||||
return ErrDocumentForbidden
|
||||
}
|
||||
|
||||
if _, exists := st.userStates[chIdentity]; !exists {
|
||||
return ErrNoSuchUser
|
||||
}
|
||||
|
||||
delete(st.userStates, chIdentity)
|
||||
|
||||
for _, replace := range ch.ReadKeyReplaces {
|
||||
repIdentity := string(replace.Identity)
|
||||
// if this is our identity then we have to decrypt the key
|
||||
if repIdentity == st.identity {
|
||||
key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey)
|
||||
if err != nil {
|
||||
return ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
st.userReadKeys[hash] = key
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *AclState) decryptReadKeyAndHash(msg []byte) (*crypto.AESKey, uint64, error) {
|
||||
decrypted, err := st.encryptionKey.Decrypt(msg)
|
||||
if err != nil {
|
||||
return nil, 0, ErrFailedToDecrypt
|
||||
return nil, ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
key, err := crypto.UnmarshallAESKey(decrypted)
|
||||
if err != nil {
|
||||
return nil, 0, ErrFailedToDecrypt
|
||||
return nil, ErrFailedToDecrypt
|
||||
}
|
||||
|
||||
hasher := fnv.New64()
|
||||
hasher.Write(decrypted)
|
||||
return key, hasher.Sum64(), nil
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (st *AclState) HasPermission(identity []byte, permission aclrecordproto.AclUserPermissions) bool {
|
||||
state, exists := st.userStates[string(identity)]
|
||||
func (st *AclState) HasPermission(identity crypto.PubKey, permission aclrecordproto.AclUserPermissions) bool {
|
||||
state, exists := st.userStates[mapKeyFromPubKey(identity)]
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
@ -430,36 +404,32 @@ func (st *AclState) isUserJoin(data *aclrecordproto.AclData) bool {
|
||||
return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil
|
||||
}
|
||||
|
||||
func (st *AclState) isUserAdd(data *aclrecordproto.AclData, identity []byte) bool {
|
||||
// if we have a UserAdd, then it should always be the first one applied
|
||||
userAdd := data.GetAclContent()[0].GetUserAdd()
|
||||
return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0
|
||||
}
|
||||
//func (st *AclState) isUserAdd(data *aclrecordproto.AclData, identity []byte) bool {
|
||||
// // if we have a UserAdd, then it should always be the first one applied
|
||||
// userAdd := data.GetAclContent()[0].GetUserAdd()
|
||||
// return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0
|
||||
//}
|
||||
|
||||
func (st *AclState) UserStates() map[string]*aclrecordproto.AclUserState {
|
||||
func (st *AclState) UserStates() map[string]AclUserState {
|
||||
return st.userStates
|
||||
}
|
||||
|
||||
func (st *AclState) Invite(acceptPubKey []byte) (invite *aclrecordproto.AclUserInvite, err error) {
|
||||
invite, exists := st.userInvites[string(acceptPubKey)]
|
||||
if !exists {
|
||||
err = ErrNoSuchInvite
|
||||
return
|
||||
}
|
||||
if len(invite.EncryptedReadKeys) != st.totalReadKeys {
|
||||
err = ErrOldInvite
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (st *AclState) UserKeys() (encKey encryptionkey.PrivKey, signKey signingkey.PrivKey) {
|
||||
return st.encryptionKey, st.signingKey
|
||||
}
|
||||
|
||||
func (st *AclState) Identity() []byte {
|
||||
return []byte(st.identity)
|
||||
}
|
||||
//func (st *AclState) Invite(acceptPubKey []byte) (invite *aclrecordproto.AclUserInvite, err error) {
|
||||
// invite, exists := st.userInvites[string(acceptPubKey)]
|
||||
// if !exists {
|
||||
// err = ErrNoSuchInvite
|
||||
// return
|
||||
// }
|
||||
// if len(invite.EncryptedReadKeys) != st.totalReadKeys {
|
||||
// err = ErrOldInvite
|
||||
// }
|
||||
// return
|
||||
//}
|
||||
|
||||
func (st *AclState) LastRecordId() string {
|
||||
return st.lastRecordId
|
||||
}
|
||||
|
||||
func mapKeyFromPubKey(pubKey crypto.PubKey) string {
|
||||
return string(pubKey.Storage())
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/liststorage"
|
||||
"github.com/anytypeio/any-sync/commonspace/object/keychain"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -56,11 +57,11 @@ type aclList struct {
|
||||
|
||||
func BuildAclListWithIdentity(acc *accountdata.AccountData, storage liststorage.ListStorage) (AclList, error) {
|
||||
builder := newAclStateBuilderWithIdentity(acc)
|
||||
return build(storage.Id(), builder, newAclRecordBuilder(storage.Id(), keychain.NewKeychain()), storage)
|
||||
return build(storage.Id(), builder, newAclRecordBuilder(storage.Id(), crypto.NewKeyStorage()), storage)
|
||||
}
|
||||
|
||||
func BuildAclList(storage liststorage.ListStorage) (AclList, error) {
|
||||
return build(storage.Id(), newAclStateBuilder(), newAclRecordBuilder(storage.Id(), keychain.NewKeychain()), storage)
|
||||
return build(storage.Id(), newAclStateBuilder(), newAclRecordBuilder(storage.Id(), crypto.NewKeyStorage()), storage)
|
||||
}
|
||||
|
||||
func build(id string, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder, storage liststorage.ListStorage) (list AclList, err error) {
|
||||
@ -74,7 +75,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder
|
||||
return
|
||||
}
|
||||
|
||||
record, err := recBuilder.ConvertFromRaw(rawRecordWithId)
|
||||
record, err := recBuilder.FromRaw(rawRecordWithId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -86,7 +87,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder
|
||||
return
|
||||
}
|
||||
|
||||
record, err = recBuilder.ConvertFromRaw(rawRecordWithId)
|
||||
record, err = recBuilder.FromRaw(rawRecordWithId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -137,7 +138,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added
|
||||
if _, ok := a.indexes[rawRec.Id]; ok {
|
||||
return
|
||||
}
|
||||
record, err := a.recordBuilder.ConvertFromRaw(rawRec)
|
||||
record, err := a.recordBuilder.FromRaw(rawRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -156,7 +157,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added
|
||||
}
|
||||
|
||||
func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) {
|
||||
_, err = a.recordBuilder.ConvertFromRaw(rawRec)
|
||||
_, err = a.recordBuilder.FromRaw(rawRec)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ func TestAclList_AclState_UserInviteAndJoin(t *testing.T) {
|
||||
assert.Equal(t, aclrecordproto.AclUserPermissions_Admin, aclList.AclState().UserStates()[idA].Permissions)
|
||||
assert.Equal(t, aclrecordproto.AclUserPermissions_Writer, aclList.AclState().UserStates()[idB].Permissions)
|
||||
assert.Equal(t, aclrecordproto.AclUserPermissions_Reader, aclList.AclState().UserStates()[idC].Permissions)
|
||||
assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyHash())
|
||||
assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
||||
|
||||
var records []*AclRecord
|
||||
aclList.Iterate(func(record *AclRecord) (IsContinue bool) {
|
||||
@ -36,10 +36,10 @@ func TestAclList_AclState_UserInviteAndJoin(t *testing.T) {
|
||||
// checking permissions at specific records
|
||||
assert.Equal(t, 3, len(records))
|
||||
|
||||
_, err = aclList.AclState().PermissionsAtRecord(records[1].Id, idB)
|
||||
_, err = aclList.AclState().StateAtRecord(records[1].Id, idB)
|
||||
assert.Error(t, err, "B should have no permissions at record 1")
|
||||
|
||||
perm, err := aclList.AclState().PermissionsAtRecord(records[2].Id, idB)
|
||||
perm, err := aclList.AclState().StateAtRecord(records[2].Id, idB)
|
||||
assert.NoError(t, err, "should have no error with permissions of B in the record 2")
|
||||
assert.Equal(t, UserPermissionPair{
|
||||
Identity: idB,
|
||||
@ -63,7 +63,7 @@ func TestAclList_AclState_UserJoinAndRemove(t *testing.T) {
|
||||
// checking final state
|
||||
assert.Equal(t, aclrecordproto.AclUserPermissions_Admin, aclList.AclState().UserStates()[idA].Permissions)
|
||||
assert.Equal(t, aclrecordproto.AclUserPermissions_Reader, aclList.AclState().UserStates()[idC].Permissions)
|
||||
assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyHash())
|
||||
assert.Equal(t, aclList.Head().CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
||||
|
||||
_, exists := aclList.AclState().UserStates()[idB]
|
||||
assert.Equal(t, false, exists)
|
||||
@ -77,15 +77,15 @@ func TestAclList_AclState_UserJoinAndRemove(t *testing.T) {
|
||||
// checking permissions at specific records
|
||||
assert.Equal(t, 4, len(records))
|
||||
|
||||
assert.NotEqual(t, records[2].CurrentReadKeyHash, aclList.AclState().CurrentReadKeyHash())
|
||||
assert.NotEqual(t, records[2].CurrentReadKeyHash, aclList.AclState().CurrentReadKeyId())
|
||||
|
||||
perm, err := aclList.AclState().PermissionsAtRecord(records[2].Id, idB)
|
||||
perm, err := aclList.AclState().StateAtRecord(records[2].Id, idB)
|
||||
assert.NoError(t, err, "should have no error with permissions of B in the record 2")
|
||||
assert.Equal(t, UserPermissionPair{
|
||||
Identity: idB,
|
||||
Permission: aclrecordproto.AclUserPermissions_Writer,
|
||||
}, perm)
|
||||
|
||||
_, err = aclList.AclState().PermissionsAtRecord(records[3].Id, idB)
|
||||
_, err = aclList.AclState().StateAtRecord(records[3].Id, idB)
|
||||
assert.Error(t, err, "B should have no permissions at record 3, because user should be removed")
|
||||
}
|
||||
|
||||
22
commonspace/object/acl/list/models.go
Normal file
22
commonspace/object/acl/list/models.go
Normal file
@ -0,0 +1,22 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
|
||||
"github.com/anytypeio/any-sync/util/crypto"
|
||||
)
|
||||
|
||||
type AclRecord struct {
|
||||
Id string
|
||||
PrevId string
|
||||
ReadKeyId string
|
||||
Timestamp int64
|
||||
Data []byte
|
||||
Identity crypto.PubKey
|
||||
Model interface{}
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
type AclUserState struct {
|
||||
PubKey crypto.PubKey
|
||||
Permissions aclrecordproto.AclUserPermissions
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
package list
|
||||
|
||||
type AclRecord struct {
|
||||
Id string
|
||||
PrevId string
|
||||
CurrentReadKeyHash uint64
|
||||
Timestamp int64
|
||||
Data []byte
|
||||
Identity []byte
|
||||
Model interface{}
|
||||
Signature []byte
|
||||
}
|
||||
@ -68,7 +68,7 @@ func (t *treeExporter) ExportUnencrypted(tree objecttree.ReadableObjectTree) (er
|
||||
return false
|
||||
}
|
||||
// that means that change is unencrypted
|
||||
change.ReadKeyHash = 0
|
||||
change.ReadKeyId = 0
|
||||
change.Data = data
|
||||
err = putStorage(change)
|
||||
return err == nil
|
||||
|
||||
@ -20,7 +20,7 @@ type Change struct {
|
||||
SnapshotId string
|
||||
IsSnapshot bool
|
||||
Timestamp int64
|
||||
ReadKeyHash uint64
|
||||
ReadKeyId string
|
||||
Identity string
|
||||
Data []byte
|
||||
Model interface{}
|
||||
@ -38,7 +38,7 @@ func NewChange(id string, ch *treechangeproto.TreeChange, signature []byte) *Cha
|
||||
PreviousIds: ch.TreeHeadIds,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
Timestamp: ch.Timestamp,
|
||||
ReadKeyHash: ch.CurrentReadKeyHash,
|
||||
ReadKeyId: ch.ReadKeyId,
|
||||
Id: id,
|
||||
Data: ch.ChangesData,
|
||||
SnapshotId: ch.SnapshotBaseId,
|
||||
|
||||
@ -14,15 +14,15 @@ import (
|
||||
var ErrEmptyChange = errors.New("change payload should not be empty")
|
||||
|
||||
type BuilderContent struct {
|
||||
TreeHeadIds []string
|
||||
AclHeadId string
|
||||
SnapshotBaseId string
|
||||
CurrentReadKeyHash uint64
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
SigningKey signingkey.PrivKey
|
||||
ReadKey *crypto.AESKey
|
||||
Content []byte
|
||||
TreeHeadIds []string
|
||||
AclHeadId string
|
||||
SnapshotBaseId string
|
||||
ReadKeyId string
|
||||
Identity []byte
|
||||
IsSnapshot bool
|
||||
SigningKey signingkey.PrivKey
|
||||
ReadKey *crypto.AESKey
|
||||
Content []byte
|
||||
}
|
||||
|
||||
type InitialContent struct {
|
||||
@ -161,13 +161,13 @@ func (c *changeBuilder) BuildRoot(payload InitialContent) (ch *Change, rawIdChan
|
||||
|
||||
func (c *changeBuilder) Build(payload BuilderContent) (ch *Change, rawIdChange *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
change := &treechangeproto.TreeChange{
|
||||
TreeHeadIds: payload.TreeHeadIds,
|
||||
AclHeadId: payload.AclHeadId,
|
||||
SnapshotBaseId: payload.SnapshotBaseId,
|
||||
CurrentReadKeyHash: payload.CurrentReadKeyHash,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Identity: payload.Identity,
|
||||
IsSnapshot: payload.IsSnapshot,
|
||||
TreeHeadIds: payload.TreeHeadIds,
|
||||
AclHeadId: payload.AclHeadId,
|
||||
SnapshotBaseId: payload.SnapshotBaseId,
|
||||
ReadKeyId: payload.ReadKeyId,
|
||||
Timestamp: time.Now().Unix(),
|
||||
Identity: payload.Identity,
|
||||
IsSnapshot: payload.IsSnapshot,
|
||||
}
|
||||
if payload.ReadKey != nil {
|
||||
var encrypted []byte
|
||||
@ -212,14 +212,14 @@ func (c *changeBuilder) Marshall(ch *Change) (raw *treechangeproto.RawTreeChange
|
||||
return c.rootChange, nil
|
||||
}
|
||||
treeChange := &treechangeproto.TreeChange{
|
||||
TreeHeadIds: ch.PreviousIds,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
SnapshotBaseId: ch.SnapshotId,
|
||||
ChangesData: ch.Data,
|
||||
CurrentReadKeyHash: ch.ReadKeyHash,
|
||||
Timestamp: ch.Timestamp,
|
||||
Identity: []byte(ch.Identity),
|
||||
IsSnapshot: ch.IsSnapshot,
|
||||
TreeHeadIds: ch.PreviousIds,
|
||||
AclHeadId: ch.AclHeadId,
|
||||
SnapshotBaseId: ch.SnapshotId,
|
||||
ChangesData: ch.Data,
|
||||
ReadKeyId: ch.ReadKeyId,
|
||||
Timestamp: ch.Timestamp,
|
||||
Identity: []byte(ch.Identity),
|
||||
IsSnapshot: ch.IsSnapshot,
|
||||
}
|
||||
var marshalled []byte
|
||||
marshalled, err = treeChange.Marshal()
|
||||
|
||||
@ -236,22 +236,22 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
|
||||
}
|
||||
|
||||
if content.IsEncrypted {
|
||||
readKeyHash = state.CurrentReadKeyHash()
|
||||
readKeyHash = state.CurrentReadKeyId()
|
||||
readKey, err = state.CurrentReadKey()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
cnt = BuilderContent{
|
||||
TreeHeadIds: ot.tree.Heads(),
|
||||
AclHeadId: ot.aclList.Head().Id,
|
||||
SnapshotBaseId: ot.tree.RootId(),
|
||||
CurrentReadKeyHash: readKeyHash,
|
||||
Identity: content.Identity,
|
||||
IsSnapshot: content.IsSnapshot,
|
||||
SigningKey: content.Key,
|
||||
ReadKey: readKey,
|
||||
Content: content.Data,
|
||||
TreeHeadIds: ot.tree.Heads(),
|
||||
AclHeadId: ot.aclList.Head().Id,
|
||||
SnapshotBaseId: ot.tree.RootId(),
|
||||
ReadKeyId: readKeyHash,
|
||||
Identity: content.Identity,
|
||||
IsSnapshot: content.IsSnapshot,
|
||||
SigningKey: content.Key,
|
||||
ReadKey: readKey,
|
||||
Content: content.Data,
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -488,11 +488,11 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
|
||||
}
|
||||
decrypt := func(c *Change) (decrypted []byte, err error) {
|
||||
// the change is not encrypted
|
||||
if c.ReadKeyHash == 0 {
|
||||
if c.ReadKeyId == 0 {
|
||||
decrypted = c.Data
|
||||
return
|
||||
}
|
||||
readKey, exists := ot.keys[c.ReadKeyHash]
|
||||
readKey, exists := ot.keys[c.ReadKeyId]
|
||||
if !exists {
|
||||
err = list.ErrNoReadKey
|
||||
return
|
||||
|
||||
@ -54,7 +54,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c
|
||||
state = aclList.AclState()
|
||||
)
|
||||
// checking if the user could write
|
||||
perm, err = state.PermissionsAtRecord(c.AclHeadId, c.Identity)
|
||||
perm, err = state.StateAtRecord(c.AclHeadId, c.Identity)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anytypeio/any-sync/util/crypto/cryptoproto"
|
||||
"github.com/anytypeio/any-sync/util/strkey"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"io"
|
||||
"sync"
|
||||
@ -119,6 +120,11 @@ func (k *Ed25519PrivKey) Decrypt(msg []byte) ([]byte, error) {
|
||||
return DecryptX25519(k.privCurve, k.pubCurve, msg)
|
||||
}
|
||||
|
||||
func (k *Ed25519PubKey) String() string {
|
||||
res, _ := strkey.Encode(strkey.AccountAddressVersionByte, k.pubKey)
|
||||
return res
|
||||
}
|
||||
|
||||
// Raw public key bytes.
|
||||
func (k *Ed25519PubKey) Raw() ([]byte, error) {
|
||||
return k.pubKey, nil
|
||||
@ -134,6 +140,11 @@ func (k *Ed25519PubKey) Encrypt(msg []byte) (data []byte, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Storage returns underlying byte storage
|
||||
func (k *Ed25519PubKey) Storage() []byte {
|
||||
return k.pubKey
|
||||
}
|
||||
|
||||
// Equals compares two ed25519 public keys.
|
||||
func (k *Ed25519PubKey) Equals(o Key) bool {
|
||||
edk, ok := o.(*Ed25519PubKey)
|
||||
|
||||
@ -38,6 +38,10 @@ type PubKey interface {
|
||||
Verify(data []byte, sig []byte) (bool, error)
|
||||
// Marshall wraps key in proto encoding and marshalls it
|
||||
Marshall() ([]byte, error)
|
||||
// Storage returns underlying key storage
|
||||
Storage() []byte
|
||||
// String returns string representation
|
||||
String() string
|
||||
}
|
||||
|
||||
type SymKey interface {
|
||||
|
||||
9
util/crypto/keystorage.go
Normal file
9
util/crypto/keystorage.go
Normal file
@ -0,0 +1,9 @@
|
||||
package crypto
|
||||
|
||||
type KeyStorage interface {
|
||||
PubKeyFromProto(protoBytes []byte) (PubKey, error)
|
||||
}
|
||||
|
||||
func NewKeyStorage() KeyStorage {
|
||||
return nil
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user