Exemple #1
0
func main() {
	var configFilename string

	flag.StringVar(&configFilename, "config", "example.yaml", "YAML configuration file")
	flag.Parse()

	configBytes, err := ioutil.ReadFile(configFilename)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to read configuration file '%s': %s", configFilename, err)
		os.Exit(1)
	}
	var conf config.Configuration
	err = yaml.Unmarshal(configBytes, &conf)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to parse configuration file: %s", err)
		os.Exit(1)
	}

	clk := clock.Default()
	logger := log.NewLogger(conf.Syslog.Network, conf.Syslog.Addr, conf.Syslog.StdoutLevel, clk)

	timeout := time.Second * time.Duration(10)
	if conf.Fetcher.Timeout.Duration != 0 {
		timeout = conf.Fetcher.Timeout.Duration
	}

	client := new(http.Client)
	if len(conf.Fetcher.Proxies) != 0 {
		proxyFunc, err := common.ProxyFunc(conf.Fetcher.Proxies)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to parsed proxy URI: %s", err)
		}
		client.Transport = &http.Transport{
			Proxy: proxyFunc,
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout: 10 * time.Second,
		}
	}

	stableBackings := []scache.Cache{}
	if conf.Disk.CacheFolder != "" {
		stableBackings = append(stableBackings, scache.NewDisk(logger, clk, conf.Disk.CacheFolder))
	}

	issuers := []*x509.Certificate{}
	if conf.Definitions.IssuerFolder != "" {
		files, err := ioutil.ReadDir(conf.Definitions.IssuerFolder)
		if err != nil {
			logger.Err("Failed to read directory '%s': %s", conf.Definitions.IssuerFolder, err)
			os.Exit(1)
		}
		for _, fi := range files {
			if fi.IsDir() {
				continue
			}
			issuer, err := common.ReadCertificate(fi.Name())
			if err != nil {
				logger.Err("Failed to read issuer '%s': %s", fi.Name(), err)
				continue
			}
			issuers = append(issuers, issuer)
		}
	}

	c := mcache.NewEntryCache(clk, logger, 1*time.Minute, stableBackings, client, timeout, issuers, conf.SupportedHashes)

	logger.Info("Loading certificates")
	for _, def := range conf.Definitions.Certificates {
		var issuer *x509.Certificate
		var responders []string
		if def.Issuer != "" {
			issuer, err = common.ReadCertificate(def.Issuer)
			if err != nil {
				logger.Err("Failed to load issuer '%s': %s", def.Issuer, err)
				os.Exit(1)
			}
		}
		err = c.AddFromCertificate(def.Certificate, issuer, responders)
		if err != nil {
			logger.Err("Failed to load entry: %s", err)
			os.Exit(1)
		}
	}

	logger.Info("Initializing stapled")
	s, err := New(
		c,
		logger,
		clk,
		conf.HTTP.Addr,
		conf.Fetcher.UpstreamResponders,
		conf.Definitions.CertWatchFolder,
	)
	if err != nil {
		logger.Err("Failed to initialize stapled: %s", err)
		os.Exit(1)
	}

	logger.Info("Running stapled")
	err = s.Run()
	if err != nil {
		logger.Err("stapled failed: %s", err)
		os.Exit(1)
	}
}
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")
		}
	}
}