Skip to content

Commit

Permalink
Merge pull request #117 from smallstep/iid-common-name
Browse files Browse the repository at this point in the history
Allow custom common names in cloud identity provisioners.
  • Loading branch information
maraino authored Jul 16, 2019
2 parents 98635d1 + a36b147 commit f40b7ff
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 55 deletions.
12 changes: 6 additions & 6 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 10 additions & 32 deletions command/ca/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func certificateAction(ctx *cli.Context) error {
}
}

req, pk, err := flow.CreateSignRequest(tok, sans)
req, pk, err := flow.CreateSignRequest(tok, subject, sans)
if err != nil {
return err
}
Expand All @@ -164,18 +164,9 @@ func certificateAction(ctx *cli.Context) error {
if email := req.CsrPEM.EmailAddresses[0]; email != subject {
return errors.Errorf("token email '%s' and argument '%s' do not match", email, subject)
}
case token.AWS: // Validate that the subject matches the instance id
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
return errors.Errorf("token subject '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
}
case token.GCP: // Validate that the subject matches the instance Name
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
return errors.Errorf("token google.compute_engine.instance_name '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
}
case token.Azure: // Validate that the subject matches the virtual machine name
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
return errors.Errorf("token virtual machine '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
}
case token.AWS, token.GCP, token.Azure:
// Common name will be validated on the server side, it depends on
// server configuration.
default:
return errors.New("token is not supported")
}
Expand Down Expand Up @@ -235,20 +226,9 @@ func (f *certificateFlow) getClient(ctx *cli.Context, subject, tok string) (caCl
return nil, errors.Wrap(err, "error parsing flag '--token'")
}
switch jwt.Payload.Type() {
case token.AWS:
instanceID := jwt.Payload.Amazon.InstanceIdentityDocument.InstanceID
if strings.ToLower(instanceID) != strings.ToLower(subject) {
return nil, errors.Errorf("token amazon.document.instanceId '%s' and CSR CommonName '%s' do not match", instanceID, subject)
}
case token.GCP:
instanceName := jwt.Payload.Google.ComputeEngine.InstanceName
if strings.ToLower(instanceName) != strings.ToLower(subject) {
return nil, errors.Errorf("token google.compute_engine.instance_name '%s' and CSR CommonName '%s' do not match", instanceName, subject)
}
case token.Azure:
if strings.ToLower(jwt.Payload.Azure.VirtualMachine) != strings.ToLower(subject) {
return nil, errors.Errorf("token virtual machine '%s' and CSR CommonName '%s' do not match", jwt.Payload.Azure.VirtualMachine, subject)
}
case token.AWS, token.GCP, token.Azure:
// Common name will be validated on the server side, it depends on
// server configuration.
default:
if strings.ToLower(jwt.Payload.Subject) != strings.ToLower(subject) {
return nil, errors.Errorf("token subject '%s' and CSR CommonName '%s' do not match", jwt.Payload.Subject, subject)
Expand Down Expand Up @@ -351,7 +331,7 @@ func (f *certificateFlow) Sign(ctx *cli.Context, token string, csr api.Certifica

// CreateSignRequest is a helper function that given an x509 OTT returns a
// simple but secure sign request as well as the private key used.
func (f *certificateFlow) CreateSignRequest(tok string, sans []string) (*api.SignRequest, crypto.PrivateKey, error) {
func (f *certificateFlow) CreateSignRequest(tok, subject string, sans []string) (*api.SignRequest, crypto.PrivateKey, error) {
jwt, err := token.ParseInsecure(tok)
if err != nil {
return nil, nil, err
Expand All @@ -368,11 +348,9 @@ func (f *certificateFlow) CreateSignRequest(tok string, sans []string) (*api.Sig
emails = append(emails, jwt.Payload.Email)
}

subject := jwt.Payload.Subject
switch jwt.Payload.Type() {
case token.AWS:
doc := jwt.Payload.Amazon.InstanceIdentityDocument
subject = doc.InstanceID
if len(ips) == 0 && len(dnsNames) == 0 {
ips = append(ips, net.ParseIP(doc.PrivateIP))
dnsNames = append(dnsNames,
Expand All @@ -381,18 +359,18 @@ func (f *certificateFlow) CreateSignRequest(tok string, sans []string) (*api.Sig
}
case token.GCP:
ce := jwt.Payload.Google.ComputeEngine
subject = ce.InstanceName
if len(dnsNames) == 0 {
dnsNames = append(dnsNames,
fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
)
}
case token.Azure:
subject = jwt.Payload.Azure.VirtualMachine
if len(dnsNames) == 0 {
dnsNames = append(dnsNames, jwt.Payload.Azure.VirtualMachine)
}
default: // Use common name in the token
subject = jwt.Payload.Subject
}

template := &x509.CertificateRequest{
Expand Down
17 changes: 3 additions & 14 deletions command/ca/offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,22 +239,11 @@ func (c *offlineCA) GenerateToken(ctx *cli.Context, typ int, subject string, san
}
return strings.TrimSpace(string(out)), nil
case *provisioner.GCP: // Do the identity request to get the token
return p.GetIdentityToken(c.CaURL())
return p.GetIdentityToken(subject, c.CaURL())
case *provisioner.AWS: // Do the identity request to get the token
return p.GetIdentityToken(c.CaURL())
return p.GetIdentityToken(subject, c.CaURL())
case *provisioner.Azure: // Do the identity request to get the token
return p.GetIdentityToken()
}

// With OIDC just run step oauth
if p, ok := p.(*provisioner.OIDC); ok {
out, err := exec.Step("oauth", "--oidc", "--bare",
"--provider", p.ConfigurationEndpoint,
"--client-id", p.ClientID, "--client-secret", p.ClientSecret)
if err != nil {
return "", err
}
return string(out), nil
return p.GetIdentityToken(subject, c.CaURL())
}

// JWK provisioner
Expand Down
6 changes: 3 additions & 3 deletions command/ca/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,11 @@ func newTokenFlow(ctx *cli.Context, typ int, subject string, sans []string, caUR
}
return strings.TrimSpace(string(out)), nil
case *provisioner.GCP: // Do the identity request to get the token
return p.GetIdentityToken(caURL)
return p.GetIdentityToken(subject, caURL)
case *provisioner.AWS: // Do the identity request to get the token
return p.GetIdentityToken(caURL)
return p.GetIdentityToken(subject, caURL)
case *provisioner.Azure: // Do the identity request to get the token
return p.GetIdentityToken()
return p.GetIdentityToken(subject, caURL)
}

// JWK provisioner
Expand Down

0 comments on commit f40b7ff

Please sign in to comment.