mirror of
https://github.com/outbackdingo/certificates.git
synced 2026-01-27 10:18:34 +00:00
support for oidc id token
This commit is contained in:
@@ -431,6 +431,25 @@ func wireOIDC01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSO
|
||||
if err = db.UpdateChallenge(ctx, ch); err != nil {
|
||||
return WrapErrorISE(err, "error updating challenge")
|
||||
}
|
||||
|
||||
parsedIdToken, err := jwt.ParseSigned(wireChallengePayload.IdToken)
|
||||
if err != nil {
|
||||
return WrapErrorISE(err, "Invalid OIDC id token")
|
||||
}
|
||||
oidcToken := make(map[string]interface{})
|
||||
if err := parsedIdToken.UnsafeClaimsWithoutVerification(&oidcToken); err != nil {
|
||||
return WrapErrorISE(err, "Failed parsing OIDC id token")
|
||||
}
|
||||
|
||||
orders, err := db.GetAllOrdersByAccountID(ctx, ch.AccountID)
|
||||
if err != nil {
|
||||
return WrapErrorISE(err, "Could not find current order by account id")
|
||||
}
|
||||
|
||||
if err := db.CreateOidcToken(ctx, orders[0], oidcToken); err != nil {
|
||||
return WrapErrorISE(err, "Failed storing OIDC id token")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -568,7 +587,7 @@ func wireDPOP01Validate(ctx context.Context, ch *Challenge, db DB, jwk *jose.JSO
|
||||
return WrapErrorISE(err, "Could not find current order by account id")
|
||||
}
|
||||
|
||||
if err := db.CreateDpop(ctx, orders[0], dpop); err != nil {
|
||||
if err := db.CreateDpopToken(ctx, orders[0], dpop); err != nil {
|
||||
return WrapErrorISE(err, "Failed storing DPoP token")
|
||||
}
|
||||
|
||||
|
||||
@@ -55,8 +55,10 @@ type DB interface {
|
||||
GetAllOrdersByAccountID(ctx context.Context, accountID string) ([]string, error)
|
||||
UpdateOrder(ctx context.Context, o *Order) error
|
||||
|
||||
CreateDpop(ctx context.Context, orderId string, dpop map[string]interface{}) error
|
||||
GetDpop(ctx context.Context, orderId string) (map[string]interface{}, error)
|
||||
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)
|
||||
}
|
||||
|
||||
type dbKey struct{}
|
||||
|
||||
@@ -23,7 +23,8 @@ var (
|
||||
externalAccountKeyTable = []byte("acme_external_account_keys")
|
||||
externalAccountKeyIDsByReferenceTable = []byte("acme_external_account_keyID_reference_index")
|
||||
externalAccountKeyIDsByProvisionerIDTable = []byte("acme_external_account_keyID_provisionerID_index")
|
||||
dpopTable = []byte("acme_dpop")
|
||||
dpopTokenTable = []byte("acme_dpop_token")
|
||||
oidcTokenTable = []byte("oidc_token")
|
||||
)
|
||||
|
||||
// DB is a struct that implements the AcmeDB interface.
|
||||
|
||||
@@ -10,30 +10,31 @@ import (
|
||||
"github.com/smallstep/nosql"
|
||||
)
|
||||
|
||||
type dbDpop struct {
|
||||
type dbDpopToken struct {
|
||||
ID string `json:"id"`
|
||||
Content []byte `json:"content"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// getDBDpop retrieves and unmarshals an DPoP type from the database.
|
||||
func (db *DB) getDBDpop(ctx context.Context, orderId string) (*dbDpop, error) {
|
||||
b, err := db.db.Get(dpopTable, []byte(orderId))
|
||||
// getDBDpopToken retrieves and unmarshals an DPoP type from the database.
|
||||
func (db *DB) getDBDpopToken(ctx context.Context, orderId string) (*dbDpopToken, error) {
|
||||
b, err := db.db.Get(dpopTokenTable, []byte(orderId))
|
||||
if nosql.IsErrNotFound(err) {
|
||||
return nil, acme.NewError(acme.ErrorMalformedType, "dpop %s not found", orderId)
|
||||
} else if err != nil {
|
||||
return nil, errors.Wrapf(err, "error loading dpop %s", orderId)
|
||||
}
|
||||
o := new(dbDpop)
|
||||
if err := json.Unmarshal(b, &o); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling dpop %s into dbDpop", orderId)
|
||||
|
||||
d := new(dbDpopToken)
|
||||
if err := json.Unmarshal(b, &d); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling dpop %s into dbDpopToken", orderId)
|
||||
}
|
||||
return o, nil
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// GetDpop retrieves an DPoP from the database.
|
||||
func (db *DB) GetDpop(ctx context.Context, orderId string) (map[string]interface{}, error) {
|
||||
dbDpop, err := db.getDBDpop(ctx, orderId)
|
||||
// GetDpopToken retrieves an DPoP from the database.
|
||||
func (db *DB) GetDpopToken(ctx context.Context, orderId string) (map[string]interface{}, error) {
|
||||
dbDpop, err := db.getDBDpopToken(ctx, orderId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -44,20 +45,73 @@ func (db *DB) GetDpop(ctx context.Context, orderId string) (map[string]interface
|
||||
return dpop, err
|
||||
}
|
||||
|
||||
// CreateDpop creates DPoP resources and saves them to the DB.
|
||||
func (db *DB) CreateDpop(ctx context.Context, orderId string, dpop map[string]interface{}) error {
|
||||
// CreateDpopToken creates DPoP resources and saves them to the DB.
|
||||
func (db *DB) CreateDpopToken(ctx context.Context, orderId string, dpop map[string]interface{}) error {
|
||||
content, err := json.Marshal(dpop)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := clock.Now()
|
||||
dbDpop := &dbDpop{
|
||||
dbDpop := &dbDpopToken{
|
||||
ID: orderId,
|
||||
Content: content,
|
||||
CreatedAt: now,
|
||||
}
|
||||
if err := db.save(ctx, orderId, dbDpop, nil, "dpop", dpopTable); err != nil {
|
||||
if err := db.save(ctx, orderId, dbDpop, nil, "dpop", dpopTokenTable); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type dbOidcToken struct {
|
||||
ID string `json:"id"`
|
||||
Content []byte `json:"content"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
|
||||
// getDBOidcToken retrieves and unmarshals an OIDC id token type from the database.
|
||||
func (db *DB) getDBOidcToken(ctx context.Context, orderId string) (*dbOidcToken, error) {
|
||||
b, err := db.db.Get(oidcTokenTable, []byte(orderId))
|
||||
if nosql.IsErrNotFound(err) {
|
||||
return nil, acme.NewError(acme.ErrorMalformedType, "oidc token %s not found", orderId)
|
||||
} else if err != nil {
|
||||
return nil, errors.Wrapf(err, "error loading oidc token %s", orderId)
|
||||
}
|
||||
o := new(dbOidcToken)
|
||||
if err := json.Unmarshal(b, &o); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling oidc token %s into dbOidcToken", orderId)
|
||||
}
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// GetOidcToken retrieves an oidc token from the database.
|
||||
func (db *DB) GetOidcToken(ctx context.Context, orderId string) (map[string]interface{}, error) {
|
||||
dbOidc, err := db.getDBOidcToken(ctx, orderId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idToken := make(map[string]interface{})
|
||||
err = json.Unmarshal(dbOidc.Content, &idToken)
|
||||
|
||||
return idToken, err
|
||||
}
|
||||
|
||||
// CreateOidcToken creates oidc token resources and saves them to the DB.
|
||||
func (db *DB) CreateOidcToken(ctx context.Context, orderId string, idToken map[string]interface{}) error {
|
||||
content, err := json.Marshal(idToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
now := clock.Now()
|
||||
dbOidc := &dbOidcToken{
|
||||
ID: orderId,
|
||||
Content: content,
|
||||
CreatedAt: now,
|
||||
}
|
||||
if err := db.save(ctx, orderId, dbOidc, nil, "oidc", oidcTokenTable); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -210,43 +210,11 @@ func (o *Order) Finalize(ctx context.Context, db DB, csr *x509.CertificateReques
|
||||
}
|
||||
data.SetSubject(subject)
|
||||
|
||||
dpop, err := db.GetDpop(ctx, o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Inject Wire's custom challenges into the template once they have been validated
|
||||
dpop, err := db.GetDpopToken(ctx, o.ID)
|
||||
data.Set("Dpop", dpop)
|
||||
|
||||
// inject the raw access token as template variable
|
||||
/*
|
||||
log.Printf(">> json raw content %v", ctx.Value(wire.AccessTokenKey{}))
|
||||
access, ok := ctx.Value(wire.AccessTokenKey{}).(map[string]interface{})
|
||||
if !ok {
|
||||
return WrapErrorISE(err, "Invalid or absent access in context")
|
||||
}
|
||||
if access == nil {
|
||||
return WrapErrorISE(err, "Access was nil in context")
|
||||
}*/
|
||||
|
||||
/*// inject the raw dpop token as template variable
|
||||
dpop, ok := ctx.Value("dpop").(map[string]interface{})
|
||||
if !ok {
|
||||
return WrapErrorISE(err, "Invalid or absent dpop in context")
|
||||
}
|
||||
data.Set("dpop", dpop)*/
|
||||
|
||||
// inject the raw access token as template variable
|
||||
/*access, ok := ctx.Value("access").(map[string]interface{})
|
||||
if !ok {
|
||||
return WrapErrorISE(err, "Invalid or absent access in context")
|
||||
}
|
||||
data.Set("access", access)*/
|
||||
|
||||
/*// inject the raw OIDC id token as template variable
|
||||
oidc, ok := ctx.Value("oidc").(map[string]interface{})
|
||||
if !ok {
|
||||
return WrapErrorISE(err, "Invalid or absent oidc in context")
|
||||
}
|
||||
data.Set("oidc", oidc)*/
|
||||
oidc, err := db.GetOidcToken(ctx, o.ID)
|
||||
data.Set("Oidc", oidc)
|
||||
|
||||
// Custom sign options passed to authority.Sign
|
||||
var extraOptions []provisioner.SignOption
|
||||
|
||||
Reference in New Issue
Block a user