-
Notifications
You must be signed in to change notification settings - Fork 0
/
keys.go
139 lines (119 loc) · 2.89 KB
/
keys.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package crypt
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/pkg/errors"
)
type RSAPrivateKey struct {
Key *rsa.PrivateKey
}
func (p *RSAPrivateKey) Decode(data interface{}) error {
var key []byte
switch k := data.(type) {
case []byte:
key = k
case string:
key = []byte(k)
default:
return errors.Errorf("invalid rsa Key type: %T", data)
}
k, err := BytesToPrivateKey(key)
if err != nil {
return errors.Wrap(err, "failed to parse rsa Key")
}
p.Key = k
return nil
}
// BytesToPrivateKey parses rsa private Key from pem bytes
func BytesToPrivateKey(pemBytes []byte) (*rsa.PrivateKey, error) {
block, err := getPemBlock(pemBytes)
if err != nil {
return nil, errors.Wrap(err, "failed to parse pem block for rsa private Key")
}
key, err := x509.ParsePKCS1PrivateKey(block)
if err != nil {
return nil, errors.Wrap(err, "failed to parse pkcs1 private Key")
}
return key, nil
}
type RSAPublicKey struct {
Key *rsa.PublicKey
}
func (p *RSAPublicKey) Decode(data interface{}) error {
var key []byte
switch k := data.(type) {
case []byte:
key = k
case string:
key = []byte(k)
default:
return errors.Errorf("invalid rsa Key type: %T", data)
}
k, err := BytesToPublicKey(key)
if err != nil {
return errors.Wrap(err, "failed to parse rsa Key")
}
p.Key = k
return nil
}
// BytesToPrivateKey parses rsa private Key from pem bytes
func BytesToPublicKey(pemBytes []byte) (*rsa.PublicKey, error) {
block, err := getPemBlock(pemBytes)
if err != nil {
return nil, errors.Wrap(err, "failed to parse pem block for rsa public Key")
}
// var pk rsa.PublicKey
// if _, err := asn1.Unmarshal(block, &pk); err != nil {
// return nil, err
// }
// return &pk, nil
key, err := x509.ParsePKIXPublicKey(block)
if err != nil {
return nil, errors.Wrap(err, "failed to parse pkcs1 public Key")
}
if pk, ok := key.(*rsa.PublicKey); ok {
return pk, nil
}
return nil, fmt.Errorf("unknown key type %T", key)
}
func getPemBlock(pemBytes []byte) ([]byte, error) {
block, _ := pem.Decode(pemBytes)
if block == nil {
return nil, errors.New("failed to find pem block in Key")
}
enc := x509.IsEncryptedPEMBlock(block)
b := block.Bytes
var err error
// if encrypted pem block
if enc {
b, err = x509.DecryptPEMBlock(block, nil)
if err != nil {
return nil, errors.Wrap(err, "failed to decrypt pem block")
}
}
return b, nil
}
// PrivateKeyToBytes private Key to bytes
func PrivateKeyToBytes(priv *rsa.PrivateKey) []byte {
privBytes := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(priv),
},
)
return privBytes
}
// PublicKeyToBytes public Key to bytes
func PublicKeyToBytes(pub *rsa.PublicKey) ([]byte, error) {
pubASN1, err := x509.MarshalPKIXPublicKey(pub)
if err != nil {
return nil, err
}
pubBytes := pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubASN1,
})
return pubBytes, nil
}