func TestIssuerCache(t *testing.T) {
	tester := func(ic *issuerCache, issuer *x509.Certificate) {
		if issuer := ic.getFromCertificate(issuer.RawSubject, issuer.SubjectKeyId); issuer == nil {
			t.Fatal("Failed to retrieve issuer from cache using subject + skid")
		}
		for _, h := range []crypto.Hash{crypto.SHA1, crypto.SHA256, crypto.SHA384, crypto.SHA512} {
			issuerSubjectHash, spkiHash, err := common.HashNameAndPKI(h.New(), issuer.RawSubject, issuer.RawSubjectPublicKeyInfo)
			if err != nil {
				t.Fatalf("Failed to hash subject and subject public key info: %s", err)
			}
			if issuer := ic.getFromRequest(issuerSubjectHash, spkiHash); issuer == nil {
				t.Fatal("Failed to retrieve issuer from cache using subject hash + spki hash")
			}
		}
	}

	testIssuer, err := common.ReadCertificate("../testdata/test-issuer.der")
	if err != nil {
		t.Fatalf("Failed to read ../testdata/test-issuer.der: %s", err)
	}

	ic := newIssuerCache(nil, everyHash)
	err = ic.add(testIssuer)
	if err != nil {
		t.Fatalf("Failed to add test issuer to cache: %s", err)
	}
	tester(ic, testIssuer)

	ic = newIssuerCache([]*x509.Certificate{testIssuer}, everyHash)
	tester(ic, testIssuer)
}
func hashEntry(h hash.Hash, name, pkiBytes []byte, serial *big.Int) ([32]byte, error) {
	issuerNameHash, issuerKeyHash, err := common.HashNameAndPKI(h, name, pkiBytes)
	if err != nil {
		return [32]byte{}, err
	}
	serialHash := sha256.Sum256(serial.Bytes())
	return sha256.Sum256(append(append(issuerNameHash, issuerKeyHash...), serialHash[:]...)), nil
}
func allIssuerHashes(i *x509.Certificate, supportedHashes config.SupportedHashes) ([][32]byte, error) {
	hashes := [][32]byte{}
	for _, h := range supportedHashes {
		name, spki, err := common.HashNameAndPKI(h.New(), i.RawSubject, i.RawSubjectPublicKeyInfo)
		if err != nil {
			return nil, err
		}
		hashes = append(hashes, sha256.Sum256(append(name, spki...)))
	}
	return hashes, nil
}
func (e *Entry) init(ctx context.Context, stableBackings []scache.Cache, client *http.Client) error {
	if e.issuer == nil {
		return errors.New("entry must have non-nil issuer")
	}
	if e.request == nil {
		issuerNameHash, issuerKeyHash, err := common.HashNameAndPKI(
			crypto.SHA1.New(),
			e.issuer.RawSubject,
			e.issuer.RawSubjectPublicKeyInfo,
		)
		if err != nil {
			return err
		}
		ocspRequest := &ocsp.Request{
			HashAlgorithm:  crypto.SHA1,
			IssuerNameHash: issuerNameHash,
			IssuerKeyHash:  issuerKeyHash,
			SerialNumber:   e.serial,
		}
		e.request, err = ocspRequest.Marshal()
		if err != nil {
			return err
		}
	}
	for i := range e.responders {
		e.responders[i] = strings.TrimSuffix(e.responders[i], "/")
	}
	for _, s := range stableBackings {
		resp, respBytes := s.Read(e.name, e.serial, e.issuer)
		if resp == nil {
			continue
		}
		e.updateResponse("", 0, resp, respBytes, nil)
		return nil // return first response from a stable cache backing
	}
	err := e.refreshResponse(ctx, stableBackings, client)
	if err != nil {
		return err
	}

	return nil
}
func TestEntryCache(t *testing.T) {
	c := NewEntryCache(clock.Default(), log.NewLogger("", "", 10, clock.Default()), time.Minute, nil, nil, time.Minute, nil, everyHash)

	issuer, err := common.ReadCertificate("../testdata/test-issuer.der")
	if err != nil {
		t.Fatalf("Failed to read test issuer: %s", err)
	}
	e := &Entry{
		mu:       new(sync.RWMutex),
		name:     "test.der",
		serial:   big.NewInt(1337),
		issuer:   issuer,
		response: []byte{5, 0, 1},
	}

	err = c.add(e)
	if err != nil {
		t.Fatalf("Failed to add entry to cache: %s", err)
	}

	for _, h := range []crypto.Hash{crypto.SHA1, crypto.SHA256, crypto.SHA384, crypto.SHA512} {
		nameHash, pkHash, err := common.HashNameAndPKI(h.New(), issuer.RawSubject, issuer.RawSubjectPublicKeyInfo)
		if err != nil {
			t.Fatalf("Failed to hash subject and public key info: %s", err)
		}
		req := &ocsp.Request{h, nameHash, pkHash, e.serial}
		foundEntry, present := c.lookup(req)
		if !present {
			t.Fatal("Didn't find entry that should be in cache")
		}
		if foundEntry != e {
			t.Fatal("Cache returned wrong entry")
		}
		response, present := c.LookupResponse(req)
		if !present {
			t.Fatal("Didn't find response that should be in cache")
		}
		if bytes.Compare(response, e.response) != 0 {
			t.Fatal("Cache returned wrong response")
		}
	}

	err = c.Remove("test.der")
	if err != nil {
		t.Fatalf("Failed to remove entry from cache: %s", err)
	}

	for _, h := range []crypto.Hash{crypto.SHA1, crypto.SHA256, crypto.SHA384, crypto.SHA512} {
		nameHash, pkHash, err := common.HashNameAndPKI(h.New(), issuer.RawSubject, issuer.RawSubjectPublicKeyInfo)
		if err != nil {
			t.Fatalf("Failed to hash subject and public key info: %s", err)
		}
		_, present := c.lookup(&ocsp.Request{h, nameHash, pkHash, e.serial})
		if present {
			t.Fatal("Found entry that should've been removed from cache")
		}
		_, present = c.LookupResponse(&ocsp.Request{h, nameHash, pkHash, e.serial})
		if present {
			t.Fatal("Found response that should've been removed from cache")
		}
	}
}