-
Notifications
You must be signed in to change notification settings - Fork 0
/
x509.go
190 lines (152 loc) · 5.35 KB
/
x509.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Copyright 2022 FishGoddess. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package rsa
import (
"bytes"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"strings"
"github.com/FishGoddess/cryptox"
)
const (
blockTypePrivate = "PRIVATE KEY"
blockTypePublic = "PUBLIC KEY"
)
var (
// X509 is a x509Pem instance with X509 methods.
X509 = x509Pem{}
)
var (
_ PrivateKeyEncoder = X509.PKCS1PrivateKeyEncoder
_ PrivateKeyDecoder = X509.PKCS1PrivateKeyDecoder
_ PrivateKeyEncoder = X509.PKCS8PrivateKeyEncoder
_ PrivateKeyDecoder = X509.PKCS8PrivateKeyDecoder
_ PublicKeyEncoder = X509.PKIXPublicKeyEncoder
_ PublicKeyDecoder = X509.PKIXPublicKeyDecoder
_ PublicKeyEncoder = X509.PKCS1PublicKeyEncoder
_ PublicKeyDecoder = X509.PKCS1PublicKeyDecoder
)
// PrivateKeyEncoder encodes private key to pem bytes.
type PrivateKeyEncoder func(key *rsa.PrivateKey) (cryptox.Bytes, error)
// Encode encodes private key to pem bytes.
func (pke PrivateKeyEncoder) Encode(key *rsa.PrivateKey) (cryptox.Bytes, error) {
return pke(key)
}
// PrivateKeyDecoder decodes private key from pem bytes.
type PrivateKeyDecoder func(keyPem cryptox.Bytes) (*rsa.PrivateKey, error)
// Decode decodes private key from pem bytes.
func (pke PrivateKeyDecoder) Decode(keyPem cryptox.Bytes) (*rsa.PrivateKey, error) {
return pke(keyPem)
}
// PublicKeyEncoder encodes public key to pem bytes.
type PublicKeyEncoder func(key *rsa.PublicKey) (cryptox.Bytes, error)
// Encode encodes public key to pem bytes.
func (pke PublicKeyEncoder) Encode(key *rsa.PublicKey) (cryptox.Bytes, error) {
return pke(key)
}
// PublicKeyDecoder decodes public key from pem bytes.
type PublicKeyDecoder func(keyPem cryptox.Bytes) (*rsa.PublicKey, error)
// Decode decodes public key from pem bytes.
func (pke PublicKeyDecoder) Decode(keyPem cryptox.Bytes) (*rsa.PublicKey, error) {
return pke(keyPem)
}
// x509Pem wraps some methods about x509 with pem.
// We recommend you to use X509 variable directly.
type x509Pem struct{}
// encode encodes block to pem bytes.
func (xp x509Pem) encode(blockType string, blockBytes cryptox.Bytes) (cryptox.Bytes, error) {
block := &pem.Block{
Type: blockType,
Bytes: blockBytes,
}
var keyPem bytes.Buffer
if err := pem.Encode(&keyPem, block); err != nil {
return nil, err
}
return keyPem.Bytes(), nil
}
// decode decodes block from pem bytes.
func (xp x509Pem) decode(blockType string, keyPem cryptox.Bytes) (*pem.Block, error) {
block, _ := pem.Decode(keyPem)
if block == nil {
return nil, fmt.Errorf("cryptox.rsa: decode %s from pem failed", strings.ToLower(blockType))
}
return block, nil
}
// PKCS1PrivateKeyEncoder encodes private key to bytes using pkcs1.
func (xp x509Pem) PKCS1PrivateKeyEncoder(key *rsa.PrivateKey) (cryptox.Bytes, error) {
privateKeyBytes := x509.MarshalPKCS1PrivateKey(key)
return xp.encode(blockTypePrivate, privateKeyBytes)
}
// PKCS1PrivateKeyDecoder decodes private key from data using pkcs1.
func (xp x509Pem) PKCS1PrivateKeyDecoder(privateKeyPem cryptox.Bytes) (*rsa.PrivateKey, error) {
block, err := xp.decode(blockTypePrivate, privateKeyPem)
if err != nil {
return nil, err
}
return x509.ParsePKCS1PrivateKey(block.Bytes)
}
// PKCS8PrivateKeyEncoder encodes private key to bytes using pkcs8.
func (xp x509Pem) PKCS8PrivateKeyEncoder(key *rsa.PrivateKey) (cryptox.Bytes, error) {
privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(key)
if err != nil {
return nil, err
}
return xp.encode(blockTypePrivate, privateKeyBytes)
}
// PKCS8PrivateKeyDecoder decodes private key from data using pkcs1.
func (xp x509Pem) PKCS8PrivateKeyDecoder(privateKeyPem cryptox.Bytes) (*rsa.PrivateKey, error) {
block, err := xp.decode(blockTypePrivate, privateKeyPem)
if err != nil {
return nil, err
}
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
privateKey, ok := key.(*rsa.PrivateKey)
if !ok {
return nil, fmt.Errorf("cryptox.rsa: parsed key %T isn't a *rsa.PrivateKey", key)
}
return privateKey, nil
}
// PKIXPublicKeyEncoder encodes public key to bytes using pkix.
func (xp x509Pem) PKIXPublicKeyEncoder(key *rsa.PublicKey) (cryptox.Bytes, error) {
publicKeyBytes, err := x509.MarshalPKIXPublicKey(key)
if err != nil {
return nil, err
}
return xp.encode(blockTypePublic, publicKeyBytes)
}
// PKIXPublicKeyDecoder encodes public key to bytes using pkix.
func (xp x509Pem) PKIXPublicKeyDecoder(publicKeyPem cryptox.Bytes) (*rsa.PublicKey, error) {
block, err := xp.decode(blockTypePublic, publicKeyPem)
if err != nil {
return nil, err
}
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
publicKey, ok := key.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("cryptox.rsa: parsed key %T isn't a *rsa.PublicKey", key)
}
return publicKey, nil
}
// PKCS1PublicKeyEncoder encodes public key to bytes using pkcs1.
func (xp x509Pem) PKCS1PublicKeyEncoder(key *rsa.PublicKey) (cryptox.Bytes, error) {
publicKeyBytes := x509.MarshalPKCS1PublicKey(key)
return xp.encode(blockTypePublic, publicKeyBytes)
}
// PKCS1PublicKeyDecoder encodes public key to bytes using pkcs1.
func (xp x509Pem) PKCS1PublicKeyDecoder(publicKeyPem cryptox.Bytes) (*rsa.PublicKey, error) {
block, err := xp.decode(blockTypePublic, publicKeyPem)
if err != nil {
return nil, err
}
return x509.ParsePKCS1PublicKey(block.Bytes)
}