File: engine.go

package info (click to toggle)
golang-github-smallstep-certificates 0.20.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 23,144 kB
  • sloc: sh: 278; makefile: 170
file content (114 lines) | stat: -rw-r--r-- 3,299 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package policy

import (
	"crypto/x509"
	"errors"
	"fmt"

	"golang.org/x/crypto/ssh"
)

// Engine is a container for multiple policies.
type Engine struct {
	x509Policy    X509Policy
	sshUserPolicy UserPolicy
	sshHostPolicy HostPolicy
}

// New returns a new Engine using Options.
func New(options *Options) (*Engine, error) {

	// if no options provided, return early
	if options == nil {
		return nil, nil
	}

	var (
		x509Policy    X509Policy
		sshHostPolicy HostPolicy
		sshUserPolicy UserPolicy
		err           error
	)

	// initialize the x509 allow/deny policy engine
	if x509Policy, err = NewX509PolicyEngine(options.GetX509Options()); err != nil {
		return nil, err
	}

	// initialize the SSH allow/deny policy engine for host certificates
	if sshHostPolicy, err = NewSSHHostPolicyEngine(options.GetSSHOptions()); err != nil {
		return nil, err
	}

	// initialize the SSH allow/deny policy engine for user certificates
	if sshUserPolicy, err = NewSSHUserPolicyEngine(options.GetSSHOptions()); err != nil {
		return nil, err
	}

	return &Engine{
		x509Policy:    x509Policy,
		sshHostPolicy: sshHostPolicy,
		sshUserPolicy: sshUserPolicy,
	}, nil
}

// IsX509CertificateAllowed evaluates an X.509 certificate against
// the X.509 policy (if available) and returns an error if one of the
// names in the certificate is not allowed.
func (e *Engine) IsX509CertificateAllowed(cert *x509.Certificate) error {

	// return early if there's no policy to evaluate
	if e == nil || e.x509Policy == nil {
		return nil
	}

	// return result of X.509 policy evaluation
	return e.x509Policy.IsX509CertificateAllowed(cert)
}

// AreSANsAllowed evaluates the slice of SANs against the X.509 policy
// (if available) and returns an error if one of the SANs is not allowed.
func (e *Engine) AreSANsAllowed(sans []string) error {

	// return early if there's no policy to evaluate
	if e == nil || e.x509Policy == nil {
		return nil
	}

	// return result of X.509 policy evaluation
	return e.x509Policy.AreSANsAllowed(sans)
}

// IsSSHCertificateAllowed evaluates an SSH certificate against the
// user or host policy (if configured) and returns an error if one of the
// principals in the certificate is not allowed.
func (e *Engine) IsSSHCertificateAllowed(cert *ssh.Certificate) error {

	// return early if there's no policy to evaluate
	if e == nil || (e.sshHostPolicy == nil && e.sshUserPolicy == nil) {
		return nil
	}

	switch cert.CertType {
	case ssh.HostCert:
		// when no host policy engine is configured, but a user policy engine is
		// configured, the host certificate is denied.
		if e.sshHostPolicy == nil && e.sshUserPolicy != nil {
			return errors.New("authority not allowed to sign ssh host certificates")
		}

		// return result of SSH host policy evaluation
		return e.sshHostPolicy.IsSSHCertificateAllowed(cert)
	case ssh.UserCert:
		// 	when no user policy engine is configured, but a host policy engine is
		// 	configured, the user certificate is denied.
		if e.sshUserPolicy == nil && e.sshHostPolicy != nil {
			return errors.New("authority not allowed to sign ssh user certificates")
		}

		// return result of SSH user policy evaluation
		return e.sshUserPolicy.IsSSHCertificateAllowed(cert)
	default:
		return fmt.Errorf("unexpected ssh certificate type %q", cert.CertType)
	}
}