package server import ( "crypto/x509" "fmt" "net/http" ) // Node is an identified system that can request certificates type Node struct { Name string `json:"name"` // Artbirary node name for authentication Secret string `json:"secret"` // Arbitrary node secret for authentication Domains []string `json:"issues"` // Exact-match domain names that are allowed } func (node *Node) authenticate(r *http.Request) error { user, password, ok := r.BasicAuth() if !ok { return fmt.Errorf("no http basic auth credentials") } if user != node.Name || password != node.Secret { return fmt.Errorf("invalid http basic auth credentials") } return nil } func (node *Node) check(crt x509.Certificate) error { for _, san := range crt.DNSNames { ok := false for _, domain := range node.Domains { if domain == san { ok = true break } } if !ok { return fmt.Errorf("%s: not authorized to issue certificates for %s", node.Name, san) } } return nil } // Nodes is a list of nodes that can request certificates type Nodes []Node func (nodes *Nodes) authenticate(r *http.Request) (Node, error) { for _, node := range (*nodes)[:] { if err := node.authenticate(r); err == nil { return node, nil } } return Node{}, fmt.Errorf("no valid HTTP basic auth credentials") }