Skip to content

Commit

Permalink
Okta CA: Fix keyPurposeMax add SignPayload (#46881)
Browse files Browse the repository at this point in the history
  • Loading branch information
smallinsky authored Sep 25, 2024
1 parent 82adc5f commit 0be5617
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 18 deletions.
14 changes: 7 additions & 7 deletions lib/cryptosuites/suites.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ const (
// BotSVID represents a key used for a SPIFFE SVID generated by tbot.
BotSVID

// OktaCAJWT represents the JWT key for the Okta CA.
OktaCAJWT

// TODO(nklaassen): define remaining key purposes.

// keyPurposeMax is 1 greater than the last valid key purpose, used to test that all values less than this
// are valid for each suite.
keyPurposeMax

// OktaCAJWT represents the JWT key for the Okta CA.
OktaCAJWT
)

// Algorithm represents a cryptographic signature algorithm.
Expand Down Expand Up @@ -162,6 +162,7 @@ var (
SAMLIdPCATLS: RSA2048,
SPIFFECATLS: RSA2048,
SPIFFECAJWT: RSA2048,
OktaCAJWT: ECDSAP256,
UserSSH: RSA2048,
UserTLS: RSA2048,
DatabaseClient: RSA2048,
Expand All @@ -175,7 +176,6 @@ var (
ProxyToDatabaseAgent: RSA2048,
ProxyKubeClient: RSA2048,
// TODO(nklaassen): define remaining key purposes.
OktaCAJWT: RSA2048,
}

// balancedV1 strikes a balance between security, compatibility, and
Expand All @@ -194,6 +194,7 @@ var (
SAMLIdPCATLS: RSA2048,
SPIFFECATLS: ECDSAP256,
SPIFFECAJWT: ECDSAP256,
OktaCAJWT: ECDSAP256,
UserSSH: Ed25519,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
Expand All @@ -204,7 +205,6 @@ var (
ProxyToDatabaseAgent: ECDSAP256,
ProxyKubeClient: ECDSAP256,
// TODO(nklaassen): define remaining key purposes.
OktaCAJWT: ECDSAP256,
}

// fipsv1 is an algorithm suite tailored for FIPS compliance. It is based on
Expand All @@ -223,6 +223,7 @@ var (
SAMLIdPCATLS: RSA2048,
SPIFFECATLS: ECDSAP256,
SPIFFECAJWT: ECDSAP256,
OktaCAJWT: ECDSAP256,
UserSSH: ECDSAP256,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
Expand All @@ -232,7 +233,6 @@ var (
BotSVID: ECDSAP256,
ProxyToDatabaseAgent: ECDSAP256,
ProxyKubeClient: ECDSAP256,
OktaCAJWT: ECDSAP256,
// TODO(nklaassen): define remaining key purposes.
}

Expand All @@ -254,6 +254,7 @@ var (
SAMLIdPCATLS: RSA2048,
SPIFFECATLS: ECDSAP256,
SPIFFECAJWT: ECDSAP256,
OktaCAJWT: ECDSAP256,
UserSSH: Ed25519,
UserTLS: ECDSAP256,
DatabaseClient: RSA2048,
Expand All @@ -263,7 +264,6 @@ var (
BotSVID: ECDSAP256,
ProxyToDatabaseAgent: ECDSAP256,
ProxyKubeClient: ECDSAP256,
OktaCAJWT: ECDSAP256,
// TODO(nklaassen): define remaining key purposes.
}

Expand Down
40 changes: 29 additions & 11 deletions lib/jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,20 @@ func (k *Key) sign(claims any, opts *jose.SignerOptions) (string, error) {

// signAny will return a signed JWT with the passed in claims embedded within; unlike sign it allows more flexibility in the claim data.
func (k *Key) signAny(claims any, opts *jose.SignerOptions) (string, error) {
sig, err := k.getSigner(opts)
if err != nil {
return "", trace.Wrap(err)
}
token, err := jwt.Signed(sig).Claims(claims).CompactSerialize()
if err != nil {
return "", trace.Wrap(err)
}
return token, nil
}

func (k *Key) getSigner(opts *jose.SignerOptions) (jose.Signer, error) {
if k.config.PrivateKey == nil {
return "", trace.BadParameter("can not sign token with non-signing key")
return nil, trace.BadParameter("can not sign token with non-signing key")
}

// Create a signer with configured private key and algorithm.
Expand All @@ -157,12 +169,10 @@ func (k *Key) signAny(claims any, opts *jose.SignerOptions) (string, error) {
default:
signer = cryptosigner.Opaque(k.config.PrivateKey)
}

algorithm, err := joseAlgorithm(k.config.PrivateKey.Public())
if err != nil {
return "", trace.Wrap(err)
return nil, trace.Wrap(err)
}

signingKey := jose.SigningKey{
Algorithm: algorithm,
Key: signer,
Expand All @@ -174,14 +184,9 @@ func (k *Key) signAny(claims any, opts *jose.SignerOptions) (string, error) {
opts = opts.WithType("JWT")
sig, err := jose.NewSigner(signingKey, opts)
if err != nil {
return "", trace.Wrap(err)
}

token, err := jwt.Signed(sig).Claims(claims).CompactSerialize()
if err != nil {
return "", trace.Wrap(err)
return nil, trace.Wrap(err)
}
return token, nil
return sig, nil
}

func joseAlgorithm(pub crypto.PublicKey) (jose.SignatureAlgorithm, error) {
Expand Down Expand Up @@ -610,3 +615,16 @@ func (j *JSONTime) UnmarshalJSON(b []byte) error {
*j = JSONTime(time.Unix(unix, 0))
return nil
}

// SignPayload signs the payload with the key and JSONWebSignature.
func (k *Key) SignPayload(payload []byte, opts *jose.SignerOptions) (*jose.JSONWebSignature, error) {
sig, err := k.getSigner(opts)
if err != nil {
return nil, trace.Wrap(err)
}
signature, err := sig.Sign(payload)
if err != nil {
return nil, trace.Wrap(err)
}
return signature, nil
}

0 comments on commit 0be5617

Please sign in to comment.