...
1 package edgeencrypt
2
3 import (
4 "context"
5 "crypto/rsa"
6 "fmt"
7
8 "cloud.google.com/go/kms/apiv1/kmspb"
9 "github.com/golang-jwt/jwt"
10 v1 "k8s.io/api/core/v1"
11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12 "sigs.k8s.io/controller-runtime/pkg/client"
13 )
14
15 const (
16 EncryptionName = "sparrow"
17 EncryptionJWTSecret = "encryption-jwt-signing-secret"
18 EncryptionSecret = "%s-encryption-key"
19 EncryptionBearerToken = "%s-encryption-bearer-token"
20 EncryptionJWTSecretManager = "sparrow-jwt-signing-key"
21 EncryptionSecretManager = "channel-%s-encryption-key"
22 EncryptionTokenSecretManager = "channel-%s-encryption-bearer-token"
23
24 DecryptionName = "magpie"
25 DecryptionJWTSecret = "decryption-signing-secret"
26 DecryptionJWTSecretManager = "decryption-signing-secret"
27 DecryptionTokenSecretManager = "decryption-bearer-token"
28
29 VersionKey = "version"
30 PEMKey = "pem"
31
32 DefaultSigningCryptoKeyPurpose = kmspb.CryptoKey_ASYMMETRIC_SIGN
33 DefaultSigningCryptoKeyAlgorithm = kmspb.CryptoKeyVersion_RSA_SIGN_PSS_2048_SHA256
34
35 DefaultCryptoKeyPurpose = kmspb.CryptoKey_ASYMMETRIC_DECRYPT
36 DefaultCryptoKeyAlgorithm = kmspb.CryptoKeyVersion_RSA_DECRYPT_OAEP_2048_SHA256
37 )
38
39 type PublicKey struct {
40 Version string `json:"version"`
41 PEM string `json:"pem"`
42 }
43
44 func NewPublicKey(pem, version string) (*PublicKey, error) {
45 p := &PublicKey{
46 Version: version,
47 PEM: pem,
48 }
49 if err := p.Valid(); err != nil {
50 return nil, err
51 }
52 return p, nil
53 }
54
55 func (p *PublicKey) Valid() error {
56 if p.Version == "" {
57 return fmt.Errorf("version is required")
58 }
59 if p.PEM == "" {
60 return fmt.Errorf("pem is required")
61 }
62 return nil
63 }
64
65 func (p *PublicKey) ToSecret(ns, name string) (*v1.Secret, error) {
66 if err := p.Valid(); err != nil {
67 return nil, err
68 }
69 return &v1.Secret{
70 TypeMeta: metav1.TypeMeta{
71 Kind: "Secret",
72 APIVersion: v1.SchemeGroupVersion.String(),
73 },
74 ObjectMeta: metav1.ObjectMeta{
75 Name: name,
76 Namespace: ns,
77 },
78 Data: map[string][]byte{
79 VersionKey: []byte(p.Version),
80 PEMKey: []byte(p.PEM),
81 },
82 }, nil
83 }
84
85 func (p *PublicKey) FromSecret(secret *v1.Secret) error {
86 p.Version = string(secret.Data[VersionKey])
87 p.PEM = string(secret.Data[PEMKey])
88 return p.Valid()
89 }
90
91 func (p *PublicKey) ToRSAPublicKey() (*rsa.PublicKey, error) {
92 return jwt.ParseRSAPublicKeyFromPEM([]byte(p.PEM))
93 }
94
95
96 func (p *PublicKey) Save(ctx context.Context, cl client.Client, ns, name string) error {
97 secret, err := p.ToSecret(ns, name)
98 if err != nil {
99 return err
100 }
101 return cl.Create(ctx, secret)
102 }
103
104
105 func GetPublicKey(ctx context.Context, cl client.Client, ns, name string) (*PublicKey, error) {
106 secret := &v1.Secret{}
107 if err := cl.Get(ctx, client.ObjectKey{Namespace: ns, Name: name}, secret); err != nil {
108 return nil, fmt.Errorf("failed to get public key [%s/%s] Secret: %w", ns, name, err)
109 }
110 p := &PublicKey{}
111 if err := p.FromSecret(secret); err != nil {
112 return nil, fmt.Errorf("failed to parse public key [%s/%s] secret: %w", ns, name, err)
113 }
114 return p, nil
115 }
116
View as plain text