From 49429f0cb785c813cc4cc8df851cc46f1ffa33c4 Mon Sep 17 00:00:00 2001 From: Hayden B Date: Mon, 23 May 2022 15:40:08 -0700 Subject: [PATCH] Add e2e test that tests IssuerClaim (#605) We were lacking any test coverage for IssuerClaim. This test shows that the issuer in the issued certificate will come from the claim specified in IssuerClaim instead of from the issuer claim. Signed-off-by: Hayden Blauzvern --- pkg/api/grpc_server_test.go | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/pkg/api/grpc_server_test.go b/pkg/api/grpc_server_test.go index fd4c05125..0e713e617 100644 --- a/pkg/api/grpc_server_test.go +++ b/pkg/api/grpc_server_test.go @@ -181,6 +181,7 @@ type oidcTestContainer struct { type customClaims struct { Email string `json:"email"` EmailVerified bool `json:"email_verified"` + OtherIssuer string `json:"other_issuer"` } // Tests API for email and username subject types @@ -606,6 +607,84 @@ func TestAPIWithGitHub(t *testing.T) { } } +// Tests API with issuer claim in different field in the OIDC token +func TestAPIWithIssuerClaimConfig(t *testing.T) { + emailSigner, emailIssuer := newOIDCIssuer(t) + + // Create a FulcioConfig that supports these issuers. + cfg, err := config.Read([]byte(fmt.Sprintf(`{ + "OIDCIssuers": { + %q: { + "IssuerURL": %q, + "ClientID": "sigstore", + "Type": "email", + "IssuerClaim": "$.other_issuer" + } + } + }`, emailIssuer, emailIssuer))) + if err != nil { + t.Fatalf("config.Read() = %v", err) + } + + emailSubject := "foo@example.com" + otherIssuerVal := "other.issuer.com" + + // Create an OIDC token using this issuer's signer. + tok, err := jwt.Signed(emailSigner).Claims(jwt.Claims{ + Issuer: emailIssuer, + IssuedAt: jwt.NewNumericDate(time.Now()), + Expiry: jwt.NewNumericDate(time.Now().Add(30 * time.Minute)), + Subject: emailSubject, + Audience: jwt.Audience{"sigstore"}, + }).Claims(customClaims{Email: emailSubject, EmailVerified: true, OtherIssuer: otherIssuerVal}).CompactSerialize() + if err != nil { + t.Fatalf("CompactSerialize() = %v", err) + } + + ctClient, eca := createCA(cfg, t) + ctx := context.Background() + server, conn := setupGRPCForTest(ctx, t, cfg, ctClient, eca) + defer func() { + server.Stop() + conn.Close() + }() + + client := protobuf.NewCAClient(conn) + + pubBytes, proof := generateKeyAndProof(emailSubject, t) + + // Hit the API to have it sign our certificate. + resp, err := client.CreateSigningCertificate(ctx, &protobuf.CreateSigningCertificateRequest{ + Credentials: &protobuf.Credentials{ + Credentials: &protobuf.Credentials_OidcIdentityToken{ + OidcIdentityToken: tok, + }, + }, + Key: &protobuf.CreateSigningCertificateRequest_PublicKeyRequest{ + PublicKeyRequest: &protobuf.PublicKeyRequest{ + PublicKey: &protobuf.PublicKey{ + Content: pubBytes, + }, + ProofOfPossession: proof, + }, + }, + }) + if err != nil { + t.Fatalf("SigningCert() = %v", err) + } + + // The issuer should be otherIssuerVal, not emailIssuer + leafCert := verifyResponse(resp, eca, otherIssuerVal, t) + + // Expect email subject + if len(leafCert.EmailAddresses) != 1 { + t.Fatalf("unexpected length of leaf certificate URIs, expected 1, got %d", len(leafCert.URIs)) + } + if leafCert.EmailAddresses[0] != emailSubject { + t.Fatalf("subjects do not match: Expected %v, got %v", emailSubject, leafCert.EmailAddresses[0]) + } +} + // Tests API with challenge sent as CSR func TestAPIWithCSRChallenge(t *testing.T) { emailSigner, emailIssuer := newOIDCIssuer(t)