1
2
3
4
5 package x509
6
7 import (
8 "crypto/ecdh"
9 "crypto/ecdsa"
10 "crypto/ed25519"
11 "crypto/rsa"
12 "crypto/x509/pkix"
13 "encoding/asn1"
14 "errors"
15 "fmt"
16 )
17
18
19
20
21 type pkcs8 struct {
22 Version int
23 Algo pkix.AlgorithmIdentifier
24 PrivateKey []byte
25
26 }
27
28
29
30
31
32
33
34
35
36
37
38 func ParsePKCS8PrivateKey(der []byte) (key any, err error) {
39 var privKey pkcs8
40 if _, err := asn1.Unmarshal(der, &privKey); err != nil {
41 if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
42 return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)")
43 }
44 if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
45 return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
46 }
47 return nil, err
48 }
49 switch {
50 case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA):
51 key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
52 if err != nil {
53 return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
54 }
55 return key, nil
56
57 case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
58 bytes := privKey.Algo.Parameters.FullBytes
59 namedCurveOID := new(asn1.ObjectIdentifier)
60 if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
61 namedCurveOID = nil
62 }
63 key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
64 if err != nil {
65 return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
66 }
67 return key, nil
68
69 case privKey.Algo.Algorithm.Equal(oidPublicKeyEd25519):
70 if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
71 return nil, errors.New("x509: invalid Ed25519 private key parameters")
72 }
73 var curvePrivateKey []byte
74 if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
75 return nil, fmt.Errorf("x509: invalid Ed25519 private key: %v", err)
76 }
77 if l := len(curvePrivateKey); l != ed25519.SeedSize {
78 return nil, fmt.Errorf("x509: invalid Ed25519 private key length: %d", l)
79 }
80 return ed25519.NewKeyFromSeed(curvePrivateKey), nil
81
82 case privKey.Algo.Algorithm.Equal(oidPublicKeyX25519):
83 if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
84 return nil, errors.New("x509: invalid X25519 private key parameters")
85 }
86 var curvePrivateKey []byte
87 if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
88 return nil, fmt.Errorf("x509: invalid X25519 private key: %v", err)
89 }
90 return ecdh.X25519().NewPrivateKey(curvePrivateKey)
91
92 default:
93 return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
94 }
95 }
96
97
98
99
100
101
102
103
104
105
106 func MarshalPKCS8PrivateKey(key any) ([]byte, error) {
107 var privKey pkcs8
108
109 switch k := key.(type) {
110 case *rsa.PrivateKey:
111 privKey.Algo = pkix.AlgorithmIdentifier{
112 Algorithm: oidPublicKeyRSA,
113 Parameters: asn1.NullRawValue,
114 }
115 k.Precompute()
116 if err := k.Validate(); err != nil {
117 return nil, err
118 }
119 privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
120
121 case *ecdsa.PrivateKey:
122 oid, ok := oidFromNamedCurve(k.Curve)
123 if !ok {
124 return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
125 }
126 oidBytes, err := asn1.Marshal(oid)
127 if err != nil {
128 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
129 }
130 privKey.Algo = pkix.AlgorithmIdentifier{
131 Algorithm: oidPublicKeyECDSA,
132 Parameters: asn1.RawValue{
133 FullBytes: oidBytes,
134 },
135 }
136 if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
137 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
138 }
139
140 case ed25519.PrivateKey:
141 privKey.Algo = pkix.AlgorithmIdentifier{
142 Algorithm: oidPublicKeyEd25519,
143 }
144 curvePrivateKey, err := asn1.Marshal(k.Seed())
145 if err != nil {
146 return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
147 }
148 privKey.PrivateKey = curvePrivateKey
149
150 case *ecdh.PrivateKey:
151 if k.Curve() == ecdh.X25519() {
152 privKey.Algo = pkix.AlgorithmIdentifier{
153 Algorithm: oidPublicKeyX25519,
154 }
155 var err error
156 if privKey.PrivateKey, err = asn1.Marshal(k.Bytes()); err != nil {
157 return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
158 }
159 } else {
160 oid, ok := oidFromECDHCurve(k.Curve())
161 if !ok {
162 return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
163 }
164 oidBytes, err := asn1.Marshal(oid)
165 if err != nil {
166 return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
167 }
168 privKey.Algo = pkix.AlgorithmIdentifier{
169 Algorithm: oidPublicKeyECDSA,
170 Parameters: asn1.RawValue{
171 FullBytes: oidBytes,
172 },
173 }
174 if privKey.PrivateKey, err = marshalECDHPrivateKey(k); err != nil {
175 return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
176 }
177 }
178
179 default:
180 return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
181 }
182
183 return asn1.Marshal(privKey)
184 }
185
View as plain text