forked from keybase/client
/
cert_store_backed_by_kvstore.go
89 lines (76 loc) · 2.48 KB
/
cert_store_backed_by_kvstore.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright 2020 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.
package libpages
import (
"context"
"encoding/base64"
"github.com/keybase/client/go/kbfs/libkbfs"
"github.com/keybase/client/go/protocol/keybase1"
"github.com/pkg/errors"
"golang.org/x/crypto/acme/autocert"
)
type keybaseServiceOwner interface {
KeybaseService() libkbfs.KeybaseService
}
// certStoreBackedByKVStore is a wrapper around the KVStore in Keybase. No
// caching is done here since acme/autocert has an in-memory cache already.
type certStoreBackedByKVStore struct {
serviceOwner keybaseServiceOwner
}
var _ autocert.Cache = (*certStoreBackedByKVStore)(nil)
func newCertStoreBackedByKVStore(serviceOwner keybaseServiceOwner) autocert.Cache {
return &certStoreBackedByKVStore{
serviceOwner: serviceOwner,
}
}
func encodeData(data []byte) string {
return base64.URLEncoding.EncodeToString(data)
}
func decodeData(str string) ([]byte, error) {
return base64.URLEncoding.DecodeString(str)
}
const certKVStoreNamespace = "cert-store-v1"
// Get implements the autocert.Cache interface.
func (s *certStoreBackedByKVStore) Get(ctx context.Context, key string) ([]byte, error) {
res, err := s.serviceOwner.KeybaseService().GetKVStoreClient().GetKVEntry(ctx,
keybase1.GetKVEntryArg{
Namespace: certKVStoreNamespace,
EntryKey: key,
})
if err != nil {
return nil, errors.WithMessage(err, "kvstore get error")
}
if res.EntryValue == nil {
return nil, errors.New("kvstore get error: empty result")
}
data, err := decodeData(*res.EntryValue)
if err != nil {
return nil, errors.WithMessage(err, "decodeData error")
}
return data, nil
}
// Put implements the autocert.Cache interface.
func (s *certStoreBackedByKVStore) Put(ctx context.Context, key string, data []byte) error {
_, err := s.serviceOwner.KeybaseService().GetKVStoreClient().PutKVEntry(ctx,
keybase1.PutKVEntryArg{
Namespace: certKVStoreNamespace,
EntryKey: key,
EntryValue: encodeData(data),
})
if err != nil {
return errors.WithMessage(err, "kvstore put error")
}
return nil
}
// Delete implements the autocert.Cache interface.
func (s *certStoreBackedByKVStore) Delete(ctx context.Context, key string) error {
_, err := s.serviceOwner.KeybaseService().GetKVStoreClient().DelKVEntry(ctx, keybase1.DelKVEntryArg{
Namespace: certKVStoreNamespace,
EntryKey: key,
})
if err != nil {
return errors.WithMessage(err, "kvstore del error")
}
return nil
}