bgpwtf/cccampix/pgpencryptor: implement service
TODO:
* tests
Change-Id: I5d0506542070236a8ee879fcb54bc9518e23b5e3
diff --git a/bgpwtf/cccampix/pgpencryptor/model/pgp.go b/bgpwtf/cccampix/pgpencryptor/model/pgp.go
new file mode 100644
index 0000000..3a9c19b
--- /dev/null
+++ b/bgpwtf/cccampix/pgpencryptor/model/pgp.go
@@ -0,0 +1,83 @@
+package model
+
+import (
+ "context"
+ "database/sql"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "time"
+)
+
+var ErrKeyNotFound = errors.New("key not found in cache")
+
+func (s *sqlModel) GetKey(ctx context.Context, keyID []byte) (*PgpKey, error) {
+ q := `
+ SELECT fingerprint, okay, key_data
+ FROM pgp_keys
+ WHERE fingerprint = $1
+ LIMIT 1
+ `
+ data := sqlPGPKey{}
+ err := s.db.Get(&data, q, hex.EncodeToString(keyID))
+
+ if err == sql.ErrNoRows {
+ return nil, ErrKeyNotFound
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ fp, err := hex.DecodeString(data.Fingerprint)
+ if err != nil {
+ return nil, fmt.Errorf("data corruption: could not decode fingerprint")
+ }
+
+ kd, err := hex.DecodeString(data.KeyData)
+ if err != nil {
+ return nil, fmt.Errorf("data corruption: could not decode keydata")
+ }
+
+ key := PgpKey{
+ Fingerprint: fp,
+ KeyData: kd,
+ Okay: data.Okay,
+ }
+
+ return &key, err
+}
+
+func (s *sqlModel) PutKey(ctx context.Context, key *PgpKey) error {
+ q := `
+ INSERT INTO pgp_keys
+ (fingerprint, time_created, okay, key_data)
+ VALUES
+ (:fingerprint, :time_created, :okay, :key_data)
+ ON CONFLICT (fingerprint)
+ DO UPDATE SET
+ fingerprint = :fingerprint,
+ time_created = :time_created,
+ key_data = :key_data,
+ okay = :okay
+ WHERE pgp_keys.okay = FALSE
+ `
+
+ keyData := []byte{}
+ if key.KeyData != nil {
+ keyData = key.KeyData
+ }
+
+ data := &sqlPGPKey{
+ Fingerprint: hex.EncodeToString(key.Fingerprint),
+ KeyData: hex.EncodeToString(keyData),
+ TimeCreated: time.Now().UnixNano(),
+ Okay: key.Okay,
+ }
+
+ if _, err := s.db.NamedExecContext(ctx, q, data); err != nil {
+ return fmt.Errorf("INSERT pgp_keys: %v", err)
+ }
+
+ return nil
+}