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 bktKeyCerts = []byte("certs")
|
||||||
var bktKeyKeys = []byte("keys")
|
var bktKeyKeys = []byte("keys")
|
||||||
var bktKeyUsers = []byte("users")
|
var bktKeyUsers = []byte("users")
|
||||||
|
var bktKeyRevoked = []byte("revoked")
|
||||||
|
|
||||||
func NewBoltStore(path string) (*BoltStore, error) {
|
func NewBoltStore(path string) (*BoltStore, error) {
|
||||||
s := &BoltStore{}
|
s := &BoltStore{}
|
||||||
@ -42,6 +43,9 @@ func NewBoltStore(path string) (*BoltStore, error) {
|
|||||||
if _, err := t.CreateBucketIfNotExists(bktKeyUsers); err != nil {
|
if _, err := t.CreateBucketIfNotExists(bktKeyUsers); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err := t.CreateBucketIfNotExists(bktKeyRevoked); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -202,6 +206,29 @@ func (s *BoltStore) ListCertificates() ([]string, error) {
|
|||||||
return ids, nil
|
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{}
|
var _ UserStore = &BoltStore{}
|
||||||
|
|
||||||
func (s *BoltStore) StoreUser(user *pb.User) error {
|
func (s *BoltStore) StoreUser(user *pb.User) error {
|
||||||
|
@ -10,22 +10,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MemoryStore struct {
|
type MemoryStore struct {
|
||||||
filesLock sync.RWMutex
|
filesLock sync.RWMutex
|
||||||
files map[string]*pb.File
|
files map[string]*pb.File
|
||||||
certLock sync.RWMutex
|
certLock sync.RWMutex
|
||||||
certs map[string][]byte
|
certs map[string][]byte
|
||||||
keyLock sync.RWMutex
|
keyLock sync.RWMutex
|
||||||
keys map[string][]byte
|
keys map[string][]byte
|
||||||
usersLock sync.RWMutex
|
usersLock sync.RWMutex
|
||||||
users map[string]*pb.User
|
users map[string]*pb.User
|
||||||
|
revokedCerts map[string]struct{}
|
||||||
|
revokedLock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryStore() *MemoryStore {
|
func NewMemoryStore() *MemoryStore {
|
||||||
return &MemoryStore{
|
return &MemoryStore{
|
||||||
files: make(map[string]*pb.File),
|
files: make(map[string]*pb.File),
|
||||||
certs: make(map[string][]byte),
|
certs: make(map[string][]byte),
|
||||||
keys: make(map[string][]byte),
|
keys: make(map[string][]byte),
|
||||||
users: make(map[string]*pb.User),
|
users: make(map[string]*pb.User),
|
||||||
|
revokedCerts: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +150,22 @@ func (s *MemoryStore) ListCertificates() ([]string, error) {
|
|||||||
return certIDs, nil
|
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 //
|
// UserStore //
|
||||||
///////////////
|
///////////////
|
||||||
|
@ -23,6 +23,8 @@ type CertificateStore interface {
|
|||||||
GetKey(id string) (*ecdsa.PrivateKey, error)
|
GetKey(id string) (*ecdsa.PrivateKey, error)
|
||||||
StoreKey(id string, key *ecdsa.PrivateKey) error
|
StoreKey(id string, key *ecdsa.PrivateKey) error
|
||||||
ListCertificates() ([]string, error)
|
ListCertificates() ([]string, error)
|
||||||
|
Revoke(serial string) error
|
||||||
|
IsRevoked(serial string) (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserStore interface {
|
type UserStore interface {
|
||||||
|
@ -79,7 +79,7 @@ func doCertificateStoreTest(s store.CertificateStore, t *testing.T) {
|
|||||||
|
|
||||||
// Create cert and key
|
// Create cert and key
|
||||||
unsigned := &x509.Certificate{
|
unsigned := &x509.Certificate{
|
||||||
SerialNumber: big.NewInt(time.Now().Unix()),
|
SerialNumber: big.NewInt(time.Now().UnixMilli()),
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
Organization: []string{"ezshare"},
|
Organization: []string{"ezshare"},
|
||||||
Country: []string{"No"},
|
Country: []string{"No"},
|
||||||
@ -142,6 +142,26 @@ func doCertificateStoreTest(s store.CertificateStore, t *testing.T) {
|
|||||||
if !retrievedKey.Equal(privateKey) {
|
if !retrievedKey.Equal(privateKey) {
|
||||||
t.Errorf("Retrieved key does not match stored.")
|
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