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