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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
179 commits
Select commit Hold shift + click to select a range
8e0e355
Add Wire authz and challenges (OIDC+DPOP)
stefanwire Dec 8, 2022
da1e64a
update wire challenges' status on happy end
stefanwire Jan 31, 2023
5ca7445
simplify OIDC verification
stefanwire Feb 1, 2023
227e932
use json struct for challenge request payload otherwise it's a hell t…
beltram Feb 2, 2023
e6dd211
acquire DPoP signing key from provisioner
stefanwire Feb 2, 2023
1fe61be
better observability
beltram Feb 2, 2023
2208b03
avoid panic when OIDC config is not provided
stefanwire Feb 2, 2023
83f6be1
print oidc options
beltram Feb 2, 2023
74ddad6
fix: challenge is '.token' and not '.id'
beltram Feb 3, 2023
ca01c74
avoid manipulating the key PEM format and take a plain PEM key as input
beltram Feb 6, 2023
73ec6c8
fix csr org validation in finalize
beltram Feb 7, 2023
5ba0ab3
fix csr domain validation in finalize
beltram Feb 7, 2023
c41a99a
(finalize) have both display name & domain in SANs
beltram Feb 8, 2023
3eb0ff4
fix orderNames size
beltram Feb 8, 2023
b3dd169
cleanup my mess
beltram Feb 8, 2023
cc5fd0a
fix san validation
beltram Feb 9, 2023
01ef526
change uri prefix to impp:wireapp=
beltram Feb 9, 2023
af31a16
skip empty entries for uniqueSortedLowerNames
stefanwire Feb 9, 2023
b6ec442
feat: adapt to dex and pass the 'keyauth' in payload instead of in id…
beltram Feb 23, 2023
3f474f7
feat: change from impp prefix to just im
beltram Mar 6, 2023
79501df
fix: exclude displayName from SAN DNS
beltram Mar 7, 2023
4172b69
remove displayName validation, potentially harmful
beltram Mar 8, 2023
3576cc3
forward displayName in CSR with custom OID
beltram Mar 8, 2023
a49966f
try using google oidc for demo purpose
beltram Mar 28, 2023
49ad2d9
fix google id token matching in oidc challenge
beltram Mar 29, 2023
a97991a
infer domain from google email address
beltram Mar 29, 2023
680b6ea
adapt google demo for wire's special handle format "{firstname}_wire"
beltram Mar 30, 2023
7c9f802
fix: add URI prefix to handle
beltram Apr 3, 2023
b58de27
fix: do not convert URIs to lowercase for comparison purpose
beltram Apr 4, 2023
d32a3e2
wip
beltram May 3, 2023
9700204
fix: challenge target field was not mapped to db entity
beltram May 4, 2023
036a144
add oidc target
beltram May 4, 2023
2b1223a
simpler
beltram May 4, 2023
c4fb19d
passing expected issuer to rusty-jwt-cli
beltram May 4, 2023
83ba0bd
Replace field access by accessor functions
stefanwire May 5, 2023
5ceed08
Reorganize parsing target
stefanwire May 5, 2023
ff41a11
fix deviceId computing in dpop challenge
beltram May 5, 2023
a32bb66
trying to pass access token to template
beltram May 12, 2023
76dfcb0
try silencing template data for dichotomies
beltram May 15, 2023
abe8600
try by storing everything in db
beltram May 16, 2023
1a711e1
Add new Wire DB methods to `acme.DB` interface
hslatman Jan 8, 2024
2e12805
have updateOrder also update the update joint table [order by account]
beltram May 17, 2023
0bc530c
log more things
beltram May 22, 2023
8888262
cheat by allowing also looking up for ready orders
beltram May 22, 2023
0b68e1b
Add `GetAllOrdersByAccountID` to `MockDB`
hslatman Jan 8, 2024
613e6ca
wip
beltram May 22, 2023
03dbd91
fix dpop token json serialization to db
beltram May 22, 2023
f5b346e
i'm tired
beltram May 22, 2023
7b57401
support for oidc id token
beltram May 22, 2023
ab9e1dd
Make `MockDB` implement `acme.DB` interface again
hslatman Jan 8, 2024
1b32957
fix: verify custom display_name extension is present
beltram May 23, 2023
9d5c974
fix: PR review
beltram May 26, 2023
5fdf036
fix: invalid OID for display name in CSR
beltram Jun 6, 2023
ed2bce9
fix: access token verification in DPoP challenge. Was previously veri…
beltram Jul 28, 2023
4d028f7
client jwk was there the whole time
beltram Jul 28, 2023
8fd0192
print kid for debugging
beltram Jul 28, 2023
83f7643
b64 encode the kid since apparently it wasn't
beltram Jul 28, 2023
13df461
fix: could not reuse a signing key otherwise it would create in accou…
beltram Sep 12, 2023
ff07fdc
fix: oups
beltram Sep 12, 2023
2be7738
fix: same issue as with oidc challenge
beltram Sep 12, 2023
6ffd913
feat: remove custom hardcoded OIDC challenge for Google
beltram Nov 20, 2023
d6ceebb
feat: update the protocol by including team & handle in the client dp…
beltram Nov 22, 2023
39bf889
feat: remove query parameters from OIDC issuerUrl so that it allows u…
beltram Dec 15, 2023
90b5347
feat: try using the new ClientId & Handle format (i.e. plain URIs)
beltram Jan 2, 2024
84e9682
feat: change the separator between user-id & device-id in a client-id…
beltram Jan 5, 2024
c1a7acc
Make it compile with Go 1.20 again
hslatman Jan 8, 2024
fdea5e7
Fix tests for new ACME orders with Wire IDs
hslatman Jan 8, 2024
85309bb
Fix the integration test
hslatman Jan 8, 2024
01169b2
Make the `Target` optional in `Challenge` object
hslatman Jan 9, 2024
40668ae
Refactor `WireID` target processing a bit
hslatman Jan 9, 2024
eb9893b
Refactor logic for processing `WireID` identifiers in Order
hslatman Jan 9, 2024
f5a2f43
Fix missing `DPoP` and `OIDC` tokens for Wire integration test
hslatman Jan 9, 2024
776a839
Fix linter issues and improve error handling
hslatman Jan 9, 2024
7a464cd
Use `require` to check for errors in Wire integration test
hslatman Jan 9, 2024
29fa662
Remove the Wire CLI invocatation
hslatman Jan 10, 2024
e2a2e00
Make template use `DeviceId` for now
hslatman Jan 10, 2024
bf5f120
fix: keyauth was not bound to the id token
beltram Jan 9, 2024
8faf26c
Change `KeyAuth` back to old behavior (for now)
hslatman Jan 10, 2024
6a98fea
Fix linter issues
hslatman Jan 10, 2024
033aef9
Merge branch 'wire-acme-extensions' into herman/remove-rusty-cli
hslatman Jan 10, 2024
bf8c17e
Remove the Wire `oidc` and `dpop` from attestation formats
hslatman Jan 10, 2024
8997ce1
Disable `wire-dpop-01` and `wire-oidc-01` by default
hslatman Jan 10, 2024
ffd887f
Fix tests for ACME Wire provisioner
hslatman Jan 10, 2024
a423151
Merge branch 'wire-acme-extensions' into herman/remove-rusty-cli
hslatman Jan 10, 2024
c7892e9
Remove the `rusty-jwt-cli` configuration
hslatman Jan 10, 2024
de25740
Change name of test for Wire Order
hslatman Jan 10, 2024
70a2f43
Address review remarks
hslatman Jan 11, 2024
ca88557
Fix and add more tests to Wire order identifier validation
hslatman Jan 11, 2024
897688a
Merge branch 'wire-acme-extensions' into herman/remove-rusty-cli
hslatman Jan 11, 2024
cd9480a
Fix test for `parseAndVerifyWireAccessToken`
hslatman Jan 11, 2024
acad227
Put Wire options in lower level `wire` struct
hslatman Jan 11, 2024
b964c97
Add validation of `handle` and `token` to Wire verification
hslatman Jan 11, 2024
b6fc000
Add verification of maximum expiry time for Wire tokens
hslatman Jan 11, 2024
6ef64b6
Refactor the `Wire` option configuration
hslatman Jan 11, 2024
1f5f756
Make Wire options more robust
hslatman Jan 11, 2024
1bf807a
Use base64 encoded signing key format
hslatman Jan 11, 2024
348363a
Add Wire `DPoP` proof claims verification
hslatman Jan 11, 2024
44721a7
Remove debug err print
hslatman Jan 11, 2024
7eacb68
Merge branch 'herman/remove-rusty-cli' into herman/wire-configuration…
hslatman Jan 11, 2024
79739e5
Change signature algorithm property name
hslatman Jan 12, 2024
2479572
Perform initialization of DPoP and OIDC options once
hslatman Jan 12, 2024
c8160ca
Fix test; reworded error message
hslatman Jan 12, 2024
3f37fea
Merge pull request #1671 from smallstep/herman/wire-configuration-ref…
hslatman Jan 12, 2024
9bb1b24
Change `kid` and `dpop` validation
hslatman Jan 12, 2024
2c27e86
Fix linting issue
hslatman Jan 12, 2024
0ad381b
Add OIDC token template transformation
hslatman Jan 12, 2024
d5b0d92
Fix Wire ID token test comment
hslatman Jan 12, 2024
29202ef
Add support for functions in OIDC token transformation template
hslatman Jan 15, 2024
768a089
Store transformed OIDC token
hslatman Jan 15, 2024
7d5a791
Add tests for Wire `OIDC` and `DPoP` token persistence
hslatman Jan 15, 2024
2efd1f6
Fix expected error type check
hslatman Jan 15, 2024
bca179d
Make the Wire API integration test a bit more like the real flow
hslatman Jan 15, 2024
c46434f
Make the example Wire handle consistent
hslatman Jan 15, 2024
a2304c8
Add tests for Wire ID parsing
hslatman Jan 15, 2024
d84abac
Add test for `wireOIDC01Validate`
hslatman Jan 15, 2024
8f129a6
Add test for `wireDPOP01Validate`
hslatman Jan 15, 2024
a24b2a5
Add test case for `validateWireOIDCClaims`
hslatman Jan 16, 2024
7520736
Improve test coverage for `wireDPOP01Validate`
hslatman Jan 16, 2024
37106a4
Fix Wire integration test by acting on realistic access/dpop token
hslatman Jan 16, 2024
99934ec
Improve test coverage for `wireOIDC01Validate`
hslatman Jan 16, 2024
7680da7
Add realistic OIDC payload to Wire integration test
hslatman Jan 16, 2024
33be552
Merge branch 'master' into wire-acme-extensions
hslatman Jan 16, 2024
31bba6f
Merge branch 'wire-acme-extensions' into herman/remove-rusty-cli
hslatman Jan 16, 2024
17578b5
Merge pull request #1673 from smallstep/herman/wire-template-transform
hslatman Jan 16, 2024
0f0f060
Improve access and dpop token validation
hslatman Jan 16, 2024
0a7fe6e
Comment DPoP token checks that fail e2e test (currently)
hslatman Jan 16, 2024
b925474
Fix validations for DPoP client ID, nonce and issuer
hslatman Jan 17, 2024
f221232
Fix ACME `Validate` test for Wire DPoP challenge
hslatman Jan 17, 2024
f150a4f
Remove `sync.Once` for Wire configuration validation
hslatman Jan 17, 2024
36e14de
Improve Wire persistence errors
hslatman Jan 17, 2024
2f3819a
Use key authorization from ID token and `handle` -> `preferred_username`
hslatman Jan 17, 2024
19dbd02
Add audience validation to access, dpop and id token
hslatman Jan 17, 2024
51d1270
Merge pull request #1681 from smallstep/herman/fix-wire-extensions
hslatman Jan 17, 2024
7e6356e
Merge pull request #1670 from smallstep/herman/remove-rusty-cli
hslatman Jan 17, 2024
6ee0d70
Add check for empty deviceID in target URI template evaluation
hslatman Jan 18, 2024
a3de984
fix: use 2 separate identifiers for Wire
beltram Jan 19, 2024
b8eb559
Update acme/order.go
beltram Jan 23, 2024
9eed61a
use switch statement
beltram Jan 23, 2024
4d4719a
Change URLs used in DPoP template test
hslatman Jan 24, 2024
93ba165
Fix tests to work with Wire `UserID` and `DeviceID`
hslatman Jan 24, 2024
a38132a
Fix policy check for Wire user and device identifiers
hslatman Jan 24, 2024
502334f
Merge pull request #1689 from smallstep/beltram/wire-acme-extensions
hslatman Jan 24, 2024
675e418
Merge branch 'master' into wire-acme-extensions
hslatman Jan 24, 2024
a0e4cba
Merge branch 'master' into wire-acme-extensions
hslatman Jan 29, 2024
79943d2
Merge branch 'wire-acme-extensions' into herman/wire-acme-improvements
hslatman Jan 29, 2024
8a9b1b3
Move Wire option validation to provisioner initialization
hslatman Jan 29, 2024
14e8d47
Skip Wire option validation and initialization if not enabled
hslatman Jan 29, 2024
19feae5
Add test for ACME initialization with Wire challenges
hslatman Jan 31, 2024
cd21f8d
Refactor OIDC verifier instantation to happen only once
hslatman Jan 31, 2024
c579239
Add basic support for OIDC provider instantiation through discovery
hslatman Jan 31, 2024
ace27c0
Merge branch 'master' into wire-acme-extensions
hslatman Jan 31, 2024
e6d9208
Merge branch 'wire-acme-extensions' into herman/wire-acme-improvements
hslatman Jan 31, 2024
92b6191
Merge branch 'master' into wire-acme-extensions
hslatman Feb 6, 2024
37a9f36
Merge branch 'wire-acme-extensions' into herman/wire-acme-improvements
hslatman Feb 6, 2024
e153be3
Replace `smallstep/assert` with `stretchr/testify` for ACME provisioner
hslatman Feb 6, 2024
ef657d7
Fix OIDC target
hslatman Feb 6, 2024
c6a6622
Improve test coverage for Wire authorizations
hslatman Feb 6, 2024
2e78301
Simplify the DPoP target provider functionality
hslatman Feb 6, 2024
5d7e533
Add validation of `name` in DPoP token
hslatman Feb 6, 2024
138c101
Add validation for Wire UserID + DeviceID identifiers
hslatman Feb 6, 2024
745017c
Add test for OIDC auto discovery configuration
hslatman Feb 6, 2024
194341e
Address review comments
hslatman Feb 6, 2024
95fdbc1
Merge pull request #1691 from smallstep/herman/wire-acme-improvements
hslatman Feb 7, 2024
aaf5a1c
Merge branch 'master' into wire-acme-extensions
hslatman Feb 13, 2024
0a97e1b
Merge branch 'master' into wire-acme-extensions
hslatman Feb 15, 2024
0d4f53f
Merge branch 'master' into wire-acme-extensions
hslatman Feb 22, 2024
364566b
Merge branch 'master' into wire-acme-extensions
hslatman Mar 4, 2024
755ae0b
Fix Wire mock CA interface implementation
hslatman Mar 4, 2024
1583e53
Merge branch 'master' into wire-acme-extensions
hslatman Mar 5, 2024
64c5f19
Merge branch 'master' into wire-acme-extensions
hslatman Mar 6, 2024
6eb4662
Improve token validation error messages and use `net/url`
hslatman Mar 6, 2024
c6c2c4a
Fix ACME Wire Order tests
hslatman Mar 6, 2024
a136823
Merge branch 'master' into wire-acme-extensions
hslatman Mar 8, 2024
39e179b
Merge branch 'wire-acme-extensions' of github.com:smallstep/certifica…
hslatman Mar 8, 2024
2f38112
Merge branch 'master' into wire-acme-extensions
hslatman Mar 12, 2024
ae62663
Merge branch 'master' into wire-acme-extensions
hslatman Mar 12, 2024
6646af6
Merge branch 'master' into wire-acme-extensions
hslatman Mar 27, 2024
d140ffd
Merge branch 'wire-acme-extensions' of github.com:smallstep/certifica…
hslatman Mar 27, 2024
7426edb
Merge branch 'master' into wire-acme-extensions
hslatman Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions acme/api/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import (
)

var (
defaultDisableRenewal = false
globalProvisionerClaims = provisioner.Claims{
MinTLSDur: &provisioner.Duration{Duration: 5 * time.Minute},
MaxTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DisableRenewal: &defaultDisableRenewal,
defaultDisableRenewal = false
defaultDisableSmallstepExtensions = false
globalProvisionerClaims = provisioner.Claims{
MinTLSDur: &provisioner.Duration{Duration: 5 * time.Minute},
MaxTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DefaultTLSDur: &provisioner.Duration{Duration: 24 * time.Hour},
DisableRenewal: &defaultDisableRenewal,
DisableSmallstepExtensions: &defaultDisableSmallstepExtensions,
}
)

Expand Down
111 changes: 109 additions & 2 deletions acme/api/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/json"
"fmt"
"net"
"net/http"
"strings"
Expand All @@ -16,6 +17,7 @@ import (
"go.step.sm/crypto/x509util"

"github.com/smallstep/certificates/acme"
"github.com/smallstep/certificates/acme/wire"
"github.com/smallstep/certificates/api/render"
"github.com/smallstep/certificates/authority/policy"
"github.com/smallstep/certificates/authority/provisioner"
Expand Down Expand Up @@ -48,16 +50,86 @@ func (n *NewOrderRequest) Validate() error {
if id.Value == "" {
return acme.NewError(acme.ErrorMalformedType, "permanent identifier cannot be empty")
}
case acme.WireUser, acme.WireDevice:
// validation of Wire identifiers is performed in `validateWireIdentifiers`, but
// marked here as known and supported types.
continue
default:
return acme.NewError(acme.ErrorMalformedType, "identifier type unsupported: %s", id.Type)
}
}

// TODO(hs): add some validations for DNS domains?
// TODO(hs): combine the errors from this with allow/deny policy, like example error in https://datatracker.ietf.org/doc/html/rfc8555#section-6.7.1
if err := n.validateWireIdentifiers(); err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "failed validating Wire identifiers")
}

// TODO(hs): add some validations for DNS domains?
// TODO(hs): combine the errors from this with allow/deny policy, like example error in https://datatracker.ietf.org/doc/html/rfc8555#section-6.7.1

return nil
}

func (n *NewOrderRequest) validateWireIdentifiers() error {
if !n.hasWireIdentifiers() {
return nil
}

userIdentifiers := identifiersOfType(acme.WireUser, n.Identifiers)
deviceIdentifiers := identifiersOfType(acme.WireDevice, n.Identifiers)

if len(userIdentifiers) != 1 {
return fmt.Errorf("expected exactly one Wire UserID identifier; got %d", len(userIdentifiers))
}
if len(deviceIdentifiers) != 1 {
return fmt.Errorf("expected exactly one Wire DeviceID identifier, got %d", len(deviceIdentifiers))
}

wireUserID, err := wire.ParseUserID(userIdentifiers[0].Value)
if err != nil {
return fmt.Errorf("failed parsing Wire UserID: %w", err)
}

wireDeviceID, err := wire.ParseDeviceID(deviceIdentifiers[0].Value)
if err != nil {
return fmt.Errorf("failed parsing Wire DeviceID: %w", err)
}
if _, err := wire.ParseClientID(wireDeviceID.ClientID); err != nil {
return fmt.Errorf("invalid Wire client ID %q: %w", wireDeviceID.ClientID, err)
}

switch {
case wireUserID.Domain != wireDeviceID.Domain:
return fmt.Errorf("UserID domain %q does not match DeviceID domain %q", wireUserID.Domain, wireDeviceID.Domain)
case wireUserID.Name != wireDeviceID.Name:
return fmt.Errorf("UserID name %q does not match DeviceID name %q", wireUserID.Name, wireDeviceID.Name)
case wireUserID.Handle != wireDeviceID.Handle:
return fmt.Errorf("UserID handle %q does not match DeviceID handle %q", wireUserID.Handle, wireDeviceID.Handle)
}

return nil
}

// hasWireIdentifiers returns whether the [NewOrderRequest] contains
// Wire identifiers.
func (n *NewOrderRequest) hasWireIdentifiers() bool {
for _, i := range n.Identifiers {
if i.Type == acme.WireUser || i.Type == acme.WireDevice {
return true
}
}
return false
}

// identifiersOfType returns the Identifiers that are of type typ.
func identifiersOfType(typ acme.IdentifierType, ids []acme.Identifier) (result []acme.Identifier) {
for _, id := range ids {
if id.Type == typ {
result = append(result, id)
}
}
return
}

// FinalizeRequest captures the body for a Finalize order request.
type FinalizeRequest struct {
CSR string `json:"csr"`
Expand Down Expand Up @@ -262,12 +334,43 @@ func newAuthorization(ctx context.Context, az *acme.Authorization) error {
continue
}

var target string
switch az.Identifier.Type {
case acme.WireUser:
wireOptions, err := prov.GetOptions().GetWireOptions()
if err != nil {
return acme.WrapErrorISE(err, "failed getting Wire options")
}
target, err = wireOptions.GetOIDCOptions().EvaluateTarget("") // TODO(hs): determine if required by Wire
if err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "invalid Go template registered for 'target'")
}
case acme.WireDevice:
wireID, err := wire.ParseDeviceID(az.Identifier.Value)
if err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing WireDevice")
}
clientID, err := wire.ParseClientID(wireID.ClientID)
if err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "failed parsing ClientID")
}
wireOptions, err := prov.GetOptions().GetWireOptions()
if err != nil {
return acme.WrapErrorISE(err, "failed getting Wire options")
}
target, err = wireOptions.GetDPOPOptions().EvaluateTarget(clientID.DeviceID)
if err != nil {
return acme.WrapError(acme.ErrorMalformedType, err, "invalid Go template registered for 'target'")
}
}

ch := &acme.Challenge{
AccountID: az.AccountID,
Value: az.Identifier.Value,
Type: typ,
Token: az.Token,
Status: acme.StatusPending,
Target: target,
}
if err := db.CreateChallenge(ctx, ch); err != nil {
return acme.WrapErrorISE(err, "error creating challenge")
Expand Down Expand Up @@ -399,6 +502,10 @@ func challengeTypes(az *acme.Authorization) []acme.ChallengeType {
}
case acme.PermanentIdentifier:
chTypes = []acme.ChallengeType{acme.DEVICEATTEST01}
case acme.WireUser:
chTypes = []acme.ChallengeType{acme.WIREOIDC01}
case acme.WireDevice:
chTypes = []acme.ChallengeType{acme.WIREDPOP01}
default:
chTypes = []acme.ChallengeType{}
}
Expand Down
Loading
Loading