Add revocation to certificate stores
This commit is contained in:
parent
67014f7af7
commit
f20da8ed23
@ -21,6 +21,7 @@ var bktKey = []byte("files")
|
||||
var bktKeyCerts = []byte("certs")
|
||||
var bktKeyKeys = []byte("keys")
|
||||
var bktKeyUsers = []byte("users")
|
||||
var bktKeyRevoked = []byte("revoked")
|
||||
|
||||
func NewBoltStore(path string) (*BoltStore, error) {
|
||||
s := &BoltStore{}
|
||||
@ -42,6 +43,9 @@ func NewBoltStore(path string) (*BoltStore, error) {
|
||||
if _, err := t.CreateBucketIfNotExists(bktKeyUsers); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := t.CreateBucketIfNotExists(bktKeyRevoked); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@ -202,6 +206,29 @@ func (s *BoltStore) ListCertificates() ([]string, error) {
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (s *BoltStore) Revoke(serial string) error {
|
||||
return s.db.Update(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyRevoked)
|
||||
return bkt.Put([]byte(serial), []byte{'r'})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltStore) IsRevoked(serial string) (bool, error) {
|
||||
var revoked bool
|
||||
err := s.db.View(func(tx *bolt.Tx) error {
|
||||
bkt := tx.Bucket(bktKeyRevoked)
|
||||
status := bkt.Get([]byte(serial))
|
||||
if status != nil {
|
||||
revoked = true
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return revoked, nil
|
||||
}
|
||||
|
||||
var _ UserStore = &BoltStore{}
|
||||
|
||||
func (s *BoltStore) StoreUser(user *pb.User) error {
|
||||
|
@ -10,22 +10,25 @@ import (
|
||||
)
|
||||
|
||||
type MemoryStore struct {
|
||||
filesLock sync.RWMutex
|
||||
files map[string]*pb.File
|
||||
certLock sync.RWMutex
|
||||
certs map[string][]byte
|
||||
keyLock sync.RWMutex
|
||||
keys map[string][]byte
|
||||
usersLock sync.RWMutex
|
||||
users map[string]*pb.User
|
||||
filesLock sync.RWMutex
|
||||
files map[string]*pb.File
|
||||
certLock sync.RWMutex
|
||||
certs map[string][]byte
|
||||
keyLock sync.RWMutex
|
||||
keys map[string][]byte
|
||||
usersLock sync.RWMutex
|
||||
users map[string]*pb.User
|
||||
revokedCerts map[string]struct{}
|
||||
revokedLock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMemoryStore() *MemoryStore {
|
||||
return &MemoryStore{
|
||||
files: make(map[string]*pb.File),
|
||||
certs: make(map[string][]byte),
|
||||
keys: make(map[string][]byte),
|
||||
users: make(map[string]*pb.User),
|
||||
files: make(map[string]*pb.File),
|
||||
certs: make(map[string][]byte),
|
||||
keys: make(map[string][]byte),
|
||||
users: make(map[string]*pb.User),
|
||||
revokedCerts: make(map[string]struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +150,22 @@ func (s *MemoryStore) ListCertificates() ([]string, error) {
|
||||
return certIDs, nil
|
||||
}
|
||||
|
||||
func (s *MemoryStore) Revoke(serial string) error {
|
||||
s.revokedLock.Lock()
|
||||
defer s.revokedLock.Unlock()
|
||||
|
||||
s.revokedCerts[serial] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MemoryStore) IsRevoked(serial string) (bool, error) {
|
||||
s.revokedLock.RLock()
|
||||
defer s.revokedLock.RUnlock()
|
||||
|
||||
_, revoked := s.revokedCerts[serial]
|
||||
return revoked, nil
|
||||
}
|
||||
|
||||
///////////////
|
||||
// UserStore //
|
||||
///////////////
|
||||
|
@ -23,6 +23,8 @@ type CertificateStore interface {
|
||||
GetKey(id string) (*ecdsa.PrivateKey, error)
|
||||
StoreKey(id string, key *ecdsa.PrivateKey) error
|
||||
ListCertificates() ([]string, error)
|
||||
Revoke(serial string) error
|
||||
IsRevoked(serial string) (bool, error)
|
||||
}
|
||||
|
||||
type UserStore interface {
|
||||
|
@ -79,7 +79,7 @@ func doCertificateStoreTest(s store.CertificateStore, t *testing.T) {
|
||||
|
||||
// Create cert and key
|
||||
unsigned := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(time.Now().Unix()),
|
||||
SerialNumber: big.NewInt(time.Now().UnixMilli()),
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{"ezshare"},
|
||||
Country: []string{"No"},
|
||||
@ -142,6 +142,26 @@ func doCertificateStoreTest(s store.CertificateStore, t *testing.T) {
|
||||
if !retrievedKey.Equal(privateKey) {
|
||||
t.Errorf("Retrieved key does not match stored.")
|
||||
}
|
||||
|
||||
// Revoke
|
||||
isRevoked, err := s.IsRevoked(cert.SerialNumber.String())
|
||||
if err != nil {
|
||||
t.Fatalf("Error checking if certificate is revoked: %s", err)
|
||||
}
|
||||
if isRevoked {
|
||||
t.Fatalf("Unrevoked certificate is revoked")
|
||||
}
|
||||
if err := s.Revoke(cert.SerialNumber.String()); err != nil {
|
||||
t.Fatalf("Error revoking certificate: %s", err)
|
||||
}
|
||||
isRevoked, err = s.IsRevoked(cert.SerialNumber.String())
|
||||
if err != nil {
|
||||
t.Fatalf("Error checking if certificate is revoked: %s", err)
|
||||
}
|
||||
if !isRevoked {
|
||||
t.Fatalf("Revoked certificate is not revoked")
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user