-
Notifications
You must be signed in to change notification settings - Fork 0
/
PKCipherer.go
114 lines (80 loc) · 2.63 KB
/
PKCipherer.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package hippo
import (
"fmt"
"sync"
)
// A PKCipherer encapsulates key generation for a specific public key
// encryption algorithm and parameterization.
type PKCipherer interface {
// Algorithm returns the label identifying the algorithm and
// parameterization of this PKCipherer.
Algorithm() string
// Generate creates a new PKCipher.
Generate() (PKCipher, error)
// New wraps the given keys as a PKCipher.
New(public PublicKey, private PrivateKey) (PKCipher, error)
// NewEncrypter wraps the given PublicKey as a PKCipher.
NewEncrypter(key PublicKey) (PKCipher, error)
// NewDecrypter wraps the given PublicKey as a PKCipher.
NewDecrypter(key PrivateKey) (PKCipher, error)
}
var pkcipherers = make(map[string]PKCipherer)
var pkcipherersmutex sync.Mutex
// RegisterPKCipherer makes a PKCipherer for a specific algorithm available
// through the uniform interface.
func RegisterPKCipherer(cipherer PKCipherer) error {
pkcipherersmutex.Lock()
_, ok := pkcipherers[cipherer.Algorithm()]
defer pkcipherersmutex.Unlock()
if ok {
return ErrPreviousAlgorithm
}
pkcipherers[cipherer.Algorithm()] = cipherer
return nil
}
// GeneratePKCipher produces a PKCipher with new random keys following
// the given algorithm.
func GeneratePKCipher(algorithm string) (PKCipher, error) {
pkcipherersmutex.Lock()
cipherer, ok := pkcipherers[algorithm]
pkcipherersmutex.Unlock()
if !ok {
return nil, ErrUnknownAlgorithm
}
return cipherer.Generate()
}
// NewPKCipher creates a PKCipher wrapping the given public and
// private key. These must indicate the same algorithm but otherwise
// no test is made to confirm that they correspond to each other.
func NewPKCipher(public PublicKey, private PrivateKey) (PKCipher, error) {
if public.Algorithm != private.Algorithm {
return nil, fmt.Errorf("Algorithm mismatch %v vs %v", public.Algorithm, private.Algorithm)
}
pkcipherersmutex.Lock()
cipherer, ok := pkcipherers[public.Algorithm]
pkcipherersmutex.Unlock()
if !ok {
return nil, ErrUnknownAlgorithm
}
return cipherer.New(public, private)
}
// NewEncrypter wraps the given public key in a PKCipher for use.
func NewEncrypter(key PublicKey) (PKCipher, error) {
pkcipherersmutex.Lock()
cipherer, ok := pkcipherers[key.Algorithm]
pkcipherersmutex.Unlock()
if !ok {
return nil, ErrUnknownAlgorithm
}
return cipherer.NewEncrypter(key)
}
// NewDecrypter wraps the given private key in a PKCipher for use.
func NewDecrypter(key PrivateKey) (PKCipher, error) {
pkcipherersmutex.Lock()
cipherer, ok := pkcipherers[key.Algorithm]
pkcipherersmutex.Unlock()
if !ok {
return nil, ErrUnknownAlgorithm
}
return cipherer.NewDecrypter(key)
}