forked from TrueCloudLab/certificates
Merge pull request #395 from smallstep/aws-identity-cert
Add option to specify the AWS IID certificates to use.
This commit is contained in:
commit
6838233416
7 changed files with 158 additions and 33 deletions
|
@ -75,25 +75,49 @@ type awsConfig struct {
|
||||||
signatureURL string
|
signatureURL string
|
||||||
tokenURL string
|
tokenURL string
|
||||||
tokenTTL string
|
tokenTTL string
|
||||||
certificate *x509.Certificate
|
certificates []*x509.Certificate
|
||||||
signatureAlgorithm x509.SignatureAlgorithm
|
signatureAlgorithm x509.SignatureAlgorithm
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAWSConfig() (*awsConfig, error) {
|
func newAWSConfig(certPath string) (*awsConfig, error) {
|
||||||
block, _ := pem.Decode([]byte(awsCertificate))
|
var certBytes []byte
|
||||||
if block == nil || block.Type != "CERTIFICATE" {
|
if certPath == "" {
|
||||||
return nil, errors.New("error decoding AWS certificate")
|
certBytes = []byte(awsCertificate)
|
||||||
|
} else {
|
||||||
|
if b, err := ioutil.ReadFile(certPath); err == nil {
|
||||||
|
certBytes = b
|
||||||
|
} else {
|
||||||
|
return nil, errors.Wrapf(err, "error reading %s", certPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cert, err := x509.ParseCertificate(block.Bytes)
|
|
||||||
if err != nil {
|
// Read all the certificates.
|
||||||
return nil, errors.Wrap(err, "error parsing AWS certificate")
|
var certs []*x509.Certificate
|
||||||
|
for len(certBytes) > 0 {
|
||||||
|
var block *pem.Block
|
||||||
|
block, certBytes = pem.Decode(certBytes)
|
||||||
|
if block == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cert, err := x509.ParseCertificate(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "error parsing AWS IID certificate")
|
||||||
|
}
|
||||||
|
certs = append(certs, cert)
|
||||||
}
|
}
|
||||||
|
if len(certs) == 0 {
|
||||||
|
return nil, errors.New("error parsing AWS IID certificate: no certificates found")
|
||||||
|
}
|
||||||
|
|
||||||
return &awsConfig{
|
return &awsConfig{
|
||||||
identityURL: awsIdentityURL,
|
identityURL: awsIdentityURL,
|
||||||
signatureURL: awsSignatureURL,
|
signatureURL: awsSignatureURL,
|
||||||
tokenURL: awsAPITokenURL,
|
tokenURL: awsAPITokenURL,
|
||||||
tokenTTL: awsAPITokenTTL,
|
tokenTTL: awsAPITokenTTL,
|
||||||
certificate: cert,
|
certificates: certs,
|
||||||
signatureAlgorithm: awsSignatureAlgorithm,
|
signatureAlgorithm: awsSignatureAlgorithm,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -140,6 +164,9 @@ type awsInstanceIdentityDocument struct {
|
||||||
// If InstanceAge is set, only the instances with a pendingTime within the given
|
// If InstanceAge is set, only the instances with a pendingTime within the given
|
||||||
// period will be accepted.
|
// period will be accepted.
|
||||||
//
|
//
|
||||||
|
// IIDRoots can be used to specify a path to the certificates used to verify the
|
||||||
|
// identity certificate signature.
|
||||||
|
//
|
||||||
// Amazon Identity docs are available at
|
// Amazon Identity docs are available at
|
||||||
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
|
||||||
type AWS struct {
|
type AWS struct {
|
||||||
|
@ -151,6 +178,7 @@ type AWS struct {
|
||||||
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
DisableTrustOnFirstUse bool `json:"disableTrustOnFirstUse"`
|
||||||
IMDSVersions []string `json:"imdsVersions"`
|
IMDSVersions []string `json:"imdsVersions"`
|
||||||
InstanceAge Duration `json:"instanceAge,omitempty"`
|
InstanceAge Duration `json:"instanceAge,omitempty"`
|
||||||
|
IIDRoots string `json:"iidRoots,omitempty"`
|
||||||
Claims *Claims `json:"claims,omitempty"`
|
Claims *Claims `json:"claims,omitempty"`
|
||||||
Options *Options `json:"options,omitempty"`
|
Options *Options `json:"options,omitempty"`
|
||||||
claimer *Claimer
|
claimer *Claimer
|
||||||
|
@ -260,7 +288,7 @@ func (p *AWS) GetIdentityToken(subject, caURL string) (string, error) {
|
||||||
|
|
||||||
tok, err := jose.Signed(signer).Claims(payload).CompactSerialize()
|
tok, err := jose.Signed(signer).Claims(payload).CompactSerialize()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, "error serialiazing token")
|
return "", errors.Wrap(err, "error serializing token")
|
||||||
}
|
}
|
||||||
|
|
||||||
return tok, nil
|
return tok, nil
|
||||||
|
@ -281,7 +309,7 @@ func (p *AWS) Init(config Config) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Add default config
|
// Add default config
|
||||||
if p.config, err = newAWSConfig(); err != nil {
|
if p.config, err = newAWSConfig(p.IIDRoots); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.audiences = config.Audiences.WithFragment(p.GetID())
|
p.audiences = config.Audiences.WithFragment(p.GetID())
|
||||||
|
@ -371,16 +399,18 @@ func (p *AWS) assertConfig() (err error) {
|
||||||
if p.config != nil {
|
if p.config != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p.config, err = newAWSConfig()
|
p.config, err = newAWSConfig(p.IIDRoots)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkSignature returns an error if the signature is not valid.
|
// checkSignature returns an error if the signature is not valid.
|
||||||
func (p *AWS) checkSignature(signed, signature []byte) error {
|
func (p *AWS) checkSignature(signed, signature []byte) error {
|
||||||
if err := p.config.certificate.CheckSignature(p.config.signatureAlgorithm, signed, signature); err != nil {
|
for _, crt := range p.config.certificates {
|
||||||
return errors.Wrap(err, "error validating identity document signature")
|
if err := crt.CheckSignature(p.config.signatureAlgorithm, signed, signature); err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return errors.New("error validating identity document signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
// readURL does a GET request to the given url and returns the body. It's not
|
// readURL does a GET request to the given url and returns the body. It's not
|
||||||
|
|
|
@ -178,8 +178,12 @@ func TestAWS_GetIdentityToken(t *testing.T) {
|
||||||
assert.Equals(t, tt.args.subject, c.Subject)
|
assert.Equals(t, tt.args.subject, c.Subject)
|
||||||
assert.Equals(t, jose.Audience{u.ResolveReference(&url.URL{Path: "/1.0/sign", Fragment: tt.aws.GetID()}).String()}, c.Audience)
|
assert.Equals(t, jose.Audience{u.ResolveReference(&url.URL{Path: "/1.0/sign", Fragment: tt.aws.GetID()}).String()}, c.Audience)
|
||||||
assert.Equals(t, tt.aws.Accounts[0], c.document.AccountID)
|
assert.Equals(t, tt.aws.Accounts[0], c.document.AccountID)
|
||||||
err = tt.aws.config.certificate.CheckSignature(
|
for _, crt := range tt.aws.config.certificates {
|
||||||
tt.aws.config.signatureAlgorithm, c.Amazon.Document, c.Amazon.Signature)
|
err = crt.CheckSignature(tt.aws.config.signatureAlgorithm, c.Amazon.Document, c.Amazon.Signature)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,8 +210,12 @@ func TestAWS_GetIdentityToken_V1Only(t *testing.T) {
|
||||||
assert.Equals(t, subject, c.Subject)
|
assert.Equals(t, subject, c.Subject)
|
||||||
assert.Equals(t, jose.Audience{u.ResolveReference(&url.URL{Path: "/1.0/sign", Fragment: aws.GetID()}).String()}, c.Audience)
|
assert.Equals(t, jose.Audience{u.ResolveReference(&url.URL{Path: "/1.0/sign", Fragment: aws.GetID()}).String()}, c.Audience)
|
||||||
assert.Equals(t, aws.Accounts[0], c.document.AccountID)
|
assert.Equals(t, aws.Accounts[0], c.document.AccountID)
|
||||||
err = aws.config.certificate.CheckSignature(
|
for _, crt := range aws.config.certificates {
|
||||||
aws.config.signatureAlgorithm, c.Amazon.Document, c.Amazon.Signature)
|
err = crt.CheckSignature(aws.config.signatureAlgorithm, c.Amazon.Document, c.Amazon.Signature)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,6 +255,7 @@ func TestAWS_Init(t *testing.T) {
|
||||||
DisableTrustOnFirstUse bool
|
DisableTrustOnFirstUse bool
|
||||||
InstanceAge Duration
|
InstanceAge Duration
|
||||||
IMDSVersions []string
|
IMDSVersions []string
|
||||||
|
IIDRoots string
|
||||||
Claims *Claims
|
Claims *Claims
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
|
@ -258,16 +267,19 @@ func TestAWS_Init(t *testing.T) {
|
||||||
args args
|
args args
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"ok", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, false},
|
{"ok", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, "", nil}, args{config}, false},
|
||||||
{"ok/v1", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1"}, nil}, args{config}, false},
|
{"ok/v1", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1"}, "", nil}, args{config}, false},
|
||||||
{"ok/v2", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v2"}, nil}, args{config}, false},
|
{"ok/v2", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v2"}, "", nil}, args{config}, false},
|
||||||
{"ok/empty", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{}, nil}, args{config}, false},
|
{"ok/empty", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{}, "", nil}, args{config}, false},
|
||||||
{"ok/duration", fields{"AWS", "name", []string{"account"}, true, true, Duration{Duration: 1 * time.Minute}, []string{"v1", "v2"}, nil}, args{config}, false},
|
{"ok/duration", fields{"AWS", "name", []string{"account"}, true, true, Duration{Duration: 1 * time.Minute}, []string{"v1", "v2"}, "", nil}, args{config}, false},
|
||||||
{"fail type ", fields{"", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, true},
|
{"ok/cert", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, "testdata/certs/aws.crt", nil}, args{config}, false},
|
||||||
{"fail name", fields{"AWS", "", []string{"account"}, false, false, zero, []string{"v1", "v2"}, nil}, args{config}, true},
|
{"fail type ", fields{"", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, "", nil}, args{config}, true},
|
||||||
{"bad instance age", fields{"AWS", "name", []string{"account"}, false, false, Duration{Duration: -1 * time.Minute}, []string{"v1", "v2"}, nil}, args{config}, true},
|
{"fail name", fields{"AWS", "", []string{"account"}, false, false, zero, []string{"v1", "v2"}, "", nil}, args{config}, true},
|
||||||
{"fail/imds", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"bad"}, nil}, args{config}, true},
|
{"bad instance age", fields{"AWS", "name", []string{"account"}, false, false, Duration{Duration: -1 * time.Minute}, []string{"v1", "v2"}, "", nil}, args{config}, true},
|
||||||
{"fail claims", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, badClaims}, args{config}, true},
|
{"fail/imds", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"bad"}, "", nil}, args{config}, true},
|
||||||
|
{"fail/missing", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"bad"}, "testdata/missing.crt", nil}, args{config}, true},
|
||||||
|
{"fail/cert", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"bad"}, "testdata/certs/rsa.csr", nil}, args{config}, true},
|
||||||
|
{"fail claims", fields{"AWS", "name", []string{"account"}, false, false, zero, []string{"v1", "v2"}, "", badClaims}, args{config}, true},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
@ -279,6 +291,7 @@ func TestAWS_Init(t *testing.T) {
|
||||||
DisableTrustOnFirstUse: tt.fields.DisableTrustOnFirstUse,
|
DisableTrustOnFirstUse: tt.fields.DisableTrustOnFirstUse,
|
||||||
InstanceAge: tt.fields.InstanceAge,
|
InstanceAge: tt.fields.InstanceAge,
|
||||||
IMDSVersions: tt.fields.IMDSVersions,
|
IMDSVersions: tt.fields.IMDSVersions,
|
||||||
|
IIDRoots: tt.fields.IIDRoots,
|
||||||
Claims: tt.fields.Claims,
|
Claims: tt.fields.Claims,
|
||||||
}
|
}
|
||||||
if err := p.Init(tt.args.config); (err != nil) != tt.wantErr {
|
if err := p.Init(tt.args.config); (err != nil) != tt.wantErr {
|
||||||
|
@ -457,6 +470,19 @@ func TestAWS_authorizeToken(t *testing.T) {
|
||||||
err: errors.New("aws.authorizeToken; aws identity document pendingTime is too old"),
|
err: errors.New("aws.authorizeToken; aws identity document pendingTime is too old"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fail/identityCert": func(t *testing.T) test {
|
||||||
|
p, err := generateAWS()
|
||||||
|
p.IIDRoots = "testdata/certs/aws.crt"
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
tok, err := generateAWSToken(
|
||||||
|
"instance-id", awsIssuer, p.GetID(), p.Accounts[0], "instance-id",
|
||||||
|
"127.0.0.1", "us-west-1", time.Now(), key)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
return test{
|
||||||
|
p: p,
|
||||||
|
token: tok,
|
||||||
|
}
|
||||||
|
},
|
||||||
"ok": func(t *testing.T) test {
|
"ok": func(t *testing.T) test {
|
||||||
p, err := generateAWS()
|
p, err := generateAWS()
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
@ -469,6 +495,19 @@ func TestAWS_authorizeToken(t *testing.T) {
|
||||||
token: tok,
|
token: tok,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ok/identityCert": func(t *testing.T) test {
|
||||||
|
p, err := generateAWS()
|
||||||
|
p.IIDRoots = "testdata/certs/aws-test.crt"
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
tok, err := generateAWSToken(
|
||||||
|
"instance-id", awsIssuer, p.GetID(), p.Accounts[0], "instance-id",
|
||||||
|
"127.0.0.1", "us-west-1", time.Now(), key)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
return test{
|
||||||
|
p: p,
|
||||||
|
token: tok,
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for name, tt := range tests {
|
for name, tt := range tests {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
|
|
33
authority/provisioner/testdata/certs/aws-test.crt
vendored
Normal file
33
authority/provisioner/testdata/certs/aws-test.crt
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDIjCCAougAwIBAgIJAKnL4UEDMN/FMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV
|
||||||
|
BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRgw
|
||||||
|
FgYDVQQKEw9BbWF6b24uY29tIEluYy4xGjAYBgNVBAMTEWVjMi5hbWF6b25hd3Mu
|
||||||
|
Y29tMB4XDTE0MDYwNTE0MjgwMloXDTI0MDYwNTE0MjgwMlowajELMAkGA1UEBhMC
|
||||||
|
VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxGDAWBgNV
|
||||||
|
BAoTD0FtYXpvbi5jb20gSW5jLjEaMBgGA1UEAxMRZWMyLmFtYXpvbmF3cy5jb20w
|
||||||
|
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIe9GN//SRK2knbjySG0ho3yqQM3
|
||||||
|
e2TDhWO8D2e8+XZqck754gFSo99AbT2RmXClambI7xsYHZFapbELC4H91ycihvrD
|
||||||
|
jbST1ZjkLQgga0NE1q43eS68ZeTDccScXQSNivSlzJZS8HJZjgqzBlXjZftjtdJL
|
||||||
|
XeE4hwvo0sD4f3j9AgMBAAGjgc8wgcwwHQYDVR0OBBYEFCXWzAgVyrbwnFncFFIs
|
||||||
|
77VBdlE4MIGcBgNVHSMEgZQwgZGAFCXWzAgVyrbwnFncFFIs77VBdlE4oW6kbDBq
|
||||||
|
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh
|
||||||
|
dHRsZTEYMBYGA1UEChMPQW1hem9uLmNvbSBJbmMuMRowGAYDVQQDExFlYzIuYW1h
|
||||||
|
em9uYXdzLmNvbYIJAKnL4UEDMN/FMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
|
||||||
|
BQADgYEAFYcz1OgEhQBXIwIdsgCOS8vEtiJYF+j9uO6jz7VOmJqO+pRlAbRlvY8T
|
||||||
|
C1haGgSI/A1uZUKs/Zfnph0oEI0/hu1IIJ/SKBDtN5lvmZ/IzbOPIJWirlsllQIQ
|
||||||
|
7zvWbGd9c9+Rm3p04oTvhup99la7kZqevJK0QRdD/6NpCKsqP/0=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICFTCCAX6gAwIBAgIRAKmbVVYAl/1XEqRfF3eJ97MwDQYJKoZIhvcNAQELBQAw
|
||||||
|
GDEWMBQGA1UEAxMNQVdTIFRlc3QgQ2VydDAeFw0xOTA0MjQyMjU3MzlaFw0yOTA0
|
||||||
|
MjEyMjU3MzlaMBgxFjAUBgNVBAMTDUFXUyBUZXN0IENlcnQwgZ8wDQYJKoZIhvcN
|
||||||
|
AQEBBQADgY0AMIGJAoGBAOHMmMXwbXN90SoRl/xXAcJs5TacaVYJ5iNAVWM5KYyF
|
||||||
|
+JwqYuJp/umLztFUi0oX0luu3EzD4KurVeUJSzZjTFTX1d/NX6hA45+bvdSUOcgV
|
||||||
|
UghO+2uhBZ4SNFxFRZ7SKvoWIN195l5bVX6/60Eo6+kUCKCkyxW4V/ksWzdXjHnf
|
||||||
|
AgMBAAGjXzBdMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMB0G
|
||||||
|
A1UdDgQWBBRHfLOjEddK/CWCIHNg8Oc/oJa1IzAYBgNVHREEETAPgg1BV1MgVGVz
|
||||||
|
dCBDZXJ0MA0GCSqGSIb3DQEBCwUAA4GBAKNCiVM9eGb9dW2xNyHaHAmmy7ERB2OJ
|
||||||
|
7oXHfLjooOavk9lU/Gs2jfX/JSBa84+DzWg9ShmCNLti8CxU/dhzXW7jE/5CcdTa
|
||||||
|
DCA6B3Yl5TmfG9+D9dtFqRB2CiMgNcsJJE5Dc6pDwBIiSj/MkE0AaGVQmSwn6Cb6
|
||||||
|
vX1TAxqeWJHq
|
||||||
|
-----END CERTIFICATE-----
|
19
authority/provisioner/testdata/certs/aws.crt
vendored
Normal file
19
authority/provisioner/testdata/certs/aws.crt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDIjCCAougAwIBAgIJAKnL4UEDMN/FMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV
|
||||||
|
BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRgw
|
||||||
|
FgYDVQQKEw9BbWF6b24uY29tIEluYy4xGjAYBgNVBAMTEWVjMi5hbWF6b25hd3Mu
|
||||||
|
Y29tMB4XDTE0MDYwNTE0MjgwMloXDTI0MDYwNTE0MjgwMlowajELMAkGA1UEBhMC
|
||||||
|
VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxGDAWBgNV
|
||||||
|
BAoTD0FtYXpvbi5jb20gSW5jLjEaMBgGA1UEAxMRZWMyLmFtYXpvbmF3cy5jb20w
|
||||||
|
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAIe9GN//SRK2knbjySG0ho3yqQM3
|
||||||
|
e2TDhWO8D2e8+XZqck754gFSo99AbT2RmXClambI7xsYHZFapbELC4H91ycihvrD
|
||||||
|
jbST1ZjkLQgga0NE1q43eS68ZeTDccScXQSNivSlzJZS8HJZjgqzBlXjZftjtdJL
|
||||||
|
XeE4hwvo0sD4f3j9AgMBAAGjgc8wgcwwHQYDVR0OBBYEFCXWzAgVyrbwnFncFFIs
|
||||||
|
77VBdlE4MIGcBgNVHSMEgZQwgZGAFCXWzAgVyrbwnFncFFIs77VBdlE4oW6kbDBq
|
||||||
|
MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh
|
||||||
|
dHRsZTEYMBYGA1UEChMPQW1hem9uLmNvbSBJbmMuMRowGAYDVQQDExFlYzIuYW1h
|
||||||
|
em9uYXdzLmNvbYIJAKnL4UEDMN/FMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
|
||||||
|
BQADgYEAFYcz1OgEhQBXIwIdsgCOS8vEtiJYF+j9uO6jz7VOmJqO+pRlAbRlvY8T
|
||||||
|
C1haGgSI/A1uZUKs/Zfnph0oEI0/hu1IIJ/SKBDtN5lvmZ/IzbOPIJWirlsllQIQ
|
||||||
|
7zvWbGd9c9+Rm3p04oTvhup99la7kZqevJK0QRdD/6NpCKsqP/0=
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -419,7 +419,7 @@ func generateAWS() (*AWS, error) {
|
||||||
signatureURL: awsSignatureURL,
|
signatureURL: awsSignatureURL,
|
||||||
tokenURL: awsAPITokenURL,
|
tokenURL: awsAPITokenURL,
|
||||||
tokenTTL: awsAPITokenTTL,
|
tokenTTL: awsAPITokenTTL,
|
||||||
certificate: cert,
|
certificates: []*x509.Certificate{cert},
|
||||||
signatureAlgorithm: awsSignatureAlgorithm,
|
signatureAlgorithm: awsSignatureAlgorithm,
|
||||||
},
|
},
|
||||||
audiences: testAudiences.WithFragment("aws/" + name),
|
audiences: testAudiences.WithFragment("aws/" + name),
|
||||||
|
@ -528,7 +528,7 @@ func generateAWSV1Only() (*AWS, error) {
|
||||||
signatureURL: awsSignatureURL,
|
signatureURL: awsSignatureURL,
|
||||||
tokenURL: awsAPITokenURL,
|
tokenURL: awsAPITokenURL,
|
||||||
tokenTTL: awsAPITokenTTL,
|
tokenTTL: awsAPITokenTTL,
|
||||||
certificate: cert,
|
certificates: []*x509.Certificate{cert},
|
||||||
signatureAlgorithm: awsSignatureAlgorithm,
|
signatureAlgorithm: awsSignatureAlgorithm,
|
||||||
},
|
},
|
||||||
audiences: testAudiences.WithFragment("aws/" + name),
|
audiences: testAudiences.WithFragment("aws/" + name),
|
||||||
|
|
|
@ -441,6 +441,7 @@ In the ca.json, an AWS provisioner looks like:
|
||||||
"disableCustomSANs": false,
|
"disableCustomSANs": false,
|
||||||
"disableTrustOnFirstUse": false,
|
"disableTrustOnFirstUse": false,
|
||||||
"instanceAge": "1h",
|
"instanceAge": "1h",
|
||||||
|
"iidRoots": "/path/to/aws.crt",
|
||||||
"claims": {
|
"claims": {
|
||||||
"maxTLSCertDuration": "2160h",
|
"maxTLSCertDuration": "2160h",
|
||||||
"defaultTLSCertDuration": "2160h"
|
"defaultTLSCertDuration": "2160h"
|
||||||
|
@ -468,6 +469,9 @@ In the ca.json, an AWS provisioner looks like:
|
||||||
* `instanceAge` (optional): the maximum age of an instance to grant a
|
* `instanceAge` (optional): the maximum age of an instance to grant a
|
||||||
certificate. The instance age is a string using the duration format.
|
certificate. The instance age is a string using the duration format.
|
||||||
|
|
||||||
|
* `iidRoots` (optional): the path to one or more public certificates in PEM
|
||||||
|
format used to validate the signature of the instance identity document.
|
||||||
|
|
||||||
* `claims` (optional): overwrites the default claims set in the authority, see
|
* `claims` (optional): overwrites the default claims set in the authority, see
|
||||||
the [top](#provisioners) section for all the options.
|
the [top](#provisioners) section for all the options.
|
||||||
|
|
||||||
|
|
|
@ -538,7 +538,7 @@ func (p *PKI) Save(opt ...Option) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := json.MarshalIndent(config, "", " ")
|
b, err := json.MarshalIndent(config, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error marshaling %s", p.config)
|
return errors.Wrapf(err, "error marshaling %s", p.config)
|
||||||
}
|
}
|
||||||
|
@ -568,7 +568,7 @@ func (p *PKI) Save(opt ...Option) error {
|
||||||
CAUrl: p.caURL,
|
CAUrl: p.caURL,
|
||||||
Fingerprint: p.rootFingerprint,
|
Fingerprint: p.rootFingerprint,
|
||||||
}
|
}
|
||||||
b, err = json.MarshalIndent(defaults, "", " ")
|
b, err = json.MarshalIndent(defaults, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error marshaling %s", p.defaults)
|
return errors.Wrapf(err, "error marshaling %s", p.defaults)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue