Files
motr-enclave/internal/keybase/actions_enclave.go

170 lines
4.0 KiB
Go
Raw Normal View History

package keybase
import (
"context"
"fmt"
"enclave/internal/crypto/mpc"
)
type EnclaveResult struct {
ID int64 `json:"id"`
EnclaveID string `json:"enclave_id"`
PublicKeyHex string `json:"public_key_hex"`
Curve string `json:"curve"`
Status string `json:"status"`
CreatedAt string `json:"created_at"`
RotatedAt string `json:"rotated_at,omitempty"`
}
type NewEnclaveInput struct {
EnclaveID string `json:"enclave_id"`
PublicKeyHex string `json:"public_key_hex"`
PublicKey []byte `json:"public_key"`
ValShare []byte `json:"val_share"`
UserShare []byte `json:"user_share"`
Nonce []byte `json:"nonce"`
Curve string `json:"curve"`
}
func (am *ActionManager) CreateEnclave(ctx context.Context, params NewEnclaveInput) (*EnclaveResult, error) {
am.kb.mu.Lock()
defer am.kb.mu.Unlock()
if am.kb.didID == 0 {
return nil, fmt.Errorf("DID not initialized")
}
enc, err := am.kb.queries.CreateEnclave(ctx, CreateEnclaveParams{
DidID: am.kb.didID,
EnclaveID: params.EnclaveID,
PublicKeyHex: params.PublicKeyHex,
PublicKey: params.PublicKey,
ValShare: params.ValShare,
UserShare: params.UserShare,
Nonce: params.Nonce,
Curve: params.Curve,
})
if err != nil {
return nil, fmt.Errorf("create enclave: %w", err)
}
return enclaveToResult(&enc), nil
}
func (am *ActionManager) ListEnclaves(ctx context.Context) ([]EnclaveResult, error) {
am.kb.mu.RLock()
defer am.kb.mu.RUnlock()
if am.kb.didID == 0 {
return []EnclaveResult{}, nil
}
enclaves, err := am.kb.queries.ListEnclavesByDID(ctx, am.kb.didID)
if err != nil {
return nil, fmt.Errorf("list enclaves: %w", err)
}
results := make([]EnclaveResult, len(enclaves))
for i, enc := range enclaves {
results[i] = *enclaveToResult(&enc)
}
return results, nil
}
func (am *ActionManager) GetEnclaveByID(ctx context.Context, enclaveID string) (*EnclaveResult, error) {
am.kb.mu.RLock()
defer am.kb.mu.RUnlock()
enc, err := am.kb.queries.GetEnclaveByID(ctx, enclaveID)
if err != nil {
return nil, fmt.Errorf("get enclave: %w", err)
}
return enclaveToResult(&enc), nil
}
func (am *ActionManager) RotateEnclave(ctx context.Context, enclaveID string) error {
am.kb.mu.Lock()
defer am.kb.mu.Unlock()
enc, err := am.kb.queries.GetEnclaveByID(ctx, enclaveID)
if err != nil {
return fmt.Errorf("get enclave: %w", err)
}
return am.kb.queries.RotateEnclave(ctx, enc.ID)
}
func (am *ActionManager) ArchiveEnclave(ctx context.Context, enclaveID string) error {
am.kb.mu.Lock()
defer am.kb.mu.Unlock()
enc, err := am.kb.queries.GetEnclaveByID(ctx, enclaveID)
if err != nil {
return fmt.Errorf("get enclave: %w", err)
}
return am.kb.queries.ArchiveEnclave(ctx, enc.ID)
}
func (am *ActionManager) DeleteEnclave(ctx context.Context, enclaveID string) error {
am.kb.mu.Lock()
defer am.kb.mu.Unlock()
if am.kb.didID == 0 {
return fmt.Errorf("DID not initialized")
}
enc, err := am.kb.queries.GetEnclaveByID(ctx, enclaveID)
if err != nil {
return fmt.Errorf("get enclave: %w", err)
}
return am.kb.queries.DeleteEnclave(ctx, DeleteEnclaveParams{
ID: enc.ID,
DidID: am.kb.didID,
})
}
func (am *ActionManager) SignWithEnclave(ctx context.Context, enclaveID string, data []byte) ([]byte, error) {
am.kb.mu.RLock()
defer am.kb.mu.RUnlock()
enc, err := am.kb.queries.GetEnclaveByID(ctx, enclaveID)
if err != nil {
return nil, fmt.Errorf("get enclave: %w", err)
}
simpleEnc, err := mpc.ImportSimpleEnclave(
enc.PublicKey,
enc.ValShare,
enc.UserShare,
enc.Nonce,
mpc.CurveName(enc.Curve),
)
if err != nil {
return nil, fmt.Errorf("import enclave: %w", err)
}
return simpleEnc.Sign(data)
}
func enclaveToResult(enc *MpcEnclafe) *EnclaveResult {
rotatedAt := ""
if enc.RotatedAt != nil {
rotatedAt = *enc.RotatedAt
}
return &EnclaveResult{
ID: enc.ID,
EnclaveID: enc.EnclaveID,
PublicKeyHex: enc.PublicKeyHex,
Curve: enc.Curve,
Status: enc.Status,
CreatedAt: enc.CreatedAt,
RotatedAt: rotatedAt,
}
}