Skip to content

Commit

Permalink
Fix proof of key possession generation
Browse files Browse the repository at this point in the history
This commit updates the proof of key possession signature to prioritize
email over subject when the claim is present in the token. This matches
the current behaviour of Fulcio, which verifies the proof signature
using the token's email claim.

Signed-off-by: Aditya Sirish <[email protected]>
  • Loading branch information
adityasaky committed Aug 28, 2024
1 parent 79a4e82 commit 2fb105a
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions pkg/sign/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,23 @@ type FulcioOptions struct {
}

type jsonWebToken struct {
Sub string `json:"sub"`
Sub string `json:"sub"`
Email string `json:"email"`
Verified stringAsBool `json:"email_verified"` //nolint:tagliatelle
}

type stringAsBool bool

func (sb *stringAsBool) UnmarshalJSON(b []byte) error {
switch string(b) {
case "true", `"true"`, "True", `"True"`:
*sb = true
case "false", `"false"`, "False", `"False"`:
*sb = false
default:
return errors.New("invalid value for boolean")
}
return nil
}

type fulcioCertRequest struct {
Expand Down Expand Up @@ -128,8 +144,13 @@ func (f *Fulcio) GetCertificate(ctx context.Context, keypair Keypair, opts *Cert
return nil, err
}

subject, err := subjectFromClaims(jwt)
if err != nil {
return nil, err
}

// Sign JWT subject for proof of possession
subjectSignature, _, err := keypair.SignData([]byte(jwt.Sub))
subjectSignature, _, err := keypair.SignData([]byte(subject))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -220,3 +241,27 @@ func (f *Fulcio) GetCertificate(ctx context.Context, keypair Keypair, opts *Cert

return certBlock.Bytes, nil
}

// subjectFromClaims returns the claim to use for proof of key possession
// signature.
//
// FIXME: this is taken from sigstore/sigstore. We don't currently use the
// exported SubjectFromToken function because it requires an *oidc.IDToken
// object, which is generated after the token is verified by the client.
// In this library, the token is not verified as Fulcio also verifies the
// token's signature anyway. Also, sigstore/sigstore's implementation of
// SubjectFromToken operates on the token's bytes (tok.Claims() wraps around
// json.Unmarshal), so possibly this change belongs there.
func subjectFromClaims(c jsonWebToken) (string, error) {
if c.Email != "" {
if !c.Verified {
return "", errors.New("not verified by identity provider")
}
return c.Email, nil
}

if c.Sub == "" {
return "", errors.New("no subject found in claims")
}
return c.Sub, nil
}

0 comments on commit 2fb105a

Please sign in to comment.