1 package in_toto
2
3 import (
4 "crypto"
5 "crypto/ecdsa"
6 "crypto/ed25519"
7 "crypto/rand"
8 "crypto/rsa"
9 "crypto/sha256"
10 "crypto/x509"
11 "encoding/hex"
12 "encoding/pem"
13 "errors"
14 "fmt"
15 "io"
16 "os"
17 "strings"
18
19 "github.com/secure-systems-lab/go-securesystemslib/cjson"
20 )
21
22
23 var ErrFailedPEMParsing = errors.New("failed parsing the PEM block: unsupported PEM type")
24
25
26 var ErrNoPEMBlock = errors.New("failed to decode the data as PEM block (are you sure this is a pem file?)")
27
28
29 var ErrUnsupportedKeyType = errors.New("unsupported key type")
30
31
32 var ErrInvalidSignature = errors.New("invalid signature")
33
34
35 var ErrInvalidKey = errors.New("invalid key")
36
37 const (
38 rsaKeyType string = "rsa"
39 ecdsaKeyType string = "ecdsa"
40 ed25519KeyType string = "ed25519"
41 rsassapsssha256Scheme string = "rsassa-pss-sha256"
42 ecdsaSha2nistp224 string = "ecdsa-sha2-nistp224"
43 ecdsaSha2nistp256 string = "ecdsa-sha2-nistp256"
44 ecdsaSha2nistp384 string = "ecdsa-sha2-nistp384"
45 ecdsaSha2nistp521 string = "ecdsa-sha2-nistp521"
46 ed25519Scheme string = "ed25519"
47 pemPublicKey string = "PUBLIC KEY"
48 pemPrivateKey string = "PRIVATE KEY"
49 pemRSAPrivateKey string = "RSA PRIVATE KEY"
50 )
51
52
57 func getSupportedKeyIDHashAlgorithms() Set {
58 return NewSet("sha256", "sha512")
59 }
60
61
66 func getSupportedRSASchemes() []string {
67 return []string{rsassapsssha256Scheme}
68 }
69
70
75 func getSupportedEcdsaSchemes() []string {
76 return []string{ecdsaSha2nistp224, ecdsaSha2nistp256, ecdsaSha2nistp384, ecdsaSha2nistp521}
77 }
78
79
84 func getSupportedEd25519Schemes() []string {
85 return []string{ed25519Scheme}
86 }
87
88
95 func (k *Key) generateKeyID() error {
96
97
98
99
100
101
102 var keyToBeHashed = map[string]interface{}{
103 "keytype": k.KeyType,
104 "scheme": k.Scheme,
105 "keyid_hash_algorithms": k.KeyIDHashAlgorithms,
106 "keyval": map[string]string{
107 "public": k.KeyVal.Public,
108 },
109 }
110 keyCanonical, err := cjson.EncodeCanonical(keyToBeHashed)
111 if err != nil {
112 return err
113 }
114
115 keyHashed := sha256.Sum256(keyCanonical)
116 k.KeyID = fmt.Sprintf("%x", keyHashed)
117 err = validateKey(*k)
118 if err != nil {
119 return err
120 }
121 return nil
122 }
123
124
130 func generatePEMBlock(keyBytes []byte, pemType string) []byte {
131
132 pemBlock := &pem.Block{
133 Type: pemType,
134 Headers: nil,
135 Bytes: keyBytes,
136 }
137 return pem.EncodeToMemory(pemBlock)
138 }
139
140
146 func (k *Key) setKeyComponents(pubKeyBytes []byte, privateKeyBytes []byte, keyType string, scheme string, KeyIDHashAlgorithms []string) error {
147
148
149 switch keyType {
150 case rsaKeyType:
151 if len(privateKeyBytes) > 0 {
152 k.KeyVal = KeyVal{
153 Private: strings.TrimSpace(string(generatePEMBlock(privateKeyBytes, pemRSAPrivateKey))),
154 Public: strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, pemPublicKey))),
155 }
156 } else {
157 k.KeyVal = KeyVal{
158 Public: strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, pemPublicKey))),
159 }
160 }
161 case ecdsaKeyType:
162 if len(privateKeyBytes) > 0 {
163 k.KeyVal = KeyVal{
164 Private: strings.TrimSpace(string(generatePEMBlock(privateKeyBytes, pemPrivateKey))),
165 Public: strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, pemPublicKey))),
166 }
167 } else {
168 k.KeyVal = KeyVal{
169 Public: strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, pemPublicKey))),
170 }
171 }
172 case ed25519KeyType:
173 if len(privateKeyBytes) > 0 {
174 k.KeyVal = KeyVal{
175 Private: strings.TrimSpace(hex.EncodeToString(privateKeyBytes)),
176 Public: strings.TrimSpace(hex.EncodeToString(pubKeyBytes)),
177 }
178 } else {
179 k.KeyVal = KeyVal{
180 Public: strings.TrimSpace(hex.EncodeToString(pubKeyBytes)),
181 }
182 }
183 default:
184 return fmt.Errorf("%w: %s", ErrUnsupportedKeyType, keyType)
185 }
186 k.KeyType = keyType
187 k.Scheme = scheme
188 k.KeyIDHashAlgorithms = KeyIDHashAlgorithms
189 if err := k.generateKeyID(); err != nil {
190 return err
191 }
192 return nil
193 }
194
195
206 func parseKey(data []byte) (interface{}, error) {
207 key, err := x509.ParsePKCS8PrivateKey(data)
208 if err == nil {
209 return key, nil
210 }
211 key, err = x509.ParsePKCS1PrivateKey(data)
212 if err == nil {
213 return key, nil
214 }
215 key, err = x509.ParsePKIXPublicKey(data)
216 if err == nil {
217 return key, nil
218 }
219 key, err = x509.ParseCertificate(data)
220 if err == nil {
221 return key, nil
222 }
223 key, err = x509.ParseECPrivateKey(data)
224 if err == nil {
225 return key, nil
226 }
227 return nil, ErrFailedPEMParsing
228 }
229
230
239 func decodeAndParse(pemBytes []byte) (*pem.Block, interface{}, error) {
240
241
242
243 data, _ := pem.Decode(pemBytes)
244 if data == nil {
245 return nil, nil, ErrNoPEMBlock
246 }
247
248
249
250 key, err := parseKey(data.Bytes)
251 if err != nil {
252 return nil, nil, err
253 }
254 return data, key, nil
255 }
256
257
291 func (k *Key) LoadKey(path string, scheme string, KeyIDHashAlgorithms []string) error {
292 pemFile, err := os.Open(path)
293 if err != nil {
294 return err
295 }
296 defer pemFile.Close()
297
298 err = k.LoadKeyReader(pemFile, scheme, KeyIDHashAlgorithms)
299 if err != nil {
300 return err
301 }
302
303 return pemFile.Close()
304 }
305
306 func (k *Key) LoadKeyDefaults(path string) error {
307 pemFile, err := os.Open(path)
308 if err != nil {
309 return err
310 }
311 defer pemFile.Close()
312
313 err = k.LoadKeyReaderDefaults(pemFile)
314 if err != nil {
315 return err
316 }
317
318 return pemFile.Close()
319 }
320
321
322 func (k *Key) LoadKeyReader(r io.Reader, scheme string, KeyIDHashAlgorithms []string) error {
323 if r == nil {
324 return ErrNoPEMBlock
325 }
326
327 pemBytes, err := io.ReadAll(r)
328 if err != nil {
329 return err
330 }
331
332
333 pemData, key, err := decodeAndParse(pemBytes)
334 if err != nil {
335 return err
336 }
337
338 return k.loadKey(key, pemData, scheme, KeyIDHashAlgorithms)
339 }
340
341 func (k *Key) LoadKeyReaderDefaults(r io.Reader) error {
342 if r == nil {
343 return ErrNoPEMBlock
344 }
345
346 pemBytes, err := io.ReadAll(r)
347 if err != nil {
348 return err
349 }
350
351
352 pemData, key, err := decodeAndParse(pemBytes)
353 if err != nil {
354 return err
355 }
356
357 scheme, keyIDHashAlgorithms, err := getDefaultKeyScheme(key)
358 if err != nil {
359 return err
360 }
361
362 return k.loadKey(key, pemData, scheme, keyIDHashAlgorithms)
363 }
364
365 func getDefaultKeyScheme(key interface{}) (scheme string, keyIDHashAlgorithms []string, err error) {
366 keyIDHashAlgorithms = []string{"sha256", "sha512"}
367
368 switch k := key.(type) {
369 case *rsa.PublicKey, *rsa.PrivateKey:
370 scheme = rsassapsssha256Scheme
371 case ed25519.PrivateKey, ed25519.PublicKey:
372 scheme = ed25519Scheme
373 case *ecdsa.PrivateKey, *ecdsa.PublicKey:
374 scheme = ecdsaSha2nistp256
375 case *x509.Certificate:
376 return getDefaultKeyScheme(k.PublicKey)
377 default:
378 err = ErrUnsupportedKeyType
379 }
380
381 return scheme, keyIDHashAlgorithms, err
382 }
383
384 func (k *Key) loadKey(keyObj interface{}, pemData *pem.Block, scheme string, keyIDHashAlgorithms []string) error {
385 switch key := keyObj.(type) {
386 case *rsa.PublicKey:
387 pubKeyBytes, err := x509.MarshalPKIXPublicKey(key)
388 if err != nil {
389 return err
390 }
391 if err := k.setKeyComponents(pubKeyBytes, []byte{}, rsaKeyType, scheme, keyIDHashAlgorithms); err != nil {
392 return err
393 }
394 case *rsa.PrivateKey:
395
396
397 pubKeyBytes, err := x509.MarshalPKIXPublicKey(key.Public())
398 if err != nil {
399 return err
400 }
401 if err := k.setKeyComponents(pubKeyBytes, pemData.Bytes, rsaKeyType, scheme, keyIDHashAlgorithms); err != nil {
402 return err
403 }
404 case ed25519.PublicKey:
405 if err := k.setKeyComponents(key, []byte{}, ed25519KeyType, scheme, keyIDHashAlgorithms); err != nil {
406 return err
407 }
408 case ed25519.PrivateKey:
409 pubKeyBytes := key.Public()
410 if err := k.setKeyComponents(pubKeyBytes.(ed25519.PublicKey), key, ed25519KeyType, scheme, keyIDHashAlgorithms); err != nil {
411 return err
412 }
413 case *ecdsa.PrivateKey:
414 pubKeyBytes, err := x509.MarshalPKIXPublicKey(key.Public())
415 if err != nil {
416 return err
417 }
418 if err := k.setKeyComponents(pubKeyBytes, pemData.Bytes, ecdsaKeyType, scheme, keyIDHashAlgorithms); err != nil {
419 return err
420 }
421 case *ecdsa.PublicKey:
422 pubKeyBytes, err := x509.MarshalPKIXPublicKey(key)
423 if err != nil {
424 return err
425 }
426 if err := k.setKeyComponents(pubKeyBytes, []byte{}, ecdsaKeyType, scheme, keyIDHashAlgorithms); err != nil {
427 return err
428 }
429 case *x509.Certificate:
430 err := k.loadKey(key.PublicKey, pemData, scheme, keyIDHashAlgorithms)
431 if err != nil {
432 return err
433 }
434
435 k.KeyVal.Certificate = string(pem.EncodeToMemory(pemData))
436
437 default:
438
439 return errors.New("unexpected Error in LoadKey function")
440 }
441
442 return nil
443 }
444
445
460 func GenerateSignature(signable []byte, key Key) (Signature, error) {
461 err := validateKey(key)
462 if err != nil {
463 return Signature{}, err
464 }
465 var signature Signature
466 var signatureBuffer []byte
467 hashMapping := getHashMapping()
468
469
470
471 switch key.KeyType {
472 case rsaKeyType:
473
474 _, parsedKey, err := decodeAndParse([]byte(key.KeyVal.Private))
475 if err != nil {
476 return Signature{}, err
477 }
478 parsedKey, ok := parsedKey.(*rsa.PrivateKey)
479 if !ok {
480 return Signature{}, ErrKeyKeyTypeMismatch
481 }
482 switch key.Scheme {
483 case rsassapsssha256Scheme:
484 hashed := hashToHex(hashMapping["sha256"](), signable)
485
486 signatureBuffer, err = rsa.SignPSS(rand.Reader, parsedKey.(*rsa.PrivateKey), crypto.SHA256, hashed,
487 &rsa.PSSOptions{SaltLength: sha256.Size, Hash: crypto.SHA256})
488 if err != nil {
489 return signature, err
490 }
491 default:
492
493 panic("unexpected Error in GenerateSignature function")
494 }
495 case ecdsaKeyType:
496
497 _, parsedKey, err := decodeAndParse([]byte(key.KeyVal.Private))
498 if err != nil {
499 return Signature{}, err
500 }
501 parsedKey, ok := parsedKey.(*ecdsa.PrivateKey)
502 if !ok {
503 return Signature{}, ErrKeyKeyTypeMismatch
504 }
505 curveSize := parsedKey.(*ecdsa.PrivateKey).Curve.Params().BitSize
506 var hashed []byte
507 if err := matchEcdsaScheme(curveSize, key.Scheme); err != nil {
508 return Signature{}, ErrCurveSizeSchemeMismatch
509 }
510
511
512
513 switch {
514 case curveSize <= 256:
515 hashed = hashToHex(hashMapping["sha256"](), signable)
516 case 256 < curveSize && curveSize <= 384:
517 hashed = hashToHex(hashMapping["sha384"](), signable)
518 case curveSize > 384:
519 hashed = hashToHex(hashMapping["sha512"](), signable)
520 default:
521 panic("unexpected Error in GenerateSignature function")
522 }
523
524
525
526 signatureBuffer, err = ecdsa.SignASN1(rand.Reader, parsedKey.(*ecdsa.PrivateKey), hashed[:])
527 if err != nil {
528 return signature, err
529 }
530 case ed25519KeyType:
531
532
533 privateHex, err := hex.DecodeString(key.KeyVal.Private)
534 if err != nil {
535 return signature, ErrInvalidHexString
536 }
537
538
539 signatureBuffer = ed25519.Sign(privateHex, signable)
540 default:
541
542
543 panic("unexpected Error in GenerateSignature function")
544 }
545 signature.Sig = hex.EncodeToString(signatureBuffer)
546 signature.KeyID = key.KeyID
547 signature.Certificate = key.KeyVal.Certificate
548 return signature, nil
549 }
550
551
572 func VerifySignature(key Key, sig Signature, unverified []byte) error {
573 err := validateKey(key)
574 if err != nil {
575 return err
576 }
577 sigBytes, err := hex.DecodeString(sig.Sig)
578 if err != nil {
579 return err
580 }
581 hashMapping := getHashMapping()
582 switch key.KeyType {
583 case rsaKeyType:
584
585 _, parsedKey, err := decodeAndParse([]byte(key.KeyVal.Public))
586 if err != nil {
587 return err
588 }
589 parsedKey, ok := parsedKey.(*rsa.PublicKey)
590 if !ok {
591 return ErrKeyKeyTypeMismatch
592 }
593 switch key.Scheme {
594 case rsassapsssha256Scheme:
595 hashed := hashToHex(hashMapping["sha256"](), unverified)
596 err = rsa.VerifyPSS(parsedKey.(*rsa.PublicKey), crypto.SHA256, hashed, sigBytes, &rsa.PSSOptions{SaltLength: sha256.Size, Hash: crypto.SHA256})
597 if err != nil {
598 return fmt.Errorf("%w: %s", ErrInvalidSignature, err)
599 }
600 default:
601
602 panic("unexpected Error in VerifySignature function")
603 }
604 case ecdsaKeyType:
605
606 _, parsedKey, err := decodeAndParse([]byte(key.KeyVal.Public))
607 if err != nil {
608 return err
609 }
610 parsedKey, ok := parsedKey.(*ecdsa.PublicKey)
611 if !ok {
612 return ErrKeyKeyTypeMismatch
613 }
614 curveSize := parsedKey.(*ecdsa.PublicKey).Curve.Params().BitSize
615 var hashed []byte
616 if err := matchEcdsaScheme(curveSize, key.Scheme); err != nil {
617 return ErrCurveSizeSchemeMismatch
618 }
619
620
621
622 switch {
623 case curveSize <= 256:
624 hashed = hashToHex(hashMapping["sha256"](), unverified)
625 case 256 < curveSize && curveSize <= 384:
626 hashed = hashToHex(hashMapping["sha384"](), unverified)
627 case curveSize > 384:
628 hashed = hashToHex(hashMapping["sha512"](), unverified)
629 default:
630 panic("unexpected Error in VerifySignature function")
631 }
632 if ok := ecdsa.VerifyASN1(parsedKey.(*ecdsa.PublicKey), hashed[:], sigBytes); !ok {
633 return ErrInvalidSignature
634 }
635 case ed25519KeyType:
636
637
638 pubHex, err := hex.DecodeString(key.KeyVal.Public)
639 if err != nil {
640 return ErrInvalidHexString
641 }
642 if ok := ed25519.Verify(pubHex, unverified, sigBytes); !ok {
643 return fmt.Errorf("%w: ed25519", ErrInvalidSignature)
644 }
645 default:
646
647
648 panic("unexpected Error in VerifySignature function")
649 }
650 return nil
651 }
652
653
658 func VerifyCertificateTrust(cert *x509.Certificate, rootCertPool, intermediateCertPool *x509.CertPool) ([][]*x509.Certificate, error) {
659 verifyOptions := x509.VerifyOptions{
660 Roots: rootCertPool,
661 Intermediates: intermediateCertPool,
662 }
663 chains, err := cert.Verify(verifyOptions)
664 if len(chains) == 0 || err != nil {
665 return nil, fmt.Errorf("cert cannot be verified by provided roots and intermediates")
666 }
667 return chains, nil
668 }
669
View as plain text