diff options
| -rw-r--r-- | key/keyring.go | 99 | ||||
| -rw-r--r-- | key/sig_keyring.go | 33 |
2 files changed, 99 insertions, 33 deletions
diff --git a/key/keyring.go b/key/keyring.go new file mode 100644 index 0000000..9448460 --- /dev/null +++ b/key/keyring.go @@ -0,0 +1,99 @@ +package key + +import ( + "bytes" + "github.com/keybase/saltpack" + "slices" +) + +type keyring struct { + keyCreator saltpack.EphemeralKeyCreator + boxKeys []BoxKeypair // list of box keypairs sorted by public key. + sigPubKeys []SigPublicKey // sorted list of public verification keys. +} + +func NewKeyring() saltpack.SigncryptKeyring { + return new(keyring) +} + +func (ring *keyring) ImportBoxKeypair(pair BoxKeypair) { + i, ok := slices.BinarySearchFunc(ring.boxKeys, pair.Public, cmpBoxKeypairPubKey) + if ok { + return // key already in keyring. + } + ring.boxKeys = slices.Insert(ring.boxKeys, i, pair) +} + +func (ring *keyring) ImportSigPublicKey(key SigPublicKey) { + i, ok := slices.BinarySearchFunc(ring.sigPubKeys, key, cmpSigPublicKey) + if ok { + return // key already in keyring. + } + ring.sigPubKeys = slices.Insert(ring.sigPubKeys, i, key) +} + +func (ring *keyring) CreateEphemeralKey() (saltpack.BoxSecretKey, error) { + return ring.keyCreator.CreateEphemeralKey() +} + +func (ring *keyring) LookupBoxSecretKey(kids [][]byte) (int, saltpack.BoxSecretKey) { + for _, kid := range kids { + var pub BoxPublicKey + if len(kid) != len(pub) { + continue + } + pub = BoxPublicKey(kid) + i, ok := slices.BinarySearchFunc(ring.boxKeys, pub, cmpBoxKeypairPubKey) + if ok { + return i, ring.boxKeys[i] + } + } + return -1, nil +} + +func (ring *keyring) LookupBoxPublicKey(kid []byte) saltpack.BoxPublicKey { + var pub BoxPublicKey + if len(kid) != len(pub) { + return nil + } + pub = BoxPublicKey(kid) + i, ok := slices.BinarySearchFunc(ring.boxKeys, pub, cmpBoxKeypairPubKey) + if !ok { + return nil + } + return ring.boxKeys[i].Public +} + +func (ring *keyring) GetAllBoxSecretKeys() []saltpack.BoxSecretKey { + secrets := make([]saltpack.BoxSecretKey, len(ring.boxKeys)) + for i := range ring.boxKeys { + secrets[i] = ring.boxKeys[i] + } + return secrets +} + +func (ring *keyring) ImportBoxEphemeralKey(kid []byte) saltpack.BoxPublicKey { + var pub BoxPublicKey + copy(pub[:], kid) + return pub +} + +func (ring *keyring) LookupSigningPublicKey(kid []byte) saltpack.SigningPublicKey { + if len(kid) != len(SigPublicKey{}) { + return nil + } + key := SigPublicKey(kid) + i, ok := slices.BinarySearchFunc(ring.sigPubKeys, key, cmpSigPublicKey) + if !ok { + return nil // key not in keyring. + } + return ring.sigPubKeys[i] +} + +func cmpBoxKeypairPubKey(a BoxKeypair, b BoxPublicKey) int { + return a.Public.Compare(b) +} + +func cmpSigPublicKey(a, b SigPublicKey) int { + return bytes.Compare(a[:], b[:]) +} diff --git a/key/sig_keyring.go b/key/sig_keyring.go deleted file mode 100644 index aeb6180..0000000 --- a/key/sig_keyring.go +++ /dev/null @@ -1,33 +0,0 @@ -package key - -import ( - "bytes" - "github.com/keybase/saltpack" - "slices" -) - -type SigKeyring []SigPublicKey - -func (ring *SigKeyring) Import(key SigPublicKey) { - i, ok := slices.BinarySearchFunc(*ring, key, cmpSigPublicKey) - if ok { - return // key already in keyring. - } - *ring = slices.Insert(*ring, i, key) -} - -func (ring SigKeyring) LookupSigningPublicKey(kid []byte) saltpack.SigningPublicKey { - if len(kid) != len(SigPublicKey{}) { - return nil - } - key := SigPublicKey(kid) - i, ok := slices.BinarySearchFunc(ring, key, cmpSigPublicKey) - if !ok { - return nil // key not in keyring. - } - return ring[i] -} - -func cmpSigPublicKey(a, b SigPublicKey) int { - return bytes.Compare(a[:], b[:]) -} |