Skip to content

Commit

Permalink
Break up token parsing and proof of possession verification
Browse files Browse the repository at this point in the history
Signed-off-by: Nathan Smith <nathan@chainguard.dev>
  • Loading branch information
Nathan Smith committed May 12, 2022
1 parent b04529f commit 0462628
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 20 deletions.
28 changes: 21 additions & 7 deletions pkg/api/grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,15 @@ func (g *grpcCAServer) CreateSigningCertificate(ctx context.Context, request *fu
}
}

principal, err := authorize(ctx, token)
// Authenticate OIDC ID token by checking signature
idtoken, err := authorize(ctx, token)
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.Unauthenticated, err, invalidCredentials)
}
// Parse authenticated ID token into principal
// TODO:(nsmith5) replace this and authorize call above with
// just identity.IssuerPool.Authenticate()
principal, err := challenges.PrincipalFromIDToken(ctx, idtoken)
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.Unauthenticated, err, invalidCredentials)
}
Expand Down Expand Up @@ -103,10 +111,16 @@ func (g *grpcCAServer) CreateSigningCertificate(ctx context.Context, request *fu
return nil, handleFulcioGRPCError(ctx, codes.InvalidArgument, err, insecurePublicKey)
}

// verify challenge
subject, err := challenges.ExtractSubject(ctx, principal, publicKey, csr, proofOfPossession)
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.InvalidArgument, err, invalidSignature)
// verify the challenge
if csr != nil {
err = csr.CheckSignature()
if err != nil {
return nil, handleFulcioGRPCError(ctx, codes.InvalidArgument, err, invalidSignature)
}
} else {
if err := challenges.CheckSignature(publicKey, proofOfPossession, principal.Name(ctx)); err != nil {
return nil, handleFulcioGRPCError(ctx, codes.InvalidArgument, err, invalidSignature)
}
}

var csc *certauth.CodeSigningCertificate
Expand All @@ -115,7 +129,7 @@ func (g *grpcCAServer) CreateSigningCertificate(ctx context.Context, request *fu
// For CAs that do not support embedded SCTs or if the CT log is not configured
if sctCa, ok := g.ca.(certauth.EmbeddedSCTCA); !ok || g.ct == nil {
// currently configured CA doesn't support pre-certificate flow required to embed SCT in final certificate
csc, err = g.ca.CreateCertificate(ctx, subject, publicKey)
csc, err = g.ca.CreateCertificate(ctx, principal, publicKey)
if err != nil {
// if the error was due to invalid input in the request, return HTTP 400
if _, ok := err.(certauth.ValidationError); ok {
Expand Down Expand Up @@ -165,7 +179,7 @@ func (g *grpcCAServer) CreateSigningCertificate(ctx context.Context, request *fu
result.GetSignedCertificateDetachedSct().SignedCertificateTimestamp = sctBytes
}
} else {
precert, err := sctCa.CreatePrecertificate(ctx, subject, publicKey)
precert, err := sctCa.CreatePrecertificate(ctx, principal, publicKey)
if err != nil {
// if the error was due to invalid input in the request, return HTTP 400
if _, ok := err.(certauth.ValidationError); ok {
Expand Down
14 changes: 1 addition & 13 deletions pkg/challenges/challenges.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ func validateAllowedDomain(subjectHostname, issuerHostname string) error {
return fmt.Errorf("hostname top-level and second-level domains do not match: %s, %s", subjectHostname, issuerHostname)
}

func ExtractSubject(ctx context.Context, tok *oidc.IDToken, publicKey crypto.PublicKey, csr *x509.CertificateRequest, challenge []byte) (identity.Principal, error) {
func PrincipalFromIDToken(ctx context.Context, tok *oidc.IDToken) (identity.Principal, error) {
iss, ok := config.FromContext(ctx).GetIssuer(tok.Issuer)
if !ok {
return nil, fmt.Errorf("configuration can not be loaded for issuer %v", tok.Issuer)
Expand All @@ -520,18 +520,6 @@ func ExtractSubject(ctx context.Context, tok *oidc.IDToken, publicKey crypto.Pub
return nil, err
}

// verify the proof of possession of the private key
if csr != nil {
err = csr.CheckSignature()
if err != nil {
return nil, err
}
} else {
if err := CheckSignature(publicKey, challenge, principal.Name(ctx)); err != nil {
return nil, err
}
}

return principal, nil
}

Expand Down

0 comments on commit 0462628

Please sign in to comment.