1 package keys
2
3 import (
4 "bytes"
5 "crypto/ecdsa"
6 "crypto/elliptic"
7 "crypto/rand"
8 "crypto/sha256"
9 "crypto/x509"
10 "encoding/json"
11 "encoding/pem"
12 "errors"
13 "fmt"
14 "io"
15
16 "github.com/theupdateframework/go-tuf/data"
17 )
18
19 func init() {
20
21
22
23 VerifierMap.LoadOrStore(data.KeyTypeECDSA_SHA2_P256_OLD_FMT, NewEcdsaVerifier)
24 VerifierMap.LoadOrStore(data.KeyTypeECDSA_SHA2_P256, NewEcdsaVerifier)
25 SignerMap.Store(data.KeyTypeECDSA_SHA2_P256_OLD_FMT, newEcdsaSigner)
26 SignerMap.Store(data.KeyTypeECDSA_SHA2_P256, newEcdsaSigner)
27 }
28
29 func NewEcdsaVerifier() Verifier {
30 return &EcdsaVerifier{}
31 }
32
33 func newEcdsaSigner() Signer {
34 return &ecdsaSigner{}
35 }
36
37 type EcdsaVerifier struct {
38 PublicKey *PKIXPublicKey `json:"public"`
39 ecdsaKey *ecdsa.PublicKey
40 key *data.PublicKey
41 }
42
43 func (p *EcdsaVerifier) Public() string {
44
45 r, err := x509.MarshalPKIXPublicKey(p.ecdsaKey)
46 if err != nil {
47
48
49 panic(err)
50 }
51 return string(r)
52 }
53
54 func (p *EcdsaVerifier) Verify(msg, sigBytes []byte) error {
55 hash := sha256.Sum256(msg)
56
57 if !ecdsa.VerifyASN1(p.ecdsaKey, hash[:], sigBytes) {
58 return errors.New("tuf: ecdsa signature verification failed")
59 }
60 return nil
61 }
62
63 func (p *EcdsaVerifier) MarshalPublicKey() *data.PublicKey {
64 return p.key
65 }
66
67 func (p *EcdsaVerifier) UnmarshalPublicKey(key *data.PublicKey) error {
68
69 dec := json.NewDecoder(io.LimitReader(bytes.NewReader(key.Value), MaxJSONKeySize))
70
71
72 if err := dec.Decode(p); err != nil {
73 if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
74 return fmt.Errorf("tuf: the public key is truncated or too large: %w", err)
75 }
76 return err
77 }
78
79 ecdsaKey, ok := p.PublicKey.PublicKey.(*ecdsa.PublicKey)
80 if !ok {
81 return fmt.Errorf("invalid public key")
82 }
83
84 if _, err := x509.MarshalPKIXPublicKey(ecdsaKey); err != nil {
85 return fmt.Errorf("marshalling to PKIX key: invalid public key")
86 }
87
88 p.ecdsaKey = ecdsaKey
89 p.key = key
90 return nil
91 }
92
93 type ecdsaSigner struct {
94 *ecdsa.PrivateKey
95 }
96
97 type ecdsaPrivateKeyValue struct {
98 Private string `json:"private"`
99 Public *PKIXPublicKey `json:"public"`
100 }
101
102 func (s *ecdsaSigner) PublicData() *data.PublicKey {
103
104 keyValBytes, _ := json.Marshal(EcdsaVerifier{PublicKey: &PKIXPublicKey{PublicKey: s.Public()}})
105 return &data.PublicKey{
106 Type: data.KeyTypeECDSA_SHA2_P256,
107 Scheme: data.KeySchemeECDSA_SHA2_P256,
108 Algorithms: data.HashAlgorithms,
109 Value: keyValBytes,
110 }
111 }
112
113 func (s *ecdsaSigner) SignMessage(message []byte) ([]byte, error) {
114 hash := sha256.Sum256(message)
115 return ecdsa.SignASN1(rand.Reader, s.PrivateKey, hash[:])
116 }
117
118 func (s *ecdsaSigner) MarshalPrivateKey() (*data.PrivateKey, error) {
119 priv, err := x509.MarshalECPrivateKey(s.PrivateKey)
120 if err != nil {
121 return nil, err
122 }
123 pemKey := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: priv})
124 val, err := json.Marshal(ecdsaPrivateKeyValue{
125 Private: string(pemKey),
126 Public: &PKIXPublicKey{PublicKey: s.Public()},
127 })
128 if err != nil {
129 return nil, err
130 }
131 return &data.PrivateKey{
132 Type: data.KeyTypeECDSA_SHA2_P256,
133 Scheme: data.KeySchemeECDSA_SHA2_P256,
134 Algorithms: data.HashAlgorithms,
135 Value: val,
136 }, nil
137 }
138
139 func (s *ecdsaSigner) UnmarshalPrivateKey(key *data.PrivateKey) error {
140 val := ecdsaPrivateKeyValue{}
141 if err := json.Unmarshal(key.Value, &val); err != nil {
142 return err
143 }
144 block, _ := pem.Decode([]byte(val.Private))
145 if block == nil {
146 return errors.New("invalid PEM value")
147 }
148 if block.Type != "EC PRIVATE KEY" {
149 return fmt.Errorf("invalid block type: %s", block.Type)
150 }
151 k, err := x509.ParseECPrivateKey(block.Bytes)
152 if err != nil {
153 return err
154 }
155 if k.Curve != elliptic.P256() {
156 return errors.New("unsupported ecdsa curve")
157 }
158 if _, err := json.Marshal(EcdsaVerifier{
159 PublicKey: &PKIXPublicKey{PublicKey: k.Public()}}); err != nil {
160 return fmt.Errorf("invalid public key: %s", err)
161 }
162
163 s.PrivateKey = k
164 return nil
165 }
166
167 func GenerateEcdsaKey() (*ecdsaSigner, error) {
168 privkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
169 if err != nil {
170 return nil, err
171 }
172 return &ecdsaSigner{privkey}, nil
173 }
174
View as plain text