Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions pkg/connector/creategroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,38 @@ type groupKeyReleaser interface {
ReleaseGroupKey(int) error
}

type groupKeyBatchCrypto interface {
WrapRegistrationGroupKey([]string) ([]string, error)
}

func wrapRegistrationGroupKey(ctx context.Context, crypto groupKeyCrypto, pubKeys map[string]line.E2EEPeerPublicKey) (apiMembers []string, keyIDs []int, encryptedKeys []string, err error) {
if err := ctx.Err(); err != nil {
return nil, nil, nil, err
}
if batch, ok := crypto.(groupKeyBatchCrypto); ok {
apiMembers = make([]string, 0, len(pubKeys))
keyIDs = make([]int, 0, len(pubKeys))
memberPubKeys := make([]string, 0, len(pubKeys))
for mid, pk := range pubKeys {
apiMembers = append(apiMembers, mid)
keyIDs = append(keyIDs, pk.KeyID)
memberPubKeys = append(memberPubKeys, pk.KeyData)
}
if err := ctx.Err(); err != nil {
return nil, nil, nil, err
}
encryptedKeys, err = batch.WrapRegistrationGroupKey(memberPubKeys)
if err != nil {
return nil, nil, nil, fmt.Errorf("wrap group key for members: %w", err)
}
if err := ctx.Err(); err != nil {
return nil, nil, nil, err
}
if len(encryptedKeys) != len(apiMembers) {
return nil, nil, nil, fmt.Errorf("wrapped group key count does not match members")
}
return apiMembers, keyIDs, encryptedKeys, nil
}
groupKeyID, err := crypto.GenerateGroupKey()
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to generate group key: %w", err)
Expand Down
27 changes: 27 additions & 0 deletions pkg/e2ee/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,33 @@ func (m *Manager) GenerateGroupKey() (int, error) {
return m.runner.RegistrationKeyGenerate()
}

func (m *Manager) WrapRegistrationGroupKey(memberPubKeys []string) ([]string, error) {
m.mu.Lock()
defer m.mu.Unlock()
if err := m.errLocked(); err != nil {
return nil, err
}
if m.myKeyID == 0 {
return nil, fmt.Errorf("my E2EE key not loaded")
}
channelIDs := make([]int, len(memberPubKeys))
for i, memberPubKey := range memberPubKeys {
normalized, err := gen.NormalizePeerPublicKeyB64(memberPubKey)
if err != nil {
return nil, fmt.Errorf("invalid member public key: %w", err)
}
channelIDs[i], err = m.runner.ChannelCreate(m.myKeyID, normalized)
if err != nil {
return nil, fmt.Errorf("failed to create ECDH channel: %w", err)
}
}
wrapped, err := m.runner.WrapRegistrationGroupKey(channelIDs)
if err != nil {
return nil, fmt.Errorf("failed to wrap group key: %w", err)
}
return wrapped, nil
}

func (m *Manager) ReleaseGroupKey(keyID int) error {
m.mu.Lock()
defer m.mu.Unlock()
Expand Down
44 changes: 35 additions & 9 deletions pkg/ltsm/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,17 +379,43 @@ func (rt *Runtime) E2EEChannelUnwrapGroupSharedKey(chanPtr uint32, encKey []byte
return ptr, nil
}

func (rt *Runtime) E2EEChannelWrapGroupSharedKey(chanPtr uint32, keyHandle uint32) ([]byte, error) {
handle, err := rt.imp.CallMethod("E2EEChannel", "wrapGroupSharedKey", chanPtr, keyHandle)
if err != nil {
return nil, fmt.Errorf("ltsm: E2EEChannel.wrapGroupSharedKey failed: %w", err)
}
data, err := rt.imp.ReadEmvalBytes(handle)
func (rt *Runtime) WrapRegistrationGroupKey(chanPtrs []uint32) ([][]byte, error) {
var wrapped [][]byte
defer func() { rt.cryptoDirty = true }()
_, err := rt.channelCrypto(func(crypto *Runtime) ([]byte, error) {
keyPtr, err := crypto.Curve25519KeyGenerate()
if err != nil {
return nil, err
}
wrapped = make([][]byte, len(chanPtrs))
for i, chanPtr := range chanPtrs {
data, err := crypto.E2EEChannelWrapGroupSharedKey(chanPtr, keyPtr)
if err != nil {
return nil, err
}
wrapped[i] = append([]byte(nil), data...)
}
return nil, nil
})
if err != nil {
return nil, fmt.Errorf("ltsm: failed to read wrapGroupSharedKey result: %w", err)
return nil, err
}
rt.imp.emval.DecRef(handle)
return data, nil
return wrapped, nil
}

func (rt *Runtime) E2EEChannelWrapGroupSharedKey(chanPtr uint32, keyPtr uint32) ([]byte, error) {
return rt.channelCrypto(func(crypto *Runtime) ([]byte, error) {
handle, err := crypto.imp.CallMethod("E2EEChannel", "wrapGroupSharedKey", chanPtr, keyPtr)
if err != nil {
return nil, fmt.Errorf("ltsm: E2EEChannel.wrapGroupSharedKey failed: %w", err)
}
data, err := crypto.imp.ReadEmvalBytes(handle)
if err != nil {
return nil, fmt.Errorf("ltsm: failed to read wrapGroupSharedKey result: %w", err)
}
crypto.imp.emval.DecRef(handle)
return data, nil
})
}

func (rt *Runtime) E2EEChannelGenerateConfirmHash(chanPtr uint32, encKeyChain []byte) ([]byte, error) {
Expand Down
27 changes: 26 additions & 1 deletion pkg/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -1262,10 +1262,35 @@ func (r *Runner) ChannelWrapGroupSharedKey(channelID int, keyID int) (out0 strin
if r.failure != nil {
return "", r.failure
}
defer r.finishOperation("ChannelWrapGroupSharedKey", &err, true, func() { out0 = "" })
defer r.finishOperation("ChannelWrapGroupSharedKey", &err, false, func() { out0 = "" })
return r.channelWrapGroupSharedKey(channelID, keyID)
}

func (r *Runner) WrapRegistrationGroupKey(channelIDs []int) (out0 []string, err error) {
r.mu.Lock()
defer r.mu.Unlock()
if r.failure != nil {
return nil, r.failure
}
defer r.finishOperation("WrapRegistrationGroupKey", &err, false, func() { out0 = nil })
chanPtrs := make([]uint32, len(channelIDs))
for i, channelID := range channelIDs {
chanPtrs[i], err = r.getChannel(channelID)
if err != nil {
return nil, err
}
}
wrapped, err := r.rt.WrapRegistrationGroupKey(chanPtrs)
if err != nil {
return nil, err
}
out0 = make([]string, len(wrapped))
for i, data := range wrapped {
out0[i] = base64.StdEncoding.EncodeToString(data)
}
return out0, nil
}

func (r *Runner) channelWrapGroupSharedKey(channelID int, keyID int) (string, error) {

chanPtr, err := r.getChannel(channelID)
Expand Down
Loading