| package pki | 
 |  | 
 | import ( | 
 | 	"context" | 
 | 	"crypto/x509" | 
 | 	"testing" | 
 |  | 
 | 	"go.etcd.io/etcd/client/pkg/v3/testutil" | 
 | 	"go.etcd.io/etcd/tests/v3/integration" | 
 |  | 
 | 	"source.monogon.dev/metropolis/node/core/consensus/client" | 
 | ) | 
 |  | 
 | // TestRevoke exercises the CRL revocation and watching functionality of a CA | 
 | // certificate. | 
 | func TestRevoke(t *testing.T) { | 
 | 	tb, cancel := testutil.NewTestingTBProthesis("pki-revoke") | 
 | 	defer cancel() | 
 | 	cluster := integration.NewClusterV3(tb, &integration.ClusterConfig{ | 
 | 		Size: 1, | 
 | 	}) | 
 | 	cl := client.NewLocal(cluster.Client(0)) | 
 | 	defer cluster.Terminate(tb) | 
 | 	ctx, ctxC := context.WithCancel(context.Background()) | 
 | 	defer ctxC() | 
 | 	ns := Namespaced("/test-managed/") | 
 |  | 
 | 	ca := &Certificate{ | 
 | 		Namespace: &ns, | 
 | 		Issuer:    SelfSigned, | 
 | 		Name:      "ca", | 
 | 		Template:  CA("Test CA"), | 
 | 	} | 
 | 	sub := &Certificate{ | 
 | 		Namespace: &ns, | 
 | 		Issuer:    ca, | 
 | 		Name:      "sub", | 
 | 		Template:  Server([]string{"server"}, nil), | 
 | 	} | 
 |  | 
 | 	caCertBytes, err := ca.Ensure(ctx, cl) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Ensuring ca certificate failed: %v", err) | 
 | 	} | 
 | 	caCert, err := x509.ParseCertificate(caCertBytes) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Loading newly emitted CA certificate failed: %v", err) | 
 | 	} | 
 |  | 
 | 	subCertBytes, err := sub.Ensure(ctx, cl) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Ensuring sub certificate failed: %v", err) | 
 | 	} | 
 | 	subCert, err := x509.ParseCertificate(subCertBytes) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Loading newly emitted sub certificate failed: %v", err) | 
 | 	} | 
 |  | 
 | 	// Ensure CRL is correctly signed and that subCert is not yet on it. | 
 | 	crlW := ca.WatchCRL(cl) | 
 | 	crl, err := crlW.Get(ctx) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Retrieving initial CRL failed: %v", err) | 
 | 	} | 
 | 	if err := caCert.CheckCRLSignature(crl.List); err != nil { | 
 | 		t.Fatalf("Initial CRL not signed by CA: %v", err) | 
 | 	} | 
 | 	for _, el := range crl.List.TBSCertList.RevokedCertificates { | 
 | 		if el.SerialNumber.Cmp(subCert.SerialNumber) == 0 { | 
 | 			t.Fatalf("Newly emitted certificate is already on CRL.") | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Emit yet another certificate. Also shouldn't be on CRL. | 
 | 	bad := &Certificate{ | 
 | 		Namespace: &ns, | 
 | 		Issuer:    ca, | 
 | 		Name:      "bad", | 
 | 		Template:  Server([]string{"badserver"}, nil), | 
 | 	} | 
 | 	badCertBytes, err := bad.Ensure(ctx, cl) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Ensuring bad certificate failed: %v", err) | 
 | 	} | 
 | 	badCert, err := x509.ParseCertificate(badCertBytes) | 
 | 	if err != nil { | 
 | 		t.Fatalf("Loading newly emitted bad certificate failed: %v", err) | 
 | 	} | 
 | 	for _, el := range crl.List.TBSCertList.RevokedCertificates { | 
 | 		if el.SerialNumber.Cmp(badCert.SerialNumber) == 0 { | 
 | 			t.Fatalf("Newly emitted bad certificate is already on CRL.") | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Revoke bad certificate. Should now be present in CRL. | 
 | 	if err := ca.Revoke(ctx, cl, "badserver"); err != nil { | 
 | 		t.Fatalf("Revoke failed: %v", err) | 
 | 	} | 
 | 	// Get in a loop until found. | 
 | 	for { | 
 | 		crl, err = crlW.Get(ctx) | 
 | 		if err != nil { | 
 | 			t.Fatalf("Get failed: %v", err) | 
 | 		} | 
 | 		found := false | 
 | 		for _, el := range crl.List.TBSCertList.RevokedCertificates { | 
 | 			if el.SerialNumber.Cmp(badCert.SerialNumber) == 0 { | 
 | 				found = true | 
 | 			} | 
 | 			if el.SerialNumber.Cmp(subCert.SerialNumber) == 0 { | 
 | 				t.Errorf("Found non-revoked cert in CRL") | 
 | 			} | 
 | 		} | 
 | 		if found { | 
 | 			break | 
 | 		} | 
 | 	} | 
 | 	// Now revoke first certificate. Both should be now present in CRL. | 
 | 	if err := ca.Revoke(ctx, cl, "server"); err != nil { | 
 | 		t.Fatalf("Revoke failed: %v", err) | 
 | 	} | 
 | 	// Get in a loop until found. | 
 | 	for { | 
 | 		crl, err = crlW.Get(ctx) | 
 | 		if err != nil { | 
 | 			t.Fatalf("Get failed: %v", err) | 
 | 		} | 
 | 		foundSub := false | 
 | 		foundBad := false | 
 | 		for _, el := range crl.List.TBSCertList.RevokedCertificates { | 
 | 			if el.SerialNumber.Cmp(badCert.SerialNumber) == 0 { | 
 | 				foundBad = true | 
 | 			} | 
 | 			if el.SerialNumber.Cmp(subCert.SerialNumber) == 0 { | 
 | 				foundSub = true | 
 | 			} | 
 | 		} | 
 | 		if foundBad && foundSub { | 
 | 			break | 
 | 		} | 
 | 	} | 
 | } |