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

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

View File

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

View File

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

View File

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

View File

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

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_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")
}

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
}
// that means that change is unencrypted
change.ReadKeyHash = 0
change.ReadKeyId = 0
change.Data = data
err = putStorage(change)
return err == nil

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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