forked from TrueCloudLab/certificates
provisioner issuer -> name
This commit is contained in:
parent
ce5f420d77
commit
0d9dd2d14b
11 changed files with 57 additions and 44 deletions
|
@ -682,13 +682,13 @@ func Test_caHandler_Provisioners(t *testing.T) {
|
|||
p := []*authority.Provisioner{
|
||||
{
|
||||
Type: "JWK",
|
||||
Issuer: "max",
|
||||
Name: "max",
|
||||
EncryptedKey: "abc",
|
||||
Key: &key,
|
||||
},
|
||||
{
|
||||
Type: "JWK",
|
||||
Issuer: "mariano",
|
||||
Name: "mariano",
|
||||
EncryptedKey: "def",
|
||||
Key: &key,
|
||||
},
|
||||
|
|
|
@ -115,7 +115,7 @@ func (a *Authority) init() error {
|
|||
}
|
||||
|
||||
for _, p := range a.config.AuthorityConfig.Provisioners {
|
||||
a.provisionerIDIndex.Store(p.Key.KeyID, p)
|
||||
a.provisionerIDIndex.Store(p.ID(), p)
|
||||
if len(p.EncryptedKey) != 0 {
|
||||
a.encryptedKeyIndex.Store(p.Key.KeyID, p.EncryptedKey)
|
||||
}
|
||||
|
|
|
@ -17,14 +17,14 @@ func testAuthority(t *testing.T) *Authority {
|
|||
assert.FatalError(t, err)
|
||||
p := []*Provisioner{
|
||||
{
|
||||
Issuer: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
Name: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
},
|
||||
{
|
||||
Issuer: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
Name: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
},
|
||||
}
|
||||
c := &Config{
|
||||
|
@ -113,7 +113,7 @@ func TestAuthorityNew(t *testing.T) {
|
|||
assert.True(t, auth.initOnce)
|
||||
assert.NotNil(t, auth.intermediateIdentity)
|
||||
for _, p := range tc.config.AuthorityConfig.Provisioners {
|
||||
_p, ok := auth.provisionerIDIndex.Load(p.Key.KeyID)
|
||||
_p, ok := auth.provisionerIDIndex.Load(p.ID())
|
||||
assert.True(t, ok)
|
||||
assert.Equals(t, p, _p)
|
||||
if len(p.EncryptedKey) > 0 {
|
||||
|
|
|
@ -44,14 +44,21 @@ func (a *Authority) Authorize(ott string) ([]interface{}, error) {
|
|||
http.StatusUnauthorized, errContext}
|
||||
}
|
||||
|
||||
// Get claims w/out verification. We need to look up the provisioner
|
||||
// key in order to verify the claims and we need the issuer from the claims
|
||||
// before we can look up the provisioner.
|
||||
if err = token.UnsafeClaimsWithoutVerification(&claims); err != nil {
|
||||
return nil, &apiError{err, http.StatusUnauthorized, errContext}
|
||||
}
|
||||
kid := token.Headers[0].KeyID // JWT will only have 1 header.
|
||||
if len(kid) == 0 {
|
||||
return nil, &apiError{errors.New("authorize: token KeyID cannot be empty"),
|
||||
http.StatusUnauthorized, errContext}
|
||||
}
|
||||
val, ok := a.provisionerIDIndex.Load(kid)
|
||||
pid := claims.Issuer + ":" + kid
|
||||
val, ok := a.provisionerIDIndex.Load(pid)
|
||||
if !ok {
|
||||
return nil, &apiError{errors.Errorf("authorize: provisioner with KeyID %s not found", kid),
|
||||
return nil, &apiError{errors.Errorf("authorize: provisioner with id %s not found", pid),
|
||||
http.StatusUnauthorized, errContext}
|
||||
}
|
||||
p, ok := val.(*Provisioner)
|
||||
|
@ -67,7 +74,7 @@ func (a *Authority) Authorize(ott string) ([]interface{}, error) {
|
|||
// According to "rfc7519 JSON Web Token" acceptable skew should be no
|
||||
// more than a few minutes.
|
||||
if err = claims.ValidateWithLeeway(jwt.Expected{
|
||||
Issuer: p.Issuer,
|
||||
Issuer: p.Name,
|
||||
}, time.Minute); err != nil {
|
||||
return nil, &apiError{errors.Wrapf(err, "authorize: invalid token"),
|
||||
http.StatusUnauthorized, errContext}
|
||||
|
|
|
@ -121,7 +121,7 @@ func TestAuthorize(t *testing.T) {
|
|||
return &authorizeTest{
|
||||
auth: a,
|
||||
ott: raw,
|
||||
err: &apiError{errors.New("authorize: provisioner with KeyID foo not found"),
|
||||
err: &apiError{errors.New("authorize: provisioner with id step-cli:foo not found"),
|
||||
http.StatusUnauthorized, context{"ott": raw}},
|
||||
}
|
||||
},
|
||||
|
@ -132,7 +132,7 @@ func TestAuthorize(t *testing.T) {
|
|||
(&jose.SignerOptions{}).WithType("JWT").WithHeader("kid", "foo"))
|
||||
assert.FatalError(t, err)
|
||||
|
||||
_a.provisionerIDIndex.Store("foo", "42")
|
||||
_a.provisionerIDIndex.Store(validIssuer+":foo", "42")
|
||||
|
||||
cl := jwt.Claims{
|
||||
Subject: "test.smallstep.com",
|
||||
|
@ -164,7 +164,7 @@ func TestAuthorize(t *testing.T) {
|
|||
return &authorizeTest{
|
||||
auth: a,
|
||||
ott: raw,
|
||||
err: &apiError{errors.New("authorize: invalid token"),
|
||||
err: &apiError{errors.New("authorize: provisioner with id invalid-issuer:4UELJx8e0aS9m0CH3fZ0EB7D5aUPICb759zALHFejvc not found"),
|
||||
http.StatusUnauthorized, context{"ott": raw}},
|
||||
}
|
||||
},
|
||||
|
|
|
@ -19,14 +19,14 @@ func TestConfigValidate(t *testing.T) {
|
|||
ac := &AuthConfig{
|
||||
Provisioners: []*Provisioner{
|
||||
{
|
||||
Issuer: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
Name: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
},
|
||||
{
|
||||
Issuer: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
Name: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -217,14 +217,14 @@ func TestAuthConfigValidate(t *testing.T) {
|
|||
assert.FatalError(t, err)
|
||||
p := []*Provisioner{
|
||||
{
|
||||
Issuer: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
Name: "Max",
|
||||
Type: "JWK",
|
||||
Key: maxjwk,
|
||||
},
|
||||
{
|
||||
Issuer: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
Name: "step-cli",
|
||||
Type: "JWK",
|
||||
Key: clijwk,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -250,8 +250,8 @@ func TestAuthConfigValidate(t *testing.T) {
|
|||
return AuthConfigValidateTest{
|
||||
ac: &AuthConfig{
|
||||
Provisioners: []*Provisioner{
|
||||
{Issuer: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
|
||||
{Issuer: "foo", Key: &jose.JSONWebKey{}},
|
||||
{Name: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
|
||||
{Name: "foo", Key: &jose.JSONWebKey{}},
|
||||
},
|
||||
},
|
||||
err: errors.New("provisioner type cannot be empty"),
|
||||
|
|
|
@ -85,7 +85,7 @@ func (pc *ProvisionerClaims) Validate() error {
|
|||
|
||||
// Provisioner - authorized entity that can sign tokens necessary for signature requests.
|
||||
type Provisioner struct {
|
||||
Issuer string `json:"issuer,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Key *jose.JSONWebKey `json:"key,omitempty"`
|
||||
EncryptedKey string `json:"encryptedKey,omitempty"`
|
||||
|
@ -95,7 +95,7 @@ type Provisioner struct {
|
|||
// Init initializes and validates a the fields of Provisioner type.
|
||||
func (p *Provisioner) Init(global *ProvisionerClaims) error {
|
||||
switch {
|
||||
case p.Issuer == "":
|
||||
case p.Name == "":
|
||||
return errors.New("provisioner issuer cannot be empty")
|
||||
|
||||
case p.Type == "":
|
||||
|
@ -117,7 +117,7 @@ func (p *Provisioner) getTLSApps(so SignOptions) ([]x509util.WithOption, []certC
|
|||
return []x509util.WithOption{
|
||||
x509util.WithNotBeforeAfterDuration(so.NotBefore,
|
||||
so.NotAfter, c.DefaultTLSCertDuration()),
|
||||
withProvisionerOID(p.Issuer, p.Key.KeyID),
|
||||
withProvisionerOID(p.Name, p.Key.KeyID),
|
||||
}, []certClaim{
|
||||
&certTemporalClaim{
|
||||
min: c.MinTLSCertDuration(),
|
||||
|
@ -125,3 +125,9 @@ func (p *Provisioner) getTLSApps(so SignOptions) ([]x509util.WithOption, []certC
|
|||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ID returns the provisioner identifier. The name and credential id should
|
||||
// uniquely identify any provisioner.
|
||||
func (p *Provisioner) ID() string {
|
||||
return p.Name + ":" + p.Key.KeyID
|
||||
}
|
||||
|
|
|
@ -22,19 +22,19 @@ func TestProvisionerInit(t *testing.T) {
|
|||
},
|
||||
"fail-empty-type": func(t *testing.T) ProvisionerValidateTest {
|
||||
return ProvisionerValidateTest{
|
||||
p: &Provisioner{Issuer: "foo"},
|
||||
p: &Provisioner{Name: "foo"},
|
||||
err: errors.New("provisioner type cannot be empty"),
|
||||
}
|
||||
},
|
||||
"fail-empty-key": func(t *testing.T) ProvisionerValidateTest {
|
||||
return ProvisionerValidateTest{
|
||||
p: &Provisioner{Issuer: "foo", Type: "bar"},
|
||||
p: &Provisioner{Name: "foo", Type: "bar"},
|
||||
err: errors.New("provisioner key cannot be empty"),
|
||||
}
|
||||
},
|
||||
"ok": func(t *testing.T) ProvisionerValidateTest {
|
||||
return ProvisionerValidateTest{
|
||||
p: &Provisioner{Issuer: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
|
||||
p: &Provisioner{Name: "foo", Type: "bar", Key: &jose.JSONWebKey{}},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ func TestGetEncryptedKey(t *testing.T) {
|
|||
}
|
||||
} else {
|
||||
if assert.Nil(t, tc.err) {
|
||||
val, ok := tc.a.provisionerIDIndex.Load(tc.kid)
|
||||
val, ok := tc.a.provisionerIDIndex.Load("max:" + tc.kid)
|
||||
assert.Fatal(t, ok)
|
||||
p, ok := val.(*Provisioner)
|
||||
assert.Fatal(t, ok)
|
||||
|
@ -155,7 +155,7 @@ func generateProvisioner(t *testing.T) *Provisioner {
|
|||
encrypted, err := jwe.CompactSerialize()
|
||||
assert.FatalError(t, err)
|
||||
return &Provisioner{
|
||||
Issuer: issuer,
|
||||
Name: issuer,
|
||||
Type: "JWT",
|
||||
Key: &public,
|
||||
EncryptedKey: encrypted,
|
||||
|
|
|
@ -204,7 +204,7 @@ func TestSign(t *testing.T) {
|
|||
_, err := asn1.Unmarshal(ext.Value, &val)
|
||||
assert.FatalError(t, err)
|
||||
assert.Equals(t, val.Type, provisionerTypeJWK)
|
||||
assert.Equals(t, val.Name, []byte(p.Issuer))
|
||||
assert.Equals(t, val.Name, []byte(p.Name))
|
||||
assert.Equals(t, val.CredentialID, []byte(p.Key.KeyID))
|
||||
}
|
||||
assert.Equals(t, found, 1)
|
||||
|
|
10
ca/testdata/ca.json
vendored
10
ca/testdata/ca.json
vendored
|
@ -20,7 +20,7 @@
|
|||
"minCertDuration": "1m",
|
||||
"provisioners": [
|
||||
{
|
||||
"issuer": "max",
|
||||
"name": "max",
|
||||
"type": "jwk",
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IkpsNkZLWUp4V1UwdGRIbG9UanA1aGcifQ.Qy0EP6u5-t0ggOweoc3Z1DCzR5BllsQi.KUkviZ_TJKY4c0Mi.h7QZqgh_Fl2MZpmVy4h375yC0DORjB1dQULbNqc6MuUCW2iweWVRysFImUXiXMUKRarJC5adwWy1GhyAqUj6Xj1iOZDGLjYnqMETGWcI0rKDBwcSU7y7Y-2VYBRDSM2b7aWtTBfz3_kvEaw_vc3b5CEPJ86UlZc-jhKFRr_IcGWU-vXX5-bppoH15IPreyzi55YdjCll338lYpDecB_Paym3XBXotyd2iGXXUwoA1npEFwuyRMMEhl9zLp7rVcMW6A_32EzB8cZANEnA0C4FXGHQalY6u_2UeqxcC8_FuXPay6VIYODyRqcABvvkft3nwOcrI0pYDGBdk2w2Euk.kOAFq3Tg6s4vBGS_plMpSw",
|
||||
"key": {
|
||||
|
@ -33,7 +33,7 @@
|
|||
"y": "ZhYcFQBqtErdC_pA7sOXrO7AboCEPIKP9Ik4CHJqANk"
|
||||
}
|
||||
}, {
|
||||
"issuer": "max",
|
||||
"name": "max",
|
||||
"type": "jwk",
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlZsWnl0dUxrWTR5enlqZXJybnN0aGcifQ.QP15wQYjZ12BLgl-XTq2Vb12G3OHAfic.X35QqAaXwnlmeCUU._2qIUp0TI8yDI7c2e9upIRdrnmB5OvtLfrYN-Su2NLBpaoYtr9O55Wo0Iryc0W2pYqnVDPvgPPes4P4nQAnzw5WhFYc1Xf1ZEetfdNhwi1x2FNwPbACBAgxm5AW40O5AAlbLcWushYASfeMBZocTGXuSGUzwFqoWD-5EDJ80TWQ7cAj3ttHrJ_3QV9hi4O9KJUCiXngN-Yz2zXrhBL4NOH2fmRbaf5c0rF8xUJIIW-TcyYJeX_Fbx1IzzKKPd9USUwkDhxD4tLa51I345xVqjuwG1PEn6nF8JKqLRVUKEKFin-ShXrfE61KceyAvm4YhWKrbJWIm3bH5Hxaphy4.TexIrIhsRxJStpE3EJ925Q",
|
||||
"key": {
|
||||
|
@ -46,7 +46,7 @@
|
|||
"y": "wnqZSMuXpmUxORq20t83LyY4BDYmqDGV9P7FGR6mw84"
|
||||
}
|
||||
}, {
|
||||
"issuer": "step-cli",
|
||||
"name": "step-cli",
|
||||
"type": "jwk",
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlhOdmYxQjgxSUlLMFA2NUkwcmtGTGcifQ.XaN9zcPQeWt49zchUDm34FECUTHfQTn_.tmNHPQDqR3ebsWfd.9WZr3YVdeOyJh36vvx0VlRtluhvYp4K7jJ1KGDr1qypwZ3ziBVSNbYYQ71du7fTtrnfG1wgGTVR39tWSzBU-zwQ5hdV3rpMAaEbod5zeW6SHd95H3Bvcb43YiiqJFNL5sGZzFb7FqzVmpsZ1efiv6sZaGDHtnCAL6r12UG5EZuqGfM0jGCZitUz2m9TUKXJL5DJ7MOYbFfkCEsUBPDm_TInliSVn2kMJhFa0VOe5wZk5YOuYM3lNYW64HGtbf-llN2Xk-4O9TfeSPizBx9ZqGpeu8pz13efUDT2WL9tWo6-0UE-CrG0bScm8lFTncTkHcu49_a5NaUBkYlBjEiw.thPcx3t1AUcWuEygXIY3Fg",
|
||||
"key": {
|
||||
|
@ -59,7 +59,7 @@
|
|||
"y": "sQr2JdzwD2fgyrymBEXWsxDxFNjjqN64qLLSbLdLZ9Y"
|
||||
}
|
||||
}, {
|
||||
"issuer": "mariano",
|
||||
"name": "mariano",
|
||||
"type": "jwk",
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6IlB1UnJVQ1RZZkR1T2F5MEh2cGl6bncifQ.7a-OP5xWGbFra8m2MN9YuLGt6v4y0wmB.u-54daK2y-0UO9na.3GQy6E52-fOSUu5NJ_sEbxj_T3CTyWb7wOPFv2oI2PBWXp5CLpiWJbCFpF4v2oD9fN5XbxMP14ootbrFjATnoMWfWgyLwG-KOj9BqMGNxhG2v37yC7Wrris6s30nrPa3uyNEYZ12AOQW1K04cU2X0u_qJM3vzMCle548ZFTWs6_d6L8lp3o0F9MEbCmJ4p6CLqQxjxYtn1aD79lM91NbIXpRP3iUFQRly-y_iC2mSkXCdd_cQ6-dqLUchXwWRyVO5nBHb4J87aZ91VApw7ldTLtwRZ2ZGJpqGQGgjTwi4sgjEcMuGg0_83XGk2ubdlKDpmGFedOHS5rYCbxotts.vSYfxsi2UU9LQeySDjAnnQ",
|
||||
"key": {
|
||||
|
@ -75,7 +75,7 @@
|
|||
"minTLSCertDuration": "30s"
|
||||
}
|
||||
}, {
|
||||
"issuer": "mariano",
|
||||
"name": "mariano",
|
||||
"type": "jwk",
|
||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4R0NNIiwicDJjIjoxMDAwMDAsInAycyI6Ik5SLTk5ZkVMSm1CLW1FZGllUlFFc3cifQ.Fr314BEUGTda4ICJl2uxFdjpEUGGqJEV.gBbu_DZE1ONDu14r.X-7MKMyokZIF1HTCVqqL0tTWgaC1ZGZBLLltd11ZUhQTswo_8kvgiTv3cFShj7ATF0tAY8HStyJmzLO8mKPVOPDXSwjdNsPriZclI6JWGi9iOu8pEiN9pZM6-itxan1JMcDUNg2U-P1BmKppHRbDKsOTivymfRyeUk51dBIlS54p5xNK1HFLc1YtWC1Rc_ngYVqOgqlhIrCHArAEBe3jrfUaH2ym-8fkVdwVqtxmte3XXK9g8FchsygRNnOKtRcr0TyzTUV-7bPi8_t02Zi-EHLFaSawVXWV_Qk1GeLYJR22Rp74beo-b5-lCNVp10btO0xdGySUWmCJ4v4_QZw.c8unwWycwtfdJMM_0b0fuA",
|
||||
"key": {
|
||||
|
|
Loading…
Add table
Reference in a new issue