pem_truststore.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package truststore
  2. import (
  3. "crypto"
  4. "crypto/x509"
  5. "encoding/pem"
  6. "fmt"
  7. "log/slog"
  8. "os"
  9. )
  10. func newPEMTrustStore(filename string) (TrustStore, error) {
  11. raw, err := os.ReadFile(filename)
  12. if err != nil {
  13. return nil, err
  14. }
  15. result := &InMemoryTrustStore{
  16. Keys: make(map[string]crypto.PublicKey),
  17. }
  18. for {
  19. block, rest := pem.Decode(raw)
  20. if block == nil {
  21. break
  22. }
  23. switch block.Type {
  24. case "PUBLIC KEY":
  25. keyID, ok := block.Headers["key_id"]
  26. if !ok {
  27. keyID = "default"
  28. }
  29. key, err := x509.ParsePKIXPublicKey(block.Bytes)
  30. if err != nil {
  31. return nil, err
  32. }
  33. result.Keys[keyID] = key
  34. slog.Debug("public key loaded into the trustore", "id", keyID)
  35. case "CERTIFICATE":
  36. cert, err := x509.ParseCertificate(block.Bytes)
  37. if err != nil {
  38. return nil, err
  39. }
  40. keyID := string(cert.Subject.CommonName)
  41. result.Keys[keyID] = cert.PublicKey
  42. slog.Debug("certificate loaded into the trustore", "id", keyID)
  43. }
  44. raw = rest
  45. }
  46. if len(result.Keys) == 0 {
  47. return nil, fmt.Errorf("no RSA public key found: %s", filename)
  48. }
  49. return result, nil
  50. }