go-ssb-room/internal/repo/secret.go

105 lines
2.9 KiB
Go

// SPDX-FileCopyrightText: 2021 The NGI Pointer Secure-Scuttlebutt Team of 2020/2021
//
// SPDX-License-Identifier: MIT
package repo
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
refs "github.com/ssbc/go-ssb-refs"
"github.com/ssbc/go-ssb-room/v2/internal/maybemod/keys"
)
func DefaultKeyPair(r Interface) (*keys.KeyPair, error) {
secPath := r.GetPath("secret")
keyPair, err := keys.LoadKeyPair(secPath)
if err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("repo: error opening key pair: %w", err)
}
keyPair, err = keys.NewKeyPair(nil)
if err != nil {
return nil, fmt.Errorf("repo: no keypair but couldn't create one either: %w", err)
}
if err := keys.SaveKeyPair(*keyPair, secPath); err != nil {
return nil, fmt.Errorf("repo: error saving new identity file: %w", err)
}
log.Printf("saved identity %s to %s", keyPair.Feed.String(), secPath)
}
return keyPair, nil
}
func NewKeyPair(r Interface, name, algo string) (*keys.KeyPair, error) {
return newKeyPair(r, name, algo, nil)
}
func NewKeyPairFromSeed(r Interface, name, algo string, seed io.Reader) (*keys.KeyPair, error) {
return newKeyPair(r, name, algo, seed)
}
func newKeyPair(r Interface, name, algo string, seed io.Reader) (*keys.KeyPair, error) {
var secPath string
if name == "-" {
secPath = r.GetPath("secret")
} else {
secPath = r.GetPath("secrets", name)
err := os.MkdirAll(filepath.Dir(secPath), 0700)
if err != nil && !os.IsExist(err) {
return nil, err
}
}
if algo != string(refs.RefAlgoFeedSSB1) && algo != string(refs.RefAlgoFeedGabby) { // enums would be nice
return nil, fmt.Errorf("invalid feed refrence algo")
}
if _, err := keys.LoadKeyPair(secPath); err == nil {
return nil, fmt.Errorf("new key-pair name already taken")
}
keyPair, err := keys.NewKeyPair(seed)
if err != nil {
return nil, fmt.Errorf("repo: no keypair but couldn't create one either: %w", err)
}
if err := keys.SaveKeyPair(*keyPair, secPath); err != nil {
return nil, fmt.Errorf("repo: error saving new identity file: %w", err)
}
log.Printf("saved identity %s to %s", keyPair.Feed.String(), secPath)
return keyPair, nil
}
func LoadKeyPair(r Interface, name string) (*keys.KeyPair, error) {
secPath := r.GetPath("secrets", name)
keyPair, err := keys.LoadKeyPair(secPath)
if err != nil {
return nil, fmt.Errorf("Load: failed to open %q: %w", secPath, err)
}
return keyPair, nil
}
func AllKeyPairs(r Interface) (map[string]*keys.KeyPair, error) {
kps := make(map[string]*keys.KeyPair)
err := filepath.Walk(r.GetPath("secrets"), func(path string, info os.FileInfo, err error) error {
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
if info.IsDir() {
return nil
}
if kp, err := keys.LoadKeyPair(path); err == nil {
kps[filepath.Base(path)] = kp
return nil
}
return nil
})
if err != nil {
return nil, err
}
return kps, nil
}