Accept emails SANs

This commit is contained in:
max furman 2019-08-23 12:09:16 -07:00
parent f3faeeee4d
commit 635c59ed24
7 changed files with 56 additions and 13 deletions

6
Gopkg.lock generated
View file

@ -276,8 +276,8 @@
revision = "de77670473b5492f5d0bce155b5c01534c2d13f7" revision = "de77670473b5492f5d0bce155b5c01534c2d13f7"
[[projects]] [[projects]]
branch = "master" branch = "email"
digest = "1:8eb842c27bca9dae16d77baeba7cf612135033da381faf833bb8c11c29a751c7" digest = "1:cef75c86c34990ab5ed7826c35b8241474302c8264c64a0207c155229784479c"
name = "github.com/smallstep/cli" name = "github.com/smallstep/cli"
packages = [ packages = [
"command", "command",
@ -298,7 +298,7 @@
"utils", "utils",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "98635d188cade54451e3997b530716297ce7fc00" revision = "18e04f77ce327f282a5265dec5f35ec612868838"
[[projects]] [[projects]]
branch = "master" branch = "master"

View file

@ -65,7 +65,6 @@ func TestAuthority_authorizeToken(t *testing.T) {
auth *Authority auth *Authority
ott string ott string
err *apiError err *apiError
res []interface{}
} }
tests := map[string]func(t *testing.T) *authorizeTest{ tests := map[string]func(t *testing.T) *authorizeTest{
"fail/invalid-ott": func(t *testing.T) *authorizeTest { "fail/invalid-ott": func(t *testing.T) *authorizeTest {
@ -273,7 +272,6 @@ func TestAuthority_authorizeRevoke(t *testing.T) {
auth *Authority auth *Authority
opts *RevokeOptions opts *RevokeOptions
err error err error
res []interface{}
} }
tests := map[string]func(t *testing.T) *authorizeTest{ tests := map[string]func(t *testing.T) *authorizeTest{
"fail/token/invalid-ott": func(t *testing.T) *authorizeTest { "fail/token/invalid-ott": func(t *testing.T) *authorizeTest {
@ -383,7 +381,6 @@ func TestAuthority_AuthorizeSign(t *testing.T) {
auth *Authority auth *Authority
ott string ott string
err *apiError err *apiError
res []interface{}
} }
tests := map[string]func(t *testing.T) *authorizeTest{ tests := map[string]func(t *testing.T) *authorizeTest{
"fail/invalid-ott": func(t *testing.T) *authorizeTest { "fail/invalid-ott": func(t *testing.T) *authorizeTest {
@ -449,7 +446,7 @@ func TestAuthority_AuthorizeSign(t *testing.T) {
} }
} else { } else {
if assert.Nil(t, tc.err) { if assert.Nil(t, tc.err) {
assert.Len(t, 6, got) assert.Len(t, 7, got)
} }
} }
}) })
@ -476,7 +473,6 @@ func TestAuthority_Authorize(t *testing.T) {
auth *Authority auth *Authority
ott string ott string
err *apiError err *apiError
res []interface{}
} }
tests := map[string]func(t *testing.T) *authorizeTest{ tests := map[string]func(t *testing.T) *authorizeTest{
"fail/invalid-ott": func(t *testing.T) *authorizeTest { "fail/invalid-ott": func(t *testing.T) *authorizeTest {
@ -542,7 +538,7 @@ func TestAuthority_Authorize(t *testing.T) {
} }
} else { } else {
if assert.Nil(t, tc.err) { if assert.Nil(t, tc.err) {
assert.Len(t, 6, got) assert.Len(t, 7, got)
} }
} }
}) })

View file

@ -141,11 +141,12 @@ func (p *JWK) AuthorizeSign(token string) ([]SignOption, error) {
claims.SANs = []string{claims.Subject} claims.SANs = []string{claims.Subject}
} }
dnsNames, ips := x509util.SplitSANs(claims.SANs) dnsNames, ips, emails := x509util.SplitSANs(claims.SANs)
return []SignOption{ return []SignOption{
commonNameValidator(claims.Subject), commonNameValidator(claims.Subject),
dnsNamesValidator(dnsNames), dnsNamesValidator(dnsNames),
ipAddressesValidator(ips), ipAddressesValidator(ips),
emailAddressesValidator(emails),
profileDefaultDuration(p.claimer.DefaultTLSCertDuration()), profileDefaultDuration(p.claimer.DefaultTLSCertDuration()),
newProvisionerExtensionOption(TypeJWK, p.Name, p.Key.KeyID), newProvisionerExtensionOption(TypeJWK, p.Name, p.Key.KeyID),
newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()), newValidityValidator(p.claimer.MinTLSCertDuration(), p.claimer.MaxTLSCertDuration()),

View file

@ -265,7 +265,7 @@ func TestJWK_AuthorizeSign(t *testing.T) {
} }
} else { } else {
if assert.NotNil(t, got) { if assert.NotNil(t, got) {
assert.Len(t, 6, got) assert.Len(t, 7, got)
_cnv := got[0] _cnv := got[0]
cnv, ok := _cnv.(commonNameValidator) cnv, ok := _cnv.(commonNameValidator)

View file

@ -157,6 +157,26 @@ func (v ipAddressesValidator) Valid(req *x509.CertificateRequest) error {
return nil return nil
} }
// emailAddressesValidator validates the email address SANs of a certificate request.
type emailAddressesValidator []string
// Valid checks that certificate request IP Addresses match those configured in
// the bootstrap (token) flow.
func (v emailAddressesValidator) Valid(req *x509.CertificateRequest) error {
want := make(map[string]bool)
for _, s := range v {
want[s] = true
}
got := make(map[string]bool)
for _, s := range req.EmailAddresses {
got[s] = true
}
if !reflect.DeepEqual(want, got) {
return errors.Errorf("certificate request does not contain the valid Email Addresses - got %v, want %v", req.EmailAddresses, v)
}
return nil
}
// validityValidator validates the certificate temporal validity settings. // validityValidator validates the certificate temporal validity settings.
type validityValidator struct { type validityValidator struct {
min time.Duration min time.Duration

View file

@ -88,6 +88,33 @@ func Test_commonNameSliceValidator_Valid(t *testing.T) {
} }
} }
func Test_emailAddressesValidator_Valid(t *testing.T) {
type args struct {
req *x509.CertificateRequest
}
tests := []struct {
name string
v emailAddressesValidator
args args
wantErr bool
}{
{"ok0", []string{}, args{&x509.CertificateRequest{EmailAddresses: []string{}}}, false},
{"ok1", []string{"max@smallstep.com"}, args{&x509.CertificateRequest{EmailAddresses: []string{"max@smallstep.com"}}}, false},
{"ok2", []string{"max@step.com", "mike@step.com"}, args{&x509.CertificateRequest{EmailAddresses: []string{"max@step.com", "mike@step.com"}}}, false},
{"ok3", []string{"max@step.com", "mike@step.com"}, args{&x509.CertificateRequest{EmailAddresses: []string{"mike@step.com", "max@step.com"}}}, false},
{"fail1", []string{"max@step.com"}, args{&x509.CertificateRequest{EmailAddresses: []string{"mike@step.com"}}}, true},
{"fail2", []string{"mike@step.com"}, args{&x509.CertificateRequest{EmailAddresses: []string{"max@step.com", "mike@step.com"}}}, true},
{"fail3", []string{"mike@step.com", "max@step.com"}, args{&x509.CertificateRequest{DNSNames: []string{"mike@step.com", "mex@step.com"}}}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.v.Valid(tt.args.req); (err != nil) != tt.wantErr {
t.Errorf("dnsNamesValidator.Valid() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_dnsNamesValidator_Valid(t *testing.T) { func Test_dnsNamesValidator_Valid(t *testing.T) {
type args struct { type args struct {
req *x509.CertificateRequest req *x509.CertificateRequest

View file

@ -541,8 +541,7 @@ func CreateSignRequest(ott string) (*api.SignRequest, crypto.PrivateKey, error)
return nil, nil, errors.Wrap(err, "error generating key") return nil, nil, errors.Wrap(err, "error generating key")
} }
var emails []string dnsNames, ips, emails := x509util.SplitSANs(claims.SANs)
dnsNames, ips := x509util.SplitSANs(claims.SANs)
if claims.Email != "" { if claims.Email != "" {
emails = append(emails, claims.Email) emails = append(emails, claims.Email)
} }