113 lines
2.1 KiB
Go
113 lines
2.1 KiB
Go
package cert
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
type Storage struct {
|
|
basePath string
|
|
certs map[string]*Certificate
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
type Certificate struct {
|
|
ID string
|
|
OriginalPath string
|
|
StoredPath string
|
|
Password string
|
|
}
|
|
|
|
func NewStorage(basePath string) *Storage {
|
|
if basePath == "" {
|
|
basePath = "./certs/"
|
|
}
|
|
return &Storage{
|
|
basePath: basePath,
|
|
certs: make(map[string]*Certificate),
|
|
}
|
|
}
|
|
|
|
func (s *Storage) Init() error {
|
|
if err := os.MkdirAll(s.basePath, 0700); err != nil {
|
|
return fmt.Errorf("creating cert storage directory: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Storage) Store(id, origPath, password string) (string, error) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
exists := false
|
|
for _, c := range s.certs {
|
|
if c.ID == id {
|
|
exists = true
|
|
break
|
|
}
|
|
}
|
|
if exists {
|
|
return "", fmt.Errorf("certificate already exists with this ID")
|
|
}
|
|
|
|
ext := filepath.Ext(origPath)
|
|
storedFilename := fmt.Sprintf("%s%s", id, ext)
|
|
storedPath := filepath.Join(s.basePath, storedFilename)
|
|
|
|
data, err := os.ReadFile(origPath)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading certificate file: %w", err)
|
|
}
|
|
|
|
if err := os.WriteFile(storedPath, data, 0600); err != nil {
|
|
return "", fmt.Errorf("storing certificate: %w", err)
|
|
}
|
|
|
|
cert := &Certificate{
|
|
ID: id,
|
|
OriginalPath: origPath,
|
|
StoredPath: storedPath,
|
|
Password: password,
|
|
}
|
|
s.certs[id] = cert
|
|
|
|
return storedPath, nil
|
|
}
|
|
|
|
func (s *Storage) Get(id string) (*Certificate, error) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
cert, ok := s.certs[id]
|
|
if !ok {
|
|
return nil, fmt.Errorf("certificate not found")
|
|
}
|
|
return cert, nil
|
|
}
|
|
|
|
func (s *Storage) Delete(id string) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
cert, ok := s.certs[id]
|
|
if !ok {
|
|
return fmt.Errorf("certificate not found")
|
|
}
|
|
|
|
if err := os.Remove(cert.StoredPath); err != nil {
|
|
return fmt.Errorf("removing certificate file: %w", err)
|
|
}
|
|
|
|
delete(s.certs, id)
|
|
return nil
|
|
}
|
|
|
|
func GenerateID() string {
|
|
hash := sha256.Sum256([]byte(fmt.Sprintf("%d", os.Getpid())))
|
|
return hex.EncodeToString(hash[:])[:16]
|
|
}
|