ACLState refactoring

This commit is contained in:
mcrakhman 2023-03-24 22:43:25 +01:00 committed by Mikhail Iudin
parent 9f0828a56a
commit c00ea331dc
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
17 changed files with 506 additions and 606 deletions

View File

@ -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)
}

View File

@ -251,8 +251,7 @@ type AclRoot struct {
SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,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"` EncryptedReadKey []byte `protobuf:"bytes,3,opt,name=encryptedReadKey,proto3" json:"encryptedReadKey,omitempty"`
DerivationScheme string `protobuf:"bytes,4,opt,name=derivationScheme,proto3" json:"derivationScheme,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,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
Timestamp int64 `protobuf:"varint,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
} }
func (m *AclRoot) Reset() { *m = AclRoot{} } func (m *AclRoot) Reset() { *m = AclRoot{} }
@ -316,13 +315,6 @@ func (m *AclRoot) GetDerivationScheme() string {
return "" return ""
} }
func (m *AclRoot) GetCurrentReadKeyHash() uint64 {
if m != nil {
return m.CurrentReadKeyHash
}
return 0
}
func (m *AclRoot) GetTimestamp() int64 { func (m *AclRoot) GetTimestamp() int64 {
if m != nil { if m != nil {
return m.Timestamp return m.Timestamp
@ -733,10 +725,9 @@ func (m *AclUserInvite) GetPermissions() AclUserPermissions {
type AclUserJoin struct { type AclUserJoin struct {
Identity []byte `protobuf:"bytes,1,opt,name=identity,proto3" json:"identity,omitempty"` 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,2,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"`
AcceptSignature []byte `protobuf:"bytes,3,opt,name=acceptSignature,proto3" json:"acceptSignature,omitempty"` AcceptPubKey []byte `protobuf:"bytes,3,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"`
AcceptPubKey []byte `protobuf:"bytes,4,opt,name=acceptPubKey,proto3" json:"acceptPubKey,omitempty"` EncryptedReadKeys [][]byte `protobuf:"bytes,4,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
EncryptedReadKeys [][]byte `protobuf:"bytes,5,rep,name=encryptedReadKeys,proto3" json:"encryptedReadKeys,omitempty"`
} }
func (m *AclUserJoin) Reset() { *m = AclUserJoin{} } func (m *AclUserJoin) Reset() { *m = AclUserJoin{} }
@ -779,13 +770,6 @@ func (m *AclUserJoin) GetIdentity() []byte {
return nil return nil
} }
func (m *AclUserJoin) GetEncryptionKey() []byte {
if m != nil {
return m.EncryptionKey
}
return nil
}
func (m *AclUserJoin) GetAcceptSignature() []byte { func (m *AclUserJoin) GetAcceptSignature() []byte {
if m != nil { if m != nil {
return m.AcceptSignature return m.AcceptSignature
@ -1152,66 +1136,64 @@ func init() {
} }
var fileDescriptor_c8e9f754f34e929b = []byte{ 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, 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, 0x14, 0xf7, 0xd8, 0x49, 0x1c, 0x3f, 0x9b, 0xc4, 0x19, 0xa0, 0x5d, 0x45, 0xc5, 0x8a, 0x56, 0x42,
0x8a, 0xaa, 0xca, 0x11, 0x06, 0x29, 0x55, 0x84, 0xa8, 0xdc, 0x52, 0x64, 0xb7, 0x42, 0xaa, 0x26, 0x8a, 0xaa, 0x2a, 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, 0x40, 0x51, 0x39, 0x4d, 0x66, 0x47, 0xc9, 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, 0x37, 0xae, 0x5c, 0x90, 0xf8, 0x02, 0x7c, 0x07, 0x8e, 0xb9, 0x20, 0x71, 0x44, 0xc9, 0x67, 0xe0,
0x99, 0xd9, 0xff, 0xeb, 0x58, 0x70, 0x80, 0x43, 0xe2, 0x9d, 0xf7, 0x7e, 0xef, 0xcd, 0xef, 0xfd, 0x8e, 0x66, 0xc6, 0xfb, 0xdf, 0x31, 0x70, 0xa0, 0x87, 0xc4, 0x3b, 0xef, 0xfd, 0xe6, 0xcd, 0xef,
0xe6, 0xcd, 0xdb, 0x85, 0x8f, 0x69, 0x34, 0x9f, 0x47, 0xa1, 0x8c, 0x09, 0x65, 0x27, 0xd1, 0xc5, 0xfd, 0xe6, 0xbd, 0xb7, 0x0b, 0x1f, 0xb3, 0x78, 0x3a, 0x8d, 0x23, 0x95, 0x50, 0xc6, 0x8f, 0xe3,
0xb7, 0x8c, 0xaa, 0x13, 0x42, 0x03, 0xfd, 0x27, 0x18, 0x8d, 0x84, 0x1f, 0x8b, 0x48, 0x45, 0x27, 0xf3, 0x6f, 0x39, 0xd3, 0xc7, 0x94, 0x85, 0xe6, 0x4f, 0x72, 0x16, 0xcb, 0x20, 0x91, 0xb1, 0x8e,
0xe6, 0xbf, 0xcc, 0xad, 0x43, 0x63, 0x40, 0x9d, 0xcc, 0xe0, 0xfd, 0xe4, 0x40, 0x0f, 0x93, 0xef, 0x8f, 0xed, 0x7f, 0x95, 0x5b, 0x8f, 0xac, 0x01, 0x77, 0x32, 0x83, 0xff, 0x13, 0x82, 0x1e, 0xa1,
0xc6, 0x34, 0xc0, 0xc6, 0x80, 0x5c, 0x68, 0xc7, 0x64, 0x15, 0x44, 0xc4, 0x77, 0x9d, 0x23, 0xe7, 0xdf, 0x8d, 0x58, 0x48, 0xac, 0x01, 0x7b, 0xd0, 0x4e, 0xe8, 0x22, 0x8c, 0x69, 0xe0, 0xa1, 0x03,
0xb8, 0x87, 0xd3, 0x25, 0xba, 0x0f, 0x1d, 0xc9, 0x2f, 0x43, 0xa2, 0x16, 0x82, 0xb9, 0x4d, 0xe3, 0x74, 0xd8, 0x23, 0xe9, 0x12, 0xdf, 0x83, 0x8e, 0x12, 0x17, 0x11, 0xd5, 0x33, 0xc9, 0xbd, 0xa6,
0xcb, 0x0d, 0xe8, 0x01, 0xf4, 0x09, 0xa5, 0x2c, 0x56, 0x91, 0x98, 0xfa, 0x2c, 0x54, 0x5c, 0xad, 0xf5, 0xe5, 0x06, 0x7c, 0x1f, 0xfa, 0x94, 0x31, 0x9e, 0xe8, 0x58, 0x4e, 0x02, 0x1e, 0x69, 0xa1,
0xdc, 0x96, 0x01, 0xd5, 0xec, 0xe8, 0x21, 0x1c, 0xa4, 0xb6, 0xf3, 0x2c, 0xe3, 0x96, 0x01, 0xd7, 0x17, 0x5e, 0xcb, 0x82, 0x6a, 0x76, 0xfc, 0x00, 0xf6, 0x52, 0xdb, 0x59, 0x16, 0x71, 0xc3, 0x82,
0x1d, 0xde, 0x27, 0x80, 0x8a, 0x0c, 0x5f, 0x71, 0x35, 0x9b, 0x6e, 0xe2, 0xb9, 0x07, 0x4d, 0xee, 0xeb, 0x0e, 0xff, 0x13, 0xc0, 0x45, 0x86, 0x2f, 0x85, 0xbe, 0x9c, 0xac, 0xe3, 0xb9, 0x03, 0x4d,
0x1b, 0x82, 0x1d, 0xdc, 0xe4, 0xbe, 0xf7, 0xbd, 0x03, 0x9d, 0xbc, 0xbe, 0xbb, 0xb0, 0x13, 0x0b, 0x11, 0x58, 0x82, 0x1d, 0xd2, 0x14, 0x81, 0xff, 0x3d, 0x82, 0x4e, 0x9e, 0xdf, 0x1d, 0xd8, 0x4a,
0xb6, 0x9c, 0xda, 0xb0, 0x0e, 0x4e, 0x56, 0xe8, 0x10, 0x76, 0x79, 0xca, 0xdb, 0x16, 0x97, 0xad, 0x24, 0x9f, 0x4f, 0xdc, 0xb6, 0x0e, 0x59, 0xae, 0xf0, 0x3e, 0x6c, 0x8b, 0x94, 0xb7, 0x4b, 0x2e,
0x11, 0x82, 0x2d, 0x9f, 0x28, 0x92, 0xd4, 0x63, 0x9e, 0xb5, 0x1a, 0x82, 0x11, 0xff, 0x05, 0x5b, 0x5b, 0x63, 0x0c, 0x1b, 0x01, 0xd5, 0x74, 0x99, 0x8f, 0x7d, 0x36, 0x6a, 0x48, 0x4e, 0x83, 0xe7,
0x4d, 0x7d, 0xc3, 0xbd, 0x83, 0x73, 0x83, 0xf6, 0x2a, 0x3e, 0x67, 0x52, 0x91, 0x79, 0xec, 0x6e, 0x7c, 0x31, 0x09, 0x2c, 0xf7, 0x0e, 0xc9, 0x0d, 0xc6, 0xab, 0xc5, 0x94, 0x2b, 0x4d, 0xa7, 0x89,
0x1f, 0x39, 0xc7, 0x2d, 0x9c, 0x1b, 0xbc, 0x3f, 0x1d, 0x68, 0x6b, 0x46, 0x51, 0xa4, 0x4a, 0xfb, 0xb7, 0x79, 0x80, 0x0e, 0x5b, 0x24, 0x37, 0xf8, 0xbf, 0x22, 0x68, 0x1b, 0x46, 0x71, 0xac, 0x4b,
0x3a, 0x95, 0x7d, 0x5d, 0x68, 0x9b, 0x13, 0x9e, 0xa6, 0xe5, 0xa4, 0x4b, 0xad, 0x36, 0x0b, 0xa9, 0xe7, 0xa2, 0xca, 0xb9, 0x1e, 0xb4, 0xed, 0x0d, 0x4f, 0xd2, 0x74, 0xd2, 0xa5, 0x51, 0x9b, 0x47,
0x58, 0xc5, 0x8a, 0xf9, 0xd8, 0xee, 0x9a, 0xaa, 0x5d, 0xb5, 0x6b, 0xac, 0xcf, 0x04, 0x5f, 0x12, 0x4c, 0x2e, 0x12, 0xcd, 0x03, 0xe2, 0x4e, 0x4d, 0xd5, 0xae, 0xda, 0x0d, 0x36, 0xe0, 0x52, 0xcc,
0xc5, 0xa3, 0xf0, 0x9c, 0xce, 0xd8, 0x9c, 0x25, 0x84, 0x6b, 0x76, 0x34, 0x04, 0x44, 0x17, 0x42, 0xa9, 0x16, 0x71, 0x74, 0xc6, 0x2e, 0xf9, 0x94, 0x2f, 0x09, 0xd7, 0xec, 0xff, 0xc0, 0xfb, 0xf7,
0xb0, 0x50, 0x25, 0xd1, 0x13, 0x22, 0x67, 0xa6, 0x80, 0x2d, 0xbc, 0xc6, 0x53, 0xae, 0x73, 0xa7, 0x26, 0xec, 0x8e, 0x58, 0xf8, 0x24, 0x8e, 0x34, 0x8f, 0xf4, 0x57, 0x34, 0x9c, 0x71, 0xfc, 0x01,
0x5a, 0xe7, 0x6f, 0x4d, 0xd8, 0x1f, 0xd3, 0xe0, 0x69, 0x14, 0x2a, 0x16, 0xaa, 0xaf, 0x48, 0xb0, 0xb4, 0x67, 0x8a, 0xcb, 0x51, 0xe0, 0x04, 0xed, 0x0e, 0xdf, 0x3d, 0xca, 0xcb, 0x6d, 0xc4, 0xc2,
0x60, 0xe8, 0x03, 0x68, 0x2f, 0x24, 0x13, 0x63, 0xdf, 0x1e, 0x40, 0x77, 0xf4, 0xce, 0x30, 0x6f, 0x2f, 0x9d, 0x73, 0xdc, 0x20, 0x29, 0x0e, 0x9f, 0x02, 0x98, 0x47, 0xc2, 0xa7, 0xf1, 0xdc, 0x55,
0xcf, 0x31, 0x0d, 0xbe, 0xb4, 0xce, 0x49, 0x03, 0xa7, 0x38, 0x74, 0x06, 0xa0, 0x1f, 0x31, 0x9b, 0x52, 0x77, 0xe8, 0xd5, 0x77, 0x39, 0xff, 0xb8, 0x41, 0x0a, 0x68, 0xfc, 0x35, 0xbc, 0x63, 0x56,
0x47, 0x4b, 0xdb, 0x79, 0xdd, 0x91, 0x5b, 0x8f, 0xb2, 0xfe, 0x49, 0x03, 0x17, 0xd0, 0xe8, 0x6b, 0x2f, 0xb8, 0x9c, 0x0a, 0xa5, 0x44, 0x1c, 0x3d, 0xb9, 0xa4, 0xd1, 0x05, 0xb7, 0xc9, 0x77, 0x87,
0x78, 0x5b, 0xaf, 0x5e, 0x32, 0x31, 0xe7, 0x52, 0xf2, 0x28, 0x7c, 0x3a, 0x23, 0xe1, 0x25, 0x33, 0x7e, 0x3d, 0x4a, 0x15, 0x39, 0x6e, 0x90, 0x95, 0x11, 0x52, 0x56, 0x93, 0x68, 0x2e, 0xb4, 0x13,
0x62, 0x75, 0x47, 0x5e, 0x3d, 0x4b, 0x15, 0x39, 0x69, 0xe0, 0xb5, 0x19, 0x52, 0x56, 0xd3, 0x70, 0x68, 0x25, 0x2b, 0xe7, 0x4f, 0x59, 0xb9, 0x15, 0xfe, 0x08, 0xb6, 0xcd, 0xea, 0x59, 0x2c, 0x22,
0xc9, 0x95, 0x15, 0x74, 0x2d, 0x2b, 0xeb, 0x4f, 0x59, 0xd9, 0x15, 0xfa, 0x08, 0x76, 0xf5, 0xea, 0xab, 0x5a, 0x77, 0x78, 0xa7, 0xbe, 0xd3, 0x78, 0xc7, 0x0d, 0x92, 0x21, 0x1f, 0xb7, 0x61, 0x73,
0x79, 0xc4, 0x43, 0x23, 0x6e, 0x77, 0x74, 0xb7, 0x1e, 0xa9, 0xbd, 0x93, 0x06, 0xce, 0x90, 0x4f, 0x6e, 0x34, 0xf4, 0x9f, 0xda, 0x72, 0xf8, 0xd4, 0x94, 0xd5, 0x29, 0x00, 0xcd, 0x14, 0xf6, 0xd0,
0xda, 0xb0, 0xbd, 0xd4, 0x1a, 0x7a, 0xcf, 0x4c, 0xfb, 0x7c, 0xaa, 0xdb, 0xf0, 0x0c, 0x80, 0x64, 0x41, 0xeb, 0xb0, 0x3b, 0xdc, 0x2f, 0xc7, 0x2a, 0xca, 0x4f, 0x0a, 0x68, 0xff, 0x2f, 0x04, 0xdb,
0x0a, 0xbb, 0xce, 0x51, 0xeb, 0xb8, 0x3b, 0x3a, 0x2c, 0xe7, 0x2a, 0xca, 0x8f, 0x0b, 0x68, 0xef, 0x23, 0x16, 0x9e, 0x69, 0xaa, 0x39, 0x1e, 0x00, 0x64, 0xe5, 0xa8, 0x6c, 0xa0, 0x0e, 0x29, 0x58,
0x2f, 0x07, 0x76, 0xc7, 0x34, 0x38, 0x57, 0x44, 0x31, 0x34, 0x00, 0xc8, 0xda, 0x57, 0x9a, 0x44, 0xf0, 0x89, 0x4b, 0xd7, 0x82, 0x95, 0xd7, 0xb4, 0x07, 0xdd, 0xad, 0x93, 0xb6, 0x7e, 0x52, 0x80,
0x1d, 0x5c, 0xb0, 0xa0, 0x53, 0x5b, 0xae, 0x01, 0x4b, 0xb7, 0x69, 0x36, 0xba, 0x57, 0x27, 0x6d, 0xe2, 0x53, 0x68, 0x0b, 0x9b, 0xb5, 0xf2, 0x5a, 0x76, 0xd7, 0x41, 0x79, 0x97, 0x85, 0x1d, 0x39,
0xfc, 0xb8, 0x00, 0x45, 0x67, 0xd0, 0xe6, 0xa6, 0x6a, 0xe9, 0xb6, 0x4c, 0xd4, 0x51, 0x39, 0xca, 0x61, 0xd4, 0xd3, 0x48, 0xcb, 0x05, 0x49, 0x37, 0xec, 0x7f, 0x01, 0xbd, 0xa2, 0x03, 0xf7, 0xa1,
0xc0, 0x86, 0x56, 0x18, 0xf9, 0x2c, 0x54, 0x62, 0x85, 0xd3, 0x80, 0xc3, 0x2f, 0xa0, 0x57, 0x74, 0xf5, 0x9a, 0x2f, 0x96, 0x9d, 0x68, 0x1e, 0xf1, 0xd1, 0x52, 0x93, 0xdb, 0xcb, 0xc2, 0x05, 0x20,
0xa0, 0x3e, 0xb4, 0xde, 0xb0, 0x55, 0x72, 0x73, 0xf5, 0x23, 0x1a, 0x26, 0x9a, 0xdc, 0xde, 0x16, 0x0e, 0x76, 0xda, 0x7c, 0x88, 0xfc, 0xd7, 0xd0, 0x2b, 0xb2, 0x5d, 0xdb, 0x52, 0x8f, 0xa0, 0x9b,
0x36, 0x01, 0xb6, 0xb0, 0xb3, 0xe6, 0x23, 0xc7, 0x7b, 0x03, 0xbd, 0x22, 0xdb, 0x8d, 0x57, 0xf0, 0x64, 0x37, 0xaf, 0xec, 0x29, 0x3b, 0xc3, 0xf7, 0xd6, 0x95, 0x8d, 0x22, 0xc5, 0x1d, 0xfe, 0x8f,
0x31, 0x74, 0xe3, 0xec, 0xe4, 0xa5, 0xd9, 0x65, 0x6f, 0xf4, 0xee, 0xa6, 0xb6, 0x91, 0xb8, 0x18, 0x08, 0x20, 0x2f, 0xeb, 0xb5, 0x67, 0x3d, 0x80, 0xbd, 0x6a, 0x33, 0x3a, 0xa5, 0x7b, 0xa4, 0xee,
0xe1, 0xfd, 0xe8, 0x00, 0xe4, 0x6d, 0xbd, 0x71, 0xaf, 0x87, 0x70, 0x50, 0xbd, 0xbc, 0x56, 0xe9, 0xa8, 0x32, 0x6b, 0xfd, 0x67, 0x66, 0xbf, 0x20, 0x78, 0xab, 0xa4, 0x11, 0x3e, 0x84, 0x5d, 0x37,
0x1e, 0xae, 0x3b, 0xaa, 0xcc, 0x5a, 0xff, 0x9a, 0xd9, 0xcf, 0x0e, 0xdc, 0x29, 0x69, 0x84, 0x8e, 0x4e, 0x5f, 0xcc, 0xce, 0x43, 0xc1, 0x9e, 0xf3, 0x94, 0x63, 0xd5, 0xfc, 0xa6, 0xa9, 0xfe, 0x8c,
0x61, 0xdf, 0x8e, 0xdf, 0x97, 0x8b, 0x8b, 0x80, 0xd3, 0x17, 0x2c, 0xe5, 0x58, 0x35, 0xff, 0xdf, 0xa0, 0x5b, 0xe8, 0x8a, 0xb5, 0x2a, 0x66, 0x49, 0x9c, 0x55, 0x5e, 0x3e, 0x55, 0x33, 0xf6, 0xa1,
0x54, 0x7f, 0x75, 0xa0, 0x5b, 0xb8, 0x15, 0x1b, 0x55, 0x7c, 0x0f, 0xee, 0x24, 0x0c, 0x78, 0x14, 0x97, 0xe5, 0x95, 0x0f, 0xc4, 0x92, 0x6d, 0x75, 0xa2, 0x1b, 0xb7, 0x24, 0xea, 0xab, 0x4c, 0xd1,
0xea, 0x12, 0xec, 0x34, 0x2f, 0x1b, 0xf3, 0x52, 0xf3, 0x17, 0x50, 0xab, 0x58, 0x6a, 0x66, 0x46, 0xe5, 0xf8, 0x59, 0x47, 0xf4, 0x33, 0xd8, 0x5d, 0xf6, 0x17, 0xe1, 0x49, 0x48, 0x59, 0xd6, 0x56,
0x1e, 0xf4, 0xb2, 0xea, 0x75, 0x3a, 0xfb, 0x9e, 0x2a, 0xd9, 0xd6, 0xcb, 0xb1, 0x7d, 0x8b, 0x1c, 0xf7, 0xca, 0xca, 0x90, 0x12, 0x88, 0x54, 0x37, 0xf9, 0xdf, 0xc0, 0x5e, 0x0d, 0xb5, 0xf6, 0xe0,
0x9e, 0xcc, 0x74, 0x4f, 0x86, 0xd4, 0xa6, 0x72, 0x3e, 0x83, 0xfd, 0xe4, 0x16, 0x62, 0x16, 0x07, 0x55, 0x2f, 0x83, 0xe6, 0xea, 0x97, 0x81, 0x3f, 0x87, 0xbb, 0xb7, 0x0c, 0xc6, 0xff, 0xb7, 0x6d,
0x84, 0x66, 0x97, 0xef, 0x7e, 0x59, 0x3f, 0x5c, 0x02, 0xe1, 0x6a, 0x90, 0xf7, 0x0d, 0x1c, 0xd4, 0x9e, 0xc1, 0x8e, 0x99, 0x0d, 0x8b, 0x88, 0x7d, 0xce, 0x95, 0xa2, 0x17, 0x1c, 0x3f, 0x84, 0x36,
0x50, 0x1b, 0x37, 0x5e, 0xf7, 0x8a, 0x69, 0xae, 0x7f, 0xc5, 0x78, 0x4b, 0xb8, 0x77, 0xcb, 0xf8, 0xcb, 0xc6, 0x9c, 0xe9, 0xf5, 0x41, 0x65, 0x8e, 0x2c, 0x22, 0x56, 0x1a, 0x75, 0x29, 0xdc, 0x7f,
0xfc, 0x6f, 0x2f, 0xd7, 0x73, 0xd8, 0xd3, 0x13, 0x64, 0x15, 0xd2, 0xcf, 0x99, 0x94, 0xe4, 0x92, 0x05, 0x6f, 0xaf, 0xf0, 0xdb, 0xd1, 0x19, 0x04, 0xee, 0x35, 0xaf, 0x96, 0x31, 0x2b, 0xf3, 0x63,
0xa1, 0x47, 0xd0, 0xa6, 0xd9, 0x30, 0xd4, 0x13, 0x61, 0x50, 0x99, 0x36, 0xab, 0x90, 0x96, 0x06, 0x94, 0xf9, 0xcd, 0x00, 0xcf, 0xd1, 0xf9, 0x28, 0x1e, 0xdb, 0x1b, 0xcf, 0x71, 0xf8, 0x04, 0xda,
0x62, 0x0a, 0xf7, 0x5e, 0xc3, 0x5b, 0x6b, 0xfc, 0x66, 0xc0, 0xfa, 0xbe, 0xfd, 0x78, 0x90, 0x49, 0x32, 0x0b, 0x69, 0x6e, 0xb3, 0x98, 0x75, 0xfd, 0xbb, 0x84, 0xa4, 0xe8, 0xfb, 0x27, 0x80, 0xeb,
0xce, 0xca, 0x94, 0x19, 0x67, 0x7e, 0x3d, 0xe6, 0x73, 0x74, 0x3e, 0xb0, 0x27, 0xe6, 0xc4, 0x73, 0xa2, 0xe0, 0x0e, 0x6c, 0x8e, 0x82, 0xa9, 0x88, 0xfa, 0x0d, 0x0c, 0xb0, 0xf5, 0x52, 0x0a, 0xcd,
0x1c, 0x3a, 0x85, 0xb6, 0xc8, 0x52, 0xea, 0xd3, 0x2c, 0x56, 0x5d, 0xff, 0xda, 0xc1, 0x29, 0xfa, 0x65, 0x1f, 0x99, 0x67, 0x73, 0x43, 0x5c, 0xf6, 0x9b, 0x8f, 0x1f, 0xfd, 0x76, 0x3d, 0x40, 0x57,
0xc1, 0x29, 0xa0, 0xba, 0x28, 0xa8, 0x03, 0xdb, 0x63, 0x7f, 0xce, 0xc3, 0x7e, 0x03, 0x01, 0xec, 0xd7, 0x03, 0xf4, 0xe7, 0xf5, 0x00, 0xfd, 0x70, 0x33, 0x68, 0x5c, 0xdd, 0x0c, 0x1a, 0x7f, 0xdc,
0xbc, 0x12, 0x5c, 0x31, 0xd1, 0x77, 0xf4, 0xb3, 0x3e, 0x21, 0x26, 0xfa, 0xcd, 0x27, 0x8f, 0x7f, 0x0c, 0x1a, 0xaf, 0xde, 0xff, 0x57, 0x5f, 0x7d, 0xe7, 0x5b, 0xf6, 0xe7, 0xc3, 0xbf, 0x03, 0x00,
0xb9, 0x1e, 0x38, 0x57, 0xd7, 0x03, 0xe7, 0x8f, 0xeb, 0x81, 0xf3, 0xc3, 0xcd, 0xa0, 0x71, 0x75, 0x00, 0xff, 0xff, 0x34, 0xb4, 0xa5, 0x8e, 0x25, 0x0a, 0x00, 0x00,
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,
} }
func (m *RawAclRecord) Marshal() (dAtA []byte, err error) { func (m *RawAclRecord) Marshal() (dAtA []byte, err error) {
@ -1381,11 +1363,6 @@ func (m *AclRoot) MarshalToSizedBuffer(dAtA []byte) (int, error) {
if m.Timestamp != 0 { if m.Timestamp != 0 {
i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp)) i = encodeVarintAclrecord(dAtA, i, uint64(m.Timestamp))
i-- i--
dAtA[i] = 0x30
}
if m.CurrentReadKeyHash != 0 {
i = encodeVarintAclrecord(dAtA, i, uint64(m.CurrentReadKeyHash))
i--
dAtA[i] = 0x28 dAtA[i] = 0x28
} }
if len(m.DerivationScheme) > 0 { if len(m.DerivationScheme) > 0 {
@ -1814,7 +1791,7 @@ func (m *AclUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.EncryptedReadKeys[iNdEx]) copy(dAtA[i:], m.EncryptedReadKeys[iNdEx])
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx]))) i = encodeVarintAclrecord(dAtA, i, uint64(len(m.EncryptedReadKeys[iNdEx])))
i-- i--
dAtA[i] = 0x2a dAtA[i] = 0x22
} }
} }
if len(m.AcceptPubKey) > 0 { if len(m.AcceptPubKey) > 0 {
@ -1822,20 +1799,13 @@ func (m *AclUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
copy(dAtA[i:], m.AcceptPubKey) copy(dAtA[i:], m.AcceptPubKey)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptPubKey))) i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptPubKey)))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x1a
} }
if len(m.AcceptSignature) > 0 { if len(m.AcceptSignature) > 0 {
i -= len(m.AcceptSignature) i -= len(m.AcceptSignature)
copy(dAtA[i:], m.AcceptSignature) copy(dAtA[i:], m.AcceptSignature)
i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptSignature))) i = encodeVarintAclrecord(dAtA, i, uint64(len(m.AcceptSignature)))
i-- 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 dAtA[i] = 0x12
} }
if len(m.Identity) > 0 { if len(m.Identity) > 0 {
@ -2192,9 +2162,6 @@ func (m *AclRoot) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovAclrecord(uint64(l)) n += 1 + l + sovAclrecord(uint64(l))
} }
if m.CurrentReadKeyHash != 0 {
n += 1 + sovAclrecord(uint64(m.CurrentReadKeyHash))
}
if m.Timestamp != 0 { if m.Timestamp != 0 {
n += 1 + sovAclrecord(uint64(m.Timestamp)) n += 1 + sovAclrecord(uint64(m.Timestamp))
} }
@ -2392,10 +2359,6 @@ func (m *AclUserJoin) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovAclrecord(uint64(l)) n += 1 + l + sovAclrecord(uint64(l))
} }
l = len(m.EncryptionKey)
if l > 0 {
n += 1 + l + sovAclrecord(uint64(l))
}
l = len(m.AcceptSignature) l = len(m.AcceptSignature)
if l > 0 { if l > 0 {
n += 1 + l + sovAclrecord(uint64(l)) n += 1 + l + sovAclrecord(uint64(l))
@ -3188,25 +3151,6 @@ func (m *AclRoot) Unmarshal(dAtA []byte) error {
m.DerivationScheme = string(dAtA[iNdEx:postIndex]) m.DerivationScheme = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 5: 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 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType)
} }
@ -4237,40 +4181,6 @@ func (m *AclUserJoin) Unmarshal(dAtA []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
case 2: 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 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AcceptSignature", wireType) 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{} m.AcceptSignature = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 4: case 3:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field AcceptPubKey", wireType) 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{} m.AcceptPubKey = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 5: case 4:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType) return fmt.Errorf("proto: wrong wireType = %d for field EncryptedReadKeys", wireType)
} }

View File

@ -27,8 +27,7 @@ message AclRoot {
string spaceId = 2; string spaceId = 2;
bytes encryptedReadKey = 3; bytes encryptedReadKey = 3;
string derivationScheme = 4; string derivationScheme = 4;
uint64 currentReadKeyHash = 5; int64 timestamp = 5;
int64 timestamp = 6;
} }
message AclContentValue { message AclContentValue {

View File

@ -2,128 +2,130 @@ package list
import ( import (
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto" "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/cidutil"
"github.com/anytypeio/any-sync/util/crypto" "github.com/anytypeio/any-sync/util/crypto"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"time"
) )
// remove interface
type AclRecordBuilder interface { type AclRecordBuilder interface {
ConvertFromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) FromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error)
BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error)
} }
type aclRecordBuilder struct { type aclRecordBuilder struct {
id string id string
keychain *keychain.Keychain keyStorage crypto.KeyStorage
} }
func newAclRecordBuilder(id string, keychain *keychain.Keychain) AclRecordBuilder { func newAclRecordBuilder(id string, keyStorage crypto.KeyStorage) AclRecordBuilder {
return &aclRecordBuilder{ return &aclRecordBuilder{
id: id, id: id,
keychain: keychain, keyStorage: keyStorage,
} }
} }
func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error) { // TODO: update with new logic
acceptPrivKey, err := crypto.NewSigningEd25519PrivKeyFromBytes(acceptPrivKeyBytes) //func (a *aclRecordBuilder) BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *AclState) (rec *aclrecordproto.RawAclRecord, err error) {
if err != nil { // acceptPrivKey, err := crypto.NewSigningEd25519PrivKeyFromBytes(acceptPrivKeyBytes)
return // if err != nil {
} // return
acceptPubKeyBytes, err := acceptPrivKey.GetPublic().Raw() // }
if err != nil { // acceptPubKeyBytes, err := acceptPrivKey.GetPublic().Raw()
return // if err != nil {
} // return
encSymKey, err := crypto.UnmarshallAESKey(encSymKeyBytes) // }
if err != nil { // encSymKey, err := crypto.UnmarshallAESKey(encSymKeyBytes)
return // 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) func (a *aclRecordBuilder) FromRaw(rawIdRecord *aclrecordproto.RawAclRecordWithId) (rec *AclRecord, err error) {
if err != nil { var (
return rawRec = &aclrecordproto.RawAclRecord{}
} pubKey crypto.PubKey
)
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{}
err = proto.Unmarshal(rawIdRecord.Payload, rawRec) err = proto.Unmarshal(rawIdRecord.Payload, rawRec)
if err != nil { if err != nil {
return return
} }
if rawIdRecord.Id == a.id { if rawIdRecord.Id == a.id {
aclRoot := &aclrecordproto.AclRoot{} aclRoot := &aclrecordproto.AclRoot{}
err = proto.Unmarshal(rawRec.Payload, aclRoot) err = proto.Unmarshal(rawRec.Payload, aclRoot)
if err != nil { if err != nil {
return return
} }
pubKey, err = a.keyStorage.PubKeyFromProto(aclRoot.Identity)
if err != nil {
return
}
rec = &AclRecord{ rec = &AclRecord{
Id: rawIdRecord.Id, Id: rawIdRecord.Id,
CurrentReadKeyHash: aclRoot.CurrentReadKeyHash, ReadKeyId: rawIdRecord.Id,
Timestamp: aclRoot.Timestamp, Timestamp: aclRoot.Timestamp,
Signature: rawRec.Signature, Signature: rawRec.Signature,
Identity: aclRoot.Identity, Identity: pubKey,
Model: aclRoot, Model: aclRoot,
} }
} else { } else {
@ -132,34 +134,31 @@ func (a *aclRecordBuilder) ConvertFromRaw(rawIdRecord *aclrecordproto.RawAclReco
if err != nil { if err != nil {
return return
} }
pubKey, err = a.keyStorage.PubKeyFromProto(aclRecord.Identity)
if err != nil {
return
}
rec = &AclRecord{ rec = &AclRecord{
Id: rawIdRecord.Id, Id: rawIdRecord.Id,
PrevId: aclRecord.PrevId, PrevId: aclRecord.PrevId,
CurrentReadKeyHash: aclRecord.CurrentReadKeyHash, ReadKeyId: aclRecord.ReadKeyId,
Timestamp: aclRecord.Timestamp, Timestamp: aclRecord.Timestamp,
Data: aclRecord.Data, Data: aclRecord.Data,
Signature: rawRec.Signature, Signature: rawRec.Signature,
Identity: aclRecord.Identity, Identity: pubKey,
} }
} }
err = verifyRaw(a.keychain, rawRec, rawIdRecord, rec.Identity) err = verifyRaw(pubKey, rawRec, rawIdRecord)
return return
} }
func verifyRaw( func verifyRaw(
keychain *keychain.Keychain, pubKey crypto.PubKey,
rawRec *aclrecordproto.RawAclRecord, rawRec *aclrecordproto.RawAclRecord,
recWithId *aclrecordproto.RawAclRecordWithId, recWithId *aclrecordproto.RawAclRecordWithId) (err error) {
identity []byte) (err error) {
identityKey, err := keychain.GetOrAdd(string(identity))
if err != nil {
return
}
// verifying signature // verifying signature
res, err := identityKey.Verify(rawRec.Payload, rawRec.Signature) res, err := pubKey.Verify(rawRec.Payload, rawRec.Signature)
if err != nil { if err != nil {
return return
} }

View File

@ -1,18 +1,13 @@
package list package list
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"hash/fnv"
"github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/app/logger"
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto" "github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto"
"github.com/anytypeio/any-sync/commonspace/object/keychain" "github.com/anytypeio/any-sync/commonspace/object/keychain"
"github.com/anytypeio/any-sync/util/crypto" "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" "github.com/gogo/protobuf/proto"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -36,22 +31,22 @@ var (
) )
type UserPermissionPair struct { type UserPermissionPair struct {
Identity string Identity crypto.PubKey
Permission aclrecordproto.AclUserPermissions Permission aclrecordproto.AclUserPermissions
} }
type AclState struct { type AclState struct {
id string id string
currentReadKeyHash uint64 currentReadKeyId string
userReadKeys map[uint64]*crypto.AESKey userReadKeys map[string]crypto.SymKey
userStates map[string]*aclrecordproto.AclUserState userStates map[string]AclUserState
userInvites map[string]*aclrecordproto.AclUserInvite statesAtRecord map[string][]AclUserState
encryptionKey encryptionkey.PrivKey //userInvites map[string]*aclrecordproto.AclUserInvite
signingKey signingkey.PrivKey key crypto.PrivKey
pubKey crypto.PubKey
keyStore crypto.KeyStorage
totalReadKeys int totalReadKeys int
identity string
permissionsAtRecord map[string][]UserPermissionPair
lastRecordId string lastRecordId string
keychain *keychain.Keychain keychain *keychain.Keychain
@ -59,63 +54,57 @@ type AclState struct {
func newAclStateWithKeys( func newAclStateWithKeys(
id string, id string,
signingKey signingkey.PrivKey, key crypto.PrivKey) (*AclState, error) {
encryptionKey encryptionkey.PrivKey) (*AclState, error) {
identity, err := signingKey.GetPublic().Raw()
if err != nil {
return nil, err
}
return &AclState{ return &AclState{
id: id, id: id,
identity: string(identity), key: key,
signingKey: signingKey, pubKey: key.GetPublic(),
encryptionKey: encryptionKey, userReadKeys: make(map[string]crypto.SymKey),
userReadKeys: make(map[uint64]*crypto.AESKey), userStates: make(map[string]AclUserState),
userStates: make(map[string]*aclrecordproto.AclUserState), statesAtRecord: make(map[string][]AclUserState),
userInvites: make(map[string]*aclrecordproto.AclUserInvite), //userInvites: make(map[string]*aclrecordproto.AclUserInvite),
permissionsAtRecord: make(map[string][]UserPermissionPair),
}, nil }, nil
} }
func newAclState(id string) *AclState { func newAclState(id string) *AclState {
return &AclState{ return &AclState{
id: id, id: id,
userReadKeys: make(map[uint64]*crypto.AESKey), userReadKeys: make(map[string]crypto.SymKey),
userStates: make(map[string]*aclrecordproto.AclUserState), userStates: make(map[string]AclUserState),
userInvites: make(map[string]*aclrecordproto.AclUserInvite), statesAtRecord: make(map[string][]AclUserState),
permissionsAtRecord: make(map[string][]UserPermissionPair), //userInvites: make(map[string]*aclrecordproto.AclUserInvite),
} }
} }
func (st *AclState) CurrentReadKeyHash() uint64 { func (st *AclState) CurrentReadKeyId() string {
return st.currentReadKeyHash return st.currentReadKeyId
} }
func (st *AclState) CurrentReadKey() (*crypto.AESKey, error) { func (st *AclState) CurrentReadKey() (crypto.SymKey, error) {
key, exists := st.userReadKeys[st.currentReadKeyHash] key, exists := st.userReadKeys[st.currentReadKeyId]
if !exists { if !exists {
return nil, ErrNoReadKey return nil, ErrNoReadKey
} }
return key, nil return key, nil
} }
func (st *AclState) UserReadKeys() map[uint64]*crypto.AESKey { func (st *AclState) UserReadKeys() map[string]crypto.SymKey {
return st.userReadKeys return st.userReadKeys
} }
func (st *AclState) PermissionsAtRecord(id string, identity string) (UserPermissionPair, error) { func (st *AclState) StateAtRecord(id string, pubKey crypto.PubKey) (AclUserState, error) {
permissions, ok := st.permissionsAtRecord[id] userState, ok := st.statesAtRecord[id]
if !ok { if !ok {
log.Errorf("missing record at id %s", id) log.Errorf("missing record at id %s", id)
return UserPermissionPair{}, ErrNoSuchRecord return AclUserState{}, ErrNoSuchRecord
} }
for _, perm := range permissions { for _, perm := range userState {
if perm.Identity == identity { if perm.PubKey.Equals(pubKey) {
return perm, nil return perm, nil
} }
} }
return UserPermissionPair{}, ErrNoSuchUser return AclUserState{}, ErrNoSuchUser
} }
func (st *AclState) applyRecord(record *AclRecord) (err error) { func (st *AclState) applyRecord(record *AclRecord) (err error) {
@ -129,24 +118,18 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) {
return return
} }
if record.Id == st.id { if record.Id == st.id {
root, ok := record.Model.(*aclrecordproto.AclRoot) err = st.applyRoot(record)
if !ok {
return ErrIncorrectRoot
}
err = st.applyRoot(root)
if err != nil { if err != nil {
return return
} }
st.permissionsAtRecord[record.Id] = []UserPermissionPair{ st.statesAtRecord[record.Id] = []AclUserState{
{Identity: string(root.Identity), Permission: aclrecordproto.AclUserPermissions_Admin}, {PubKey: record.Identity, Permissions: aclrecordproto.AclUserPermissions_Admin},
} }
return return
} }
aclData := &aclrecordproto.AclData{}
if record.Model != nil { if record.Model == nil {
aclData = record.Model.(*aclrecordproto.AclData) aclData := &aclrecordproto.AclData{}
} else {
err = proto.Unmarshal(record.Data, aclData) err = proto.Unmarshal(record.Data, aclData)
if err != nil { if err != nil {
return return
@ -154,109 +137,96 @@ func (st *AclState) applyRecord(record *AclRecord) (err error) {
record.Model = aclData record.Model = aclData
} }
err = st.applyChangeData(aclData, record.CurrentReadKeyHash, record.Identity) err = st.applyChangeData(record)
if err != nil { if err != nil {
return return
} }
// getting all permissions for users at record // getting all states for users at record
var permissions []UserPermissionPair var states []AclUserState
for _, state := range st.userStates { for _, state := range st.userStates {
permission := UserPermissionPair{ states = append(states, state)
Identity: string(state.Identity),
Permission: state.Permissions,
}
permissions = append(permissions, permission)
} }
st.permissionsAtRecord[record.Id] = permissions st.statesAtRecord[record.Id] = states
return return
} }
func (st *AclState) applyRoot(root *aclrecordproto.AclRoot) (err error) { func (st *AclState) applyRoot(record *AclRecord) (err error) {
if st.signingKey != nil && st.encryptionKey != nil && st.identity == string(root.Identity) { if st.key != nil && st.pubKey.Equals(record.Identity) {
err = st.saveReadKeyFromRoot(root) err = st.saveReadKeyFromRoot(record)
if err != nil { if err != nil {
return return
} }
} }
// adding user to the list // adding user to the list
userState := &aclrecordproto.AclUserState{ userState := AclUserState{
Identity: root.Identity, PubKey: record.Identity,
EncryptionKey: root.EncryptionKey,
Permissions: aclrecordproto.AclUserPermissions_Admin, Permissions: aclrecordproto.AclUserPermissions_Admin,
} }
st.currentReadKeyHash = root.CurrentReadKeyHash st.currentReadKeyId = record.ReadKeyId
st.userStates[string(root.Identity)] = userState st.userStates[mapKeyFromPubKey(record.Identity)] = userState
st.totalReadKeys++ st.totalReadKeys++
return return
} }
func (st *AclState) saveReadKeyFromRoot(root *aclrecordproto.AclRoot) (err error) { func (st *AclState) saveReadKeyFromRoot(record *AclRecord) (err error) {
var readKey *crypto.AESKey var readKey crypto.SymKey
if len(root.GetDerivationScheme()) != 0 { root, ok := record.Model.(*aclrecordproto.AclRoot)
var encPrivKey []byte if !ok {
encPrivKey, err = st.encryptionKey.Raw() return ErrIncorrectRoot
if err != nil {
return
} }
var signPrivKey []byte if len(root.GetDerivationScheme()) != 0 {
signPrivKey, err = st.signingKey.Raw() var keyBytes []byte
keyBytes, err = st.key.Raw()
if err != nil { if err != nil {
return return
} }
readKey, err = aclrecordproto.AclReadKeyDerive(signPrivKey, encPrivKey) readKey, err = crypto.DeriveAccountSymmetric(keyBytes)
if err != nil { if err != nil {
return return
} }
} else { } else {
readKey, _, err = st.decryptReadKeyAndHash(root.EncryptedReadKey) readKey, err = st.decryptReadKey(root.EncryptedReadKey)
if err != nil { if err != nil {
return return
} }
} }
hasher := fnv.New64() st.userReadKeys[record.Id] = readKey
_, err = hasher.Write(readKey.Bytes())
if err != nil {
return
}
if hasher.Sum64() != root.CurrentReadKeyHash {
return ErrIncorrectRoot
}
st.userReadKeys[root.CurrentReadKeyHash] = readKey
return return
} }
func (st *AclState) applyChangeData(changeData *aclrecordproto.AclData, hash uint64, identity []byte) (err error) { func (st *AclState) applyChangeData(record *AclRecord) (err error) {
defer func() { defer func() {
if err != nil { if err != nil {
return return
} }
if hash != st.currentReadKeyHash { if record.ReadKeyId != st.currentReadKeyId {
st.totalReadKeys++ st.totalReadKeys++
st.currentReadKeyHash = hash st.currentReadKeyId = record.ReadKeyId
} }
}() }()
model := record.Model.(*aclrecordproto.AclData)
if !st.isUserJoin(changeData) { if !st.isUserJoin(model) {
// we check signature when we add this to the List, so no need to do it here // 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 err = ErrNoSuchUser
return return
} }
if !st.HasPermission(identity, aclrecordproto.AclUserPermissions_Admin) { // only Admins can do non-user join changes
err = fmt.Errorf("user %s must have admin permissions", identity) 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 return
} }
} }
for _, ch := range changeData.GetAclContent() { for _, ch := range model.GetAclContent() {
if err = st.applyChangeContent(ch); err != nil { if err = st.applyChangeContent(ch, record.Id); err != nil {
log.Info("error while applying changes: %v; ignore", zap.Error(err)) log.Info("error while applying changes: %v; ignore", zap.Error(err))
return err return err
} }
@ -265,26 +235,29 @@ func (st *AclState) applyChangeData(changeData *aclrecordproto.AclData, hash uin
return nil return nil
} }
func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue) error { func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, recordId string) error {
switch { switch {
case ch.GetUserPermissionChange() != nil: case ch.GetUserPermissionChange() != nil:
return st.applyUserPermissionChange(ch.GetUserPermissionChange()) return st.applyUserPermissionChange(ch.GetUserPermissionChange(), recordId)
case ch.GetUserAdd() != nil: case ch.GetUserAdd() != nil:
return st.applyUserAdd(ch.GetUserAdd()) return st.applyUserAdd(ch.GetUserAdd(), recordId)
case ch.GetUserRemove() != nil: case ch.GetUserRemove() != nil:
return st.applyUserRemove(ch.GetUserRemove()) return st.applyUserRemove(ch.GetUserRemove(), recordId)
case ch.GetUserInvite() != nil: case ch.GetUserInvite() != nil:
return st.applyUserInvite(ch.GetUserInvite()) return st.applyUserInvite(ch.GetUserInvite(), recordId)
case ch.GetUserJoin() != nil: case ch.GetUserJoin() != nil:
return st.applyUserJoin(ch.GetUserJoin()) return st.applyUserJoin(ch.GetUserJoin(), recordId)
default: default:
return fmt.Errorf("unexpected change type: %v", ch) return fmt.Errorf("unexpected change type: %v", ch)
} }
} }
func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissionChange) error { func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissionChange, recordId string) error {
chIdentity := string(ch.Identity) chIdentity, err := st.keyStore.PubKeyFromProto(ch.Identity)
state, exists := st.userStates[chIdentity] if err != nil {
return err
}
state, exists := st.userStates[mapKeyFromPubKey(chIdentity)]
if !exists { if !exists {
return ErrNoSuchUser return ErrNoSuchUser
} }
@ -293,131 +266,132 @@ func (st *AclState) applyUserPermissionChange(ch *aclrecordproto.AclUserPermissi
return nil return nil
} }
func (st *AclState) applyUserInvite(ch *aclrecordproto.AclUserInvite) error { func (st *AclState) applyUserInvite(ch *aclrecordproto.AclUserInvite, recordId string) error {
st.userInvites[string(ch.AcceptPublicKey)] = ch //acceptPubKey, err := st.keyStore.PubKeyFromProto(ch.AcceptPublicKey)
//if err != nil {
// return nil
//}
//st.userInvites[string(ch.AcceptPublicKey)] = ch
return nil return nil
} }
func (st *AclState) applyUserJoin(ch *aclrecordproto.AclUserJoin) error { func (st *AclState) applyUserJoin(ch *aclrecordproto.AclUserJoin, recordId string) error {
invite, exists := st.userInvites[string(ch.AcceptPubKey)] //invite, exists := st.userInvites[string(ch.AcceptPubKey)]
if !exists { //if !exists {
return fmt.Errorf("no such invite with such public key %s", keys.EncodeBytesToString(ch.AcceptPubKey)) // // 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) //}
//chIdentity := string(ch.Identity)
if _, exists = st.userStates[chIdentity]; exists { //if _, exists = st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists // return ErrUserAlreadyExists
} //}
//
// validating signature //// validating signature
signature := ch.GetAcceptSignature() //signature := ch.GetAcceptSignature()
verificationKey, err := crypto.NewSigningEd25519PubKeyFromBytes(invite.AcceptPublicKey) //verificationKey, err := crypto.UnmarshalEd25519PublicKeyProto(invite.AcceptPublicKey)
if err != nil { //if err != nil {
return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err) // return fmt.Errorf("public key verifying invite accepts is given in incorrect format: %v", err)
} //}
//
res, err := verificationKey.Verify(ch.Identity, signature) //// TODO: intuitively we need to sign not only the identity but a more complicated payload
if err != nil { //res, err := verificationKey.Verify(ch.Identity, signature)
return fmt.Errorf("verification returned error: %w", err) //if err != nil {
} // return fmt.Errorf("verification returned error: %w", err)
if !res { //}
return ErrInvalidSignature //if !res {
} // return ErrInvalidSignature
//}
// if ourselves -> we need to decrypt the read keys //
if st.identity == chIdentity { //// if ourselves -> we need to decrypt the read keys
for _, key := range ch.EncryptedReadKeys { //if st.identity == chIdentity {
key, hash, err := st.decryptReadKeyAndHash(key) // for _, key := range ch.EncryptedReadKeys {
if err != nil { // key, err := st.decryptReadKey(key)
return ErrFailedToDecrypt // if err != nil {
} // return ErrFailedToDecrypt
// }
st.userReadKeys[hash] = key //
} // st.userReadKeys[recordId] = key
} // }
//}
// adding user to the list //
userState := &aclrecordproto.AclUserState{ //// adding user to the list
Identity: ch.Identity, //userState := &aclrecordproto.AclUserState{
EncryptionKey: ch.EncryptionKey, // Identity: ch.Identity,
Permissions: invite.Permissions, // Permissions: invite.Permissions,
} //}
st.userStates[chIdentity] = userState //st.userStates[chIdentity] = userState
return nil return nil
} }
func (st *AclState) applyUserAdd(ch *aclrecordproto.AclUserAdd) error { func (st *AclState) applyUserAdd(ch *aclrecordproto.AclUserAdd, recordId string) error {
chIdentity := string(ch.Identity) //chIdentity := string(ch.Identity)
if _, exists := st.userStates[chIdentity]; exists { //if _, exists := st.userStates[chIdentity]; exists {
return ErrUserAlreadyExists // return ErrUserAlreadyExists
} //}
//
st.userStates[chIdentity] = &aclrecordproto.AclUserState{ //st.userStates[chIdentity] = &aclrecordproto.AclUserState{
Identity: ch.Identity, // Identity: ch.Identity,
EncryptionKey: ch.EncryptionKey, // EncryptionKey: ch.EncryptionKey,
Permissions: ch.Permissions, // Permissions: ch.Permissions,
} //}
//
if chIdentity == st.identity { //if chIdentity == st.identity {
for _, key := range ch.EncryptedReadKeys { // for _, key := range ch.EncryptedReadKeys {
key, hash, err := st.decryptReadKeyAndHash(key) // key, hash, err := st.decryptReadKey(key)
if err != nil { // if err != nil {
return ErrFailedToDecrypt // return ErrFailedToDecrypt
} // }
//
st.userReadKeys[hash] = key // st.userReadKeys[hash] = key
} // }
} //}
return nil return nil
} }
func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove) error { func (st *AclState) applyUserRemove(ch *aclrecordproto.AclUserRemove, recordId string) error {
chIdentity := string(ch.Identity) //chIdentity := string(ch.Identity)
if chIdentity == st.identity { //if chIdentity == st.identity {
return ErrDocumentForbidden // return ErrDocumentForbidden
} //}
//
if _, exists := st.userStates[chIdentity]; !exists { //if _, exists := st.userStates[chIdentity]; !exists {
return ErrNoSuchUser // return ErrNoSuchUser
} //}
//
delete(st.userStates, chIdentity) //delete(st.userStates, chIdentity)
//
for _, replace := range ch.ReadKeyReplaces { //for _, replace := range ch.ReadKeyReplaces {
repIdentity := string(replace.Identity) // repIdentity := string(replace.Identity)
// if this is our identity then we have to decrypt the key // // if this is our identity then we have to decrypt the key
if repIdentity == st.identity { // if repIdentity == st.identity {
key, hash, err := st.decryptReadKeyAndHash(replace.EncryptedReadKey) // key, hash, err := st.decryptReadKey(replace.EncryptedReadKey)
if err != nil { // if err != nil {
return ErrFailedToDecrypt // return ErrFailedToDecrypt
} // }
//
st.userReadKeys[hash] = key // st.userReadKeys[hash] = key
break // break
} // }
} //}
return nil return nil
} }
func (st *AclState) decryptReadKeyAndHash(msg []byte) (*crypto.AESKey, uint64, error) { func (st *AclState) decryptReadKey(msg []byte) (crypto.SymKey, error) {
decrypted, err := st.encryptionKey.Decrypt(msg) decrypted, err := st.key.Decrypt(msg)
if err != nil { if err != nil {
return nil, 0, ErrFailedToDecrypt return nil, ErrFailedToDecrypt
} }
key, err := crypto.UnmarshallAESKey(decrypted) key, err := crypto.UnmarshallAESKey(decrypted)
if err != nil { if err != nil {
return nil, 0, ErrFailedToDecrypt return nil, ErrFailedToDecrypt
}
return key, nil
} }
hasher := fnv.New64() func (st *AclState) HasPermission(identity crypto.PubKey, permission aclrecordproto.AclUserPermissions) bool {
hasher.Write(decrypted) state, exists := st.userStates[mapKeyFromPubKey(identity)]
return key, hasher.Sum64(), nil
}
func (st *AclState) HasPermission(identity []byte, permission aclrecordproto.AclUserPermissions) bool {
state, exists := st.userStates[string(identity)]
if !exists { if !exists {
return false return false
} }
@ -430,36 +404,32 @@ func (st *AclState) isUserJoin(data *aclrecordproto.AclData) bool {
return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil return data.GetAclContent() != nil && data.GetAclContent()[0].GetUserJoin() != nil
} }
func (st *AclState) isUserAdd(data *aclrecordproto.AclData, identity []byte) bool { //func (st *AclState) isUserAdd(data *aclrecordproto.AclData, identity []byte) bool {
// if we have a UserAdd, then it should always be the first one applied // // if we have a UserAdd, then it should always be the first one applied
userAdd := data.GetAclContent()[0].GetUserAdd() // userAdd := data.GetAclContent()[0].GetUserAdd()
return data.GetAclContent() != nil && userAdd != nil && bytes.Compare(userAdd.GetIdentity(), identity) == 0 // 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 return st.userStates
} }
func (st *AclState) Invite(acceptPubKey []byte) (invite *aclrecordproto.AclUserInvite, err error) { //func (st *AclState) Invite(acceptPubKey []byte) (invite *aclrecordproto.AclUserInvite, err error) {
invite, exists := st.userInvites[string(acceptPubKey)] // invite, exists := st.userInvites[string(acceptPubKey)]
if !exists { // if !exists {
err = ErrNoSuchInvite // err = ErrNoSuchInvite
return // return
} // }
if len(invite.EncryptedReadKeys) != st.totalReadKeys { // if len(invite.EncryptedReadKeys) != st.totalReadKeys {
err = ErrOldInvite // err = ErrOldInvite
} // }
return // 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) LastRecordId() string { func (st *AclState) LastRecordId() string {
return st.lastRecordId return st.lastRecordId
} }
func mapKeyFromPubKey(pubKey crypto.PubKey) string {
return string(pubKey.Storage())
}

View File

@ -9,6 +9,7 @@ import (
"github.com/anytypeio/any-sync/commonspace/object/acl/aclrecordproto" "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/acl/liststorage"
"github.com/anytypeio/any-sync/commonspace/object/keychain" "github.com/anytypeio/any-sync/commonspace/object/keychain"
"github.com/anytypeio/any-sync/util/crypto"
"sync" "sync"
) )
@ -56,11 +57,11 @@ type aclList struct {
func BuildAclListWithIdentity(acc *accountdata.AccountData, storage liststorage.ListStorage) (AclList, error) { func BuildAclListWithIdentity(acc *accountdata.AccountData, storage liststorage.ListStorage) (AclList, error) {
builder := newAclStateBuilderWithIdentity(acc) 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) { 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) { 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 return
} }
record, err := recBuilder.ConvertFromRaw(rawRecordWithId) record, err := recBuilder.FromRaw(rawRecordWithId)
if err != nil { if err != nil {
return return
} }
@ -86,7 +87,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder AclRecordBuilder
return return
} }
record, err = recBuilder.ConvertFromRaw(rawRecordWithId) record, err = recBuilder.FromRaw(rawRecordWithId)
if err != nil { if err != nil {
return return
} }
@ -137,7 +138,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added
if _, ok := a.indexes[rawRec.Id]; ok { if _, ok := a.indexes[rawRec.Id]; ok {
return return
} }
record, err := a.recordBuilder.ConvertFromRaw(rawRec) record, err := a.recordBuilder.FromRaw(rawRec)
if err != nil { if err != nil {
return return
} }
@ -156,7 +157,7 @@ func (a *aclList) AddRawRecord(rawRec *aclrecordproto.RawAclRecordWithId) (added
} }
func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) { func (a *aclList) IsValidNext(rawRec *aclrecordproto.RawAclRecordWithId) (err error) {
_, err = a.recordBuilder.ConvertFromRaw(rawRec) _, err = a.recordBuilder.FromRaw(rawRec)
if err != nil { if err != nil {
return return
} }

View File

@ -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_Admin, aclList.AclState().UserStates()[idA].Permissions)
assert.Equal(t, aclrecordproto.AclUserPermissions_Writer, aclList.AclState().UserStates()[idB].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, 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 var records []*AclRecord
aclList.Iterate(func(record *AclRecord) (IsContinue bool) { aclList.Iterate(func(record *AclRecord) (IsContinue bool) {
@ -36,10 +36,10 @@ func TestAclList_AclState_UserInviteAndJoin(t *testing.T) {
// checking permissions at specific records // checking permissions at specific records
assert.Equal(t, 3, len(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") 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.NoError(t, err, "should have no error with permissions of B in the record 2")
assert.Equal(t, UserPermissionPair{ assert.Equal(t, UserPermissionPair{
Identity: idB, Identity: idB,
@ -63,7 +63,7 @@ func TestAclList_AclState_UserJoinAndRemove(t *testing.T) {
// checking final state // checking final state
assert.Equal(t, aclrecordproto.AclUserPermissions_Admin, aclList.AclState().UserStates()[idA].Permissions) 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, 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] _, exists := aclList.AclState().UserStates()[idB]
assert.Equal(t, false, exists) assert.Equal(t, false, exists)
@ -77,15 +77,15 @@ func TestAclList_AclState_UserJoinAndRemove(t *testing.T) {
// checking permissions at specific records // checking permissions at specific records
assert.Equal(t, 4, len(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.NoError(t, err, "should have no error with permissions of B in the record 2")
assert.Equal(t, UserPermissionPair{ assert.Equal(t, UserPermissionPair{
Identity: idB, Identity: idB,
Permission: aclrecordproto.AclUserPermissions_Writer, Permission: aclrecordproto.AclUserPermissions_Writer,
}, perm) }, 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") assert.Error(t, err, "B should have no permissions at record 3, because user should be removed")
} }

View 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
}

View File

@ -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
}

View File

@ -68,7 +68,7 @@ func (t *treeExporter) ExportUnencrypted(tree objecttree.ReadableObjectTree) (er
return false return false
} }
// that means that change is unencrypted // that means that change is unencrypted
change.ReadKeyHash = 0 change.ReadKeyId = 0
change.Data = data change.Data = data
err = putStorage(change) err = putStorage(change)
return err == nil return err == nil

View File

@ -20,7 +20,7 @@ type Change struct {
SnapshotId string SnapshotId string
IsSnapshot bool IsSnapshot bool
Timestamp int64 Timestamp int64
ReadKeyHash uint64 ReadKeyId string
Identity string Identity string
Data []byte Data []byte
Model interface{} Model interface{}
@ -38,7 +38,7 @@ func NewChange(id string, ch *treechangeproto.TreeChange, signature []byte) *Cha
PreviousIds: ch.TreeHeadIds, PreviousIds: ch.TreeHeadIds,
AclHeadId: ch.AclHeadId, AclHeadId: ch.AclHeadId,
Timestamp: ch.Timestamp, Timestamp: ch.Timestamp,
ReadKeyHash: ch.CurrentReadKeyHash, ReadKeyId: ch.ReadKeyId,
Id: id, Id: id,
Data: ch.ChangesData, Data: ch.ChangesData,
SnapshotId: ch.SnapshotBaseId, SnapshotId: ch.SnapshotBaseId,

View File

@ -17,7 +17,7 @@ type BuilderContent struct {
TreeHeadIds []string TreeHeadIds []string
AclHeadId string AclHeadId string
SnapshotBaseId string SnapshotBaseId string
CurrentReadKeyHash uint64 ReadKeyId string
Identity []byte Identity []byte
IsSnapshot bool IsSnapshot bool
SigningKey signingkey.PrivKey SigningKey signingkey.PrivKey
@ -164,7 +164,7 @@ func (c *changeBuilder) Build(payload BuilderContent) (ch *Change, rawIdChange *
TreeHeadIds: payload.TreeHeadIds, TreeHeadIds: payload.TreeHeadIds,
AclHeadId: payload.AclHeadId, AclHeadId: payload.AclHeadId,
SnapshotBaseId: payload.SnapshotBaseId, SnapshotBaseId: payload.SnapshotBaseId,
CurrentReadKeyHash: payload.CurrentReadKeyHash, ReadKeyId: payload.ReadKeyId,
Timestamp: time.Now().Unix(), Timestamp: time.Now().Unix(),
Identity: payload.Identity, Identity: payload.Identity,
IsSnapshot: payload.IsSnapshot, IsSnapshot: payload.IsSnapshot,
@ -216,7 +216,7 @@ func (c *changeBuilder) Marshall(ch *Change) (raw *treechangeproto.RawTreeChange
AclHeadId: ch.AclHeadId, AclHeadId: ch.AclHeadId,
SnapshotBaseId: ch.SnapshotId, SnapshotBaseId: ch.SnapshotId,
ChangesData: ch.Data, ChangesData: ch.Data,
CurrentReadKeyHash: ch.ReadKeyHash, ReadKeyId: ch.ReadKeyId,
Timestamp: ch.Timestamp, Timestamp: ch.Timestamp,
Identity: []byte(ch.Identity), Identity: []byte(ch.Identity),
IsSnapshot: ch.IsSnapshot, IsSnapshot: ch.IsSnapshot,

View File

@ -236,7 +236,7 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
} }
if content.IsEncrypted { if content.IsEncrypted {
readKeyHash = state.CurrentReadKeyHash() readKeyHash = state.CurrentReadKeyId()
readKey, err = state.CurrentReadKey() readKey, err = state.CurrentReadKey()
if err != nil { if err != nil {
return return
@ -246,7 +246,7 @@ func (ot *objectTree) prepareBuilderContent(content SignableChangeContent) (cnt
TreeHeadIds: ot.tree.Heads(), TreeHeadIds: ot.tree.Heads(),
AclHeadId: ot.aclList.Head().Id, AclHeadId: ot.aclList.Head().Id,
SnapshotBaseId: ot.tree.RootId(), SnapshotBaseId: ot.tree.RootId(),
CurrentReadKeyHash: readKeyHash, ReadKeyId: readKeyHash,
Identity: content.Identity, Identity: content.Identity,
IsSnapshot: content.IsSnapshot, IsSnapshot: content.IsSnapshot,
SigningKey: content.Key, SigningKey: content.Key,
@ -488,11 +488,11 @@ func (ot *objectTree) IterateFrom(id string, convert ChangeConvertFunc, iterate
} }
decrypt := func(c *Change) (decrypted []byte, err error) { decrypt := func(c *Change) (decrypted []byte, err error) {
// the change is not encrypted // the change is not encrypted
if c.ReadKeyHash == 0 { if c.ReadKeyId == 0 {
decrypted = c.Data decrypted = c.Data
return return
} }
readKey, exists := ot.keys[c.ReadKeyHash] readKey, exists := ot.keys[c.ReadKeyId]
if !exists { if !exists {
err = list.ErrNoReadKey err = list.ErrNoReadKey
return return

View File

@ -54,7 +54,7 @@ func (v *objectTreeValidator) validateChange(tree *Tree, aclList list.AclList, c
state = aclList.AclState() state = aclList.AclState()
) )
// checking if the user could write // 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 { if err != nil {
return return
} }

View File

@ -8,6 +8,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/anytypeio/any-sync/util/crypto/cryptoproto" "github.com/anytypeio/any-sync/util/crypto/cryptoproto"
"github.com/anytypeio/any-sync/util/strkey"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"io" "io"
"sync" "sync"
@ -119,6 +120,11 @@ func (k *Ed25519PrivKey) Decrypt(msg []byte) ([]byte, error) {
return DecryptX25519(k.privCurve, k.pubCurve, msg) 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. // Raw public key bytes.
func (k *Ed25519PubKey) Raw() ([]byte, error) { func (k *Ed25519PubKey) Raw() ([]byte, error) {
return k.pubKey, nil return k.pubKey, nil
@ -134,6 +140,11 @@ func (k *Ed25519PubKey) Encrypt(msg []byte) (data []byte, err error) {
return return
} }
// Storage returns underlying byte storage
func (k *Ed25519PubKey) Storage() []byte {
return k.pubKey
}
// Equals compares two ed25519 public keys. // Equals compares two ed25519 public keys.
func (k *Ed25519PubKey) Equals(o Key) bool { func (k *Ed25519PubKey) Equals(o Key) bool {
edk, ok := o.(*Ed25519PubKey) edk, ok := o.(*Ed25519PubKey)

View File

@ -38,6 +38,10 @@ type PubKey interface {
Verify(data []byte, sig []byte) (bool, error) Verify(data []byte, sig []byte) (bool, error)
// Marshall wraps key in proto encoding and marshalls it // Marshall wraps key in proto encoding and marshalls it
Marshall() ([]byte, error) Marshall() ([]byte, error)
// Storage returns underlying key storage
Storage() []byte
// String returns string representation
String() string
} }
type SymKey interface { type SymKey interface {

View File

@ -0,0 +1,9 @@
package crypto
type KeyStorage interface {
PubKeyFromProto(protoBytes []byte) (PubKey, error)
}
func NewKeyStorage() KeyStorage {
return nil
}