provisioner issuer -> name

pull/2/head
max furman 6 years ago
parent ce5f420d77
commit 0d9dd2d14b

@ -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)

@ -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…
Cancel
Save