blob: 5c23f500602e006a4dd253dbd43d71cad593b5ae [file] [log] [blame]
Lorenz Brun705a4022021-12-23 11:51:06 +01001package main
2
3import (
4 "crypto/ed25519"
5 "crypto/x509"
6 "encoding/pem"
7 "errors"
8 "fmt"
9 "os"
10 "path/filepath"
11
12 "github.com/adrg/xdg"
13)
14
15var noCredentialsError = errors.New("owner certificate or key does not exist")
16
17// getCredentials returns Metropolis credentials (if any) from the current
18// metroctl config directory.
19func getCredentials() (cert *x509.Certificate, key ed25519.PrivateKey, err error) {
20 ownerPrivateKeyPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner-key.pem"))
21 if os.IsNotExist(err) {
22 return nil, nil, noCredentialsError
23 } else if err != nil {
24 return nil, nil, fmt.Errorf("failed to load owner private key: %w", err)
25 }
26 block, _ := pem.Decode(ownerPrivateKeyPEM)
27 if block == nil {
28 return nil, nil, errors.New("owner-key.pem contains invalid PEM armoring")
29 }
30 if block.Type != ownerKeyType {
31 return nil, nil, fmt.Errorf("owner-key.pem contains a PEM block that's not a %v", ownerKeyType)
32 }
33 if len(block.Bytes) != ed25519.PrivateKeySize {
34 return nil, nil, errors.New("owner-key.pem contains a non-Ed25519 key")
35 }
36 key = block.Bytes
37 ownerCertPEM, err := os.ReadFile(filepath.Join(xdg.ConfigHome, "metroctl/owner.pem"))
38 if os.IsNotExist(err) {
39 return nil, nil, noCredentialsError
40 } else if err != nil {
41 return nil, nil, fmt.Errorf("failed to load owner certificate: %w", err)
42 }
43 block, _ = pem.Decode(ownerCertPEM)
44 if block == nil {
45 return nil, nil, errors.New("owner.pem contains invalid PEM armoring")
46 }
47 if block.Type != "CERTIFICATE" {
48 return nil, nil, fmt.Errorf("owner.pem contains a PEM block that's not a CERTIFICATE")
49 }
50 cert, err = x509.ParseCertificate(block.Bytes)
51 if err != nil {
52 return nil, nil, fmt.Errorf("owner.pem contains an invalid X.509 certificate: %w", err)
53 }
54 return
55}