Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wire ACME extensions #1666

Open
wants to merge 179 commits into
base: master
Choose a base branch
from
Open

Wire ACME extensions #1666

wants to merge 179 commits into from

Conversation

hslatman
Copy link
Member

@hslatman hslatman commented Jan 8, 2024

No description provided.

stefanwire and others added 30 commits January 8, 2024 20:27
…_token. Also have a different mapping for id_token claims name
@hslatman hslatman added this to the v0.25.3 milestone Feb 20, 2024
@hslatman hslatman requested a review from a team March 5, 2024 18:19
maraino
maraino previously approved these changes Mar 5, 2024
Copy link
Contributor

@maraino maraino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, but I added a few comments about:

  1. One related to error messages
  2. Using net/url instead of kms/uri
  3. Split the db interface on two

I think it would be nice to fix 2 and 3 soon.

Comment on lines 646 to 657
if accessToken.Cnf.Kid == "" || accessToken.Cnf.Kid != v.dpopKeyID {
return nil, nil, fmt.Errorf("expected kid %q; got %q", v.dpopKeyID, accessToken.Cnf.Kid)
}
if accessToken.ClientID != v.wireID.ClientID {
return nil, nil, fmt.Errorf("invalid Wire client ID %q", accessToken.ClientID)
}
if accessToken.Expiry.Time().After(v.t.Add(time.Hour)) {
return nil, nil, fmt.Errorf("'exp' %s is too far into the future", accessToken.Expiry.Time().String())
}
if accessToken.Scope != "wire_client_id" {
return nil, nil, fmt.Errorf("invalid Wire scope %q", accessToken.Scope)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if the errors will follow the same format, all this a things in the token, and you have things like 'exp', kid, Wire scope

Comment on lines 687 to 701
if wireDpop.HTU == "" || wireDpop.HTU != v.issuer { // DPoP doesn't contains "iss" claim, but has it in the "htu" claim
return nil, nil, fmt.Errorf("DPoP contains invalid issuer (htu) %q", wireDpop.HTU)
}
if wireDpop.Expiry.Time().After(v.t.Add(time.Hour)) {
return nil, nil, fmt.Errorf("'exp' %s is too far into the future", wireDpop.Expiry.Time().String())
}
if wireDpop.Subject != v.wireID.ClientID {
return nil, nil, fmt.Errorf("DPoP contains invalid Wire client ID %q", wireDpop.ClientID)
}
if wireDpop.Nonce == "" || wireDpop.Nonce != accessToken.Nonce {
return nil, nil, fmt.Errorf("DPoP contains invalid nonce %q", wireDpop.Nonce)
}
if wireDpop.Challenge == "" || wireDpop.Challenge != accessToken.Challenge {
return nil, nil, fmt.Errorf("DPoP contains invalid challenge %q", wireDpop.Challenge)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here, (htu, 'exp', ...). One option can be Dpop contains invalid xxx ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And similar errors later.

Comment on lines +58 to +61
CreateDpopToken(ctx context.Context, orderID string, dpop map[string]interface{}) error
GetDpopToken(ctx context.Context, orderID string) (map[string]interface{}, error)
CreateOidcToken(ctx context.Context, orderID string, idToken map[string]interface{}) error
GetOidcToken(ctx context.Context, orderID string) (map[string]interface{}, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be in a TODO, but it should be fixed fast. We don't want different implementations of this DB to implement these methods unless is necessary. One simple solution would be something like:

type WireDB. interface{ 
   DB 
   GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error)
   // ...
}

acme/wire/id.go Outdated Show resolved Hide resolved
@hslatman
Copy link
Member Author

hslatman commented Mar 6, 2024

@maraino about the DB interface: I tried it before, but without changing a lot more, you'll end up with WireDB being used as the type in every struct, function and method that has to operate on the current DB interface, which I considered worse than just having these methods defined in the interface, and would basically result in what exists today.

This would've been a nice solution that I think can work, but isn't allowed in Go (today, at least; ref):

type DB interface {
    // DB methods
}
type WireDB interface {
    DB 
    // Wire methods
}
type NewDB interface {
    DB | WireDB
}

Alternatives would be:

  • Have the top level DB interface provide all methods, as it does now, and check at runtime that all(/only) the required methods are available, which could be based on some conditional logic taking into account the enabled challenge types. But that way it would still take the implementer to at least define the method in their implementation, so it's not a great solution.
  • Make the methods in the DB interface depend on a build tag.
  • Others ...?

It's not the cleanest solution, but implementers could always return some "not implemented" error. It's not as strong of a guarantee as having an interface, but it works.

So, time for the build tag?

@hslatman hslatman modified the milestones: v0.26.0, v0.26.1 Mar 29, 2024
@hslatman hslatman modified the milestones: v0.26.1, v0.26.2 Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Waiting for discussion / prioritization by team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants