Skip to content

Commit f40b7ff

Browse files
authored
Merge pull request #117 from smallstep/iid-common-name
Allow custom common names in cloud identity provisioners.
2 parents 98635d1 + a36b147 commit f40b7ff

File tree

4 files changed

+22
-55
lines changed

4 files changed

+22
-55
lines changed

Gopkg.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

command/ca/certificate.go

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func certificateAction(ctx *cli.Context) error {
139139
}
140140
}
141141

142-
req, pk, err := flow.CreateSignRequest(tok, sans)
142+
req, pk, err := flow.CreateSignRequest(tok, subject, sans)
143143
if err != nil {
144144
return err
145145
}
@@ -164,18 +164,9 @@ func certificateAction(ctx *cli.Context) error {
164164
if email := req.CsrPEM.EmailAddresses[0]; email != subject {
165165
return errors.Errorf("token email '%s' and argument '%s' do not match", email, subject)
166166
}
167-
case token.AWS: // Validate that the subject matches the instance id
168-
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
169-
return errors.Errorf("token subject '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
170-
}
171-
case token.GCP: // Validate that the subject matches the instance Name
172-
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
173-
return errors.Errorf("token google.compute_engine.instance_name '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
174-
}
175-
case token.Azure: // Validate that the subject matches the virtual machine name
176-
if strings.ToLower(subject) != strings.ToLower(req.CsrPEM.Subject.CommonName) {
177-
return errors.Errorf("token virtual machine '%s' and argument '%s' do not match", req.CsrPEM.Subject.CommonName, subject)
178-
}
167+
case token.AWS, token.GCP, token.Azure:
168+
// Common name will be validated on the server side, it depends on
169+
// server configuration.
179170
default:
180171
return errors.New("token is not supported")
181172
}
@@ -235,20 +226,9 @@ func (f *certificateFlow) getClient(ctx *cli.Context, subject, tok string) (caCl
235226
return nil, errors.Wrap(err, "error parsing flag '--token'")
236227
}
237228
switch jwt.Payload.Type() {
238-
case token.AWS:
239-
instanceID := jwt.Payload.Amazon.InstanceIdentityDocument.InstanceID
240-
if strings.ToLower(instanceID) != strings.ToLower(subject) {
241-
return nil, errors.Errorf("token amazon.document.instanceId '%s' and CSR CommonName '%s' do not match", instanceID, subject)
242-
}
243-
case token.GCP:
244-
instanceName := jwt.Payload.Google.ComputeEngine.InstanceName
245-
if strings.ToLower(instanceName) != strings.ToLower(subject) {
246-
return nil, errors.Errorf("token google.compute_engine.instance_name '%s' and CSR CommonName '%s' do not match", instanceName, subject)
247-
}
248-
case token.Azure:
249-
if strings.ToLower(jwt.Payload.Azure.VirtualMachine) != strings.ToLower(subject) {
250-
return nil, errors.Errorf("token virtual machine '%s' and CSR CommonName '%s' do not match", jwt.Payload.Azure.VirtualMachine, subject)
251-
}
229+
case token.AWS, token.GCP, token.Azure:
230+
// Common name will be validated on the server side, it depends on
231+
// server configuration.
252232
default:
253233
if strings.ToLower(jwt.Payload.Subject) != strings.ToLower(subject) {
254234
return nil, errors.Errorf("token subject '%s' and CSR CommonName '%s' do not match", jwt.Payload.Subject, subject)
@@ -351,7 +331,7 @@ func (f *certificateFlow) Sign(ctx *cli.Context, token string, csr api.Certifica
351331

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

371-
subject := jwt.Payload.Subject
372351
switch jwt.Payload.Type() {
373352
case token.AWS:
374353
doc := jwt.Payload.Amazon.InstanceIdentityDocument
375-
subject = doc.InstanceID
376354
if len(ips) == 0 && len(dnsNames) == 0 {
377355
ips = append(ips, net.ParseIP(doc.PrivateIP))
378356
dnsNames = append(dnsNames,
@@ -381,18 +359,18 @@ func (f *certificateFlow) CreateSignRequest(tok string, sans []string) (*api.Sig
381359
}
382360
case token.GCP:
383361
ce := jwt.Payload.Google.ComputeEngine
384-
subject = ce.InstanceName
385362
if len(dnsNames) == 0 {
386363
dnsNames = append(dnsNames,
387364
fmt.Sprintf("%s.c.%s.internal", ce.InstanceName, ce.ProjectID),
388365
fmt.Sprintf("%s.%s.c.%s.internal", ce.InstanceName, ce.Zone, ce.ProjectID),
389366
)
390367
}
391368
case token.Azure:
392-
subject = jwt.Payload.Azure.VirtualMachine
393369
if len(dnsNames) == 0 {
394370
dnsNames = append(dnsNames, jwt.Payload.Azure.VirtualMachine)
395371
}
372+
default: // Use common name in the token
373+
subject = jwt.Payload.Subject
396374
}
397375

398376
template := &x509.CertificateRequest{

command/ca/offline.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,11 @@ func (c *offlineCA) GenerateToken(ctx *cli.Context, typ int, subject string, san
239239
}
240240
return strings.TrimSpace(string(out)), nil
241241
case *provisioner.GCP: // Do the identity request to get the token
242-
return p.GetIdentityToken(c.CaURL())
242+
return p.GetIdentityToken(subject, c.CaURL())
243243
case *provisioner.AWS: // Do the identity request to get the token
244-
return p.GetIdentityToken(c.CaURL())
244+
return p.GetIdentityToken(subject, c.CaURL())
245245
case *provisioner.Azure: // Do the identity request to get the token
246-
return p.GetIdentityToken()
247-
}
248-
249-
// With OIDC just run step oauth
250-
if p, ok := p.(*provisioner.OIDC); ok {
251-
out, err := exec.Step("oauth", "--oidc", "--bare",
252-
"--provider", p.ConfigurationEndpoint,
253-
"--client-id", p.ClientID, "--client-secret", p.ClientSecret)
254-
if err != nil {
255-
return "", err
256-
}
257-
return string(out), nil
246+
return p.GetIdentityToken(subject, c.CaURL())
258247
}
259248

260249
// JWK provisioner

command/ca/token.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,11 @@ func newTokenFlow(ctx *cli.Context, typ int, subject string, sans []string, caUR
350350
}
351351
return strings.TrimSpace(string(out)), nil
352352
case *provisioner.GCP: // Do the identity request to get the token
353-
return p.GetIdentityToken(caURL)
353+
return p.GetIdentityToken(subject, caURL)
354354
case *provisioner.AWS: // Do the identity request to get the token
355-
return p.GetIdentityToken(caURL)
355+
return p.GetIdentityToken(subject, caURL)
356356
case *provisioner.Azure: // Do the identity request to get the token
357-
return p.GetIdentityToken()
357+
return p.GetIdentityToken(subject, caURL)
358358
}
359359

360360
// JWK provisioner

0 commit comments

Comments
 (0)