|  | package main | 
|  |  | 
|  | import ( | 
|  | "crypto/ed25519" | 
|  | "crypto/x509" | 
|  | "encoding/pem" | 
|  | "errors" | 
|  | "fmt" | 
|  | "os" | 
|  | "path/filepath" | 
|  |  | 
|  | "github.com/adrg/xdg" | 
|  | ) | 
|  |  | 
|  | var noCredentialsError = errors.New("owner certificate or key does not exist") | 
|  |  | 
|  | // getCredentials returns Metropolis credentials (if any) from the current | 
|  | // metroctl config directory. | 
|  | func getCredentials() (cert *x509.Certificate, key ed25519.PrivateKey, err error) { | 
|  | ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem")) | 
|  | if os.IsNotExist(err) { | 
|  | return nil, nil, noCredentialsError | 
|  | } else if err != nil { | 
|  | return nil, nil, fmt.Errorf("failed to load owner private key: %w", err) | 
|  | } | 
|  | block, _ := pem.Decode(ownerPrivateKeyPEM) | 
|  | if block == nil { | 
|  | return nil, nil, errors.New("owner-key.pem contains invalid PEM armoring") | 
|  | } | 
|  | if block.Type != ownerKeyType { | 
|  | return nil, nil, fmt.Errorf("owner-key.pem contains a PEM block that's not a %v", ownerKeyType) | 
|  | } | 
|  | if len(block.Bytes) != ed25519.PrivateKeySize { | 
|  | return nil, nil, errors.New("owner-key.pem contains a non-Ed25519 key") | 
|  | } | 
|  | key = block.Bytes | 
|  | ownerCertPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner.pem")) | 
|  | if os.IsNotExist(err) { | 
|  | return nil, nil, noCredentialsError | 
|  | } else if err != nil { | 
|  | return nil, nil, fmt.Errorf("failed to load owner certificate: %w", err) | 
|  | } | 
|  | block, _ = pem.Decode(ownerCertPEM) | 
|  | if block == nil { | 
|  | return nil, nil, errors.New("owner.pem contains invalid PEM armoring") | 
|  | } | 
|  | if block.Type != "CERTIFICATE" { | 
|  | return nil, nil, fmt.Errorf("owner.pem contains a PEM block that's not a CERTIFICATE") | 
|  | } | 
|  | cert, err = x509.ParseCertificate(block.Bytes) | 
|  | if err != nil { | 
|  | return nil, nil, fmt.Errorf("owner.pem contains an invalid X.509 certificate: %w", err) | 
|  | } | 
|  | return | 
|  | } |