https://github.com/tam7t/hpkp with changes.

Yawning Angel 30623e5213 Use `Config.Clone()` for the deep copy where available. 8 months ago
cmd 5a23fb33ef Fixup the import paths. 1 year ago
.gitignore 35d3a5b309 Initial commit 1 year ago
.travis.yml 2ab742e3e2 tests: initial fingerprint test and example usage 1 year ago
LICENSE 35d3a5b309 Initial commit 1 year ago
README.md 6098c6cdd3 report-uri: new dialer iface & header parser for pin failure reports 1 year ago
dialer.go 47939e66e9 Hopefully fix the package to again work with Go < 1.7. 1 year ago
example_test.go 5a23fb33ef Fixup the import paths. 1 year ago
fingerprint.go 47e029d8fe initial 1 year ago
fingerprint_test.go 2ab742e3e2 tests: initial fingerprint test and example usage 1 year ago
go17.go 30623e5213 Use `Config.Clone()` for the deep copy where available. 8 months ago
go18.go 30623e5213 Use `Config.Clone()` for the deep copy where available. 8 months ago
header.go f4d3fa52ec spelling: correct comments 1 year ago
header_test.go 548fffe0ae lint: fix lint errors 1 year ago
pre_go17.go 47939e66e9 Hopefully fix the package to again work with Go < 1.7. 1 year ago
report.go 548fffe0ae lint: fix lint errors 1 year ago
report_test.go 548fffe0ae lint: fix lint errors 1 year ago
storage.go 6098c6cdd3 report-uri: new dialer iface & header parser for pin failure reports 1 year ago
storage_test.go 8b0bd8d527 storage: add tests 1 year ago

README.md

hpkp

Go Report Card GoDoc Build Status

Library for performing certificate pin validation for golang applications.

Motivation

I couldn't find any Golang libraries that make key pinning any easier, so I decided to start my own library for writing HPKP aware clients. This library is aimed at providing:

  1. HPKP related tools (generate pins, inspect servers)
  2. A convenience functions for writing clients that support pin verification

Examples

To inspect the HPKP headers from the server:

$ hpkp-headers https://github.com
{"Created":1465765483,"MaxAge":5184000,"IncludeSubDomains":true,"Permanent":false,"Sha256Pins":["WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=","RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=","k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=","K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=","IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4=","iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0=","LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="]}

And generate pins from the certs a server presents:

$ hpkp-pins -server=github.com:443
pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=

Or generate a pin from a PEM-encoded certificate file:

$ hpkp-pins -file=cert.pem
AD4C8VGyUrvmReK+D/PYtH52cYJrG9o7VR+uOZIh1Q0=
pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=

And finally, how to use the hpkp package to verify pins as part of your application:

s := hpkp.NewMemStorage()

s.Add("github.com", &hpkp.Header{
    Permanent: true,
    Sha256Pins: []string{
        "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=",
        "RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=",
        "k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=",
        "K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=",
        "IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4=",
        "iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0=",
        "LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A=",
    },
})

client := &http.Client{}
dialConf := &hpkp.DialerConfig{
	Storage:   s,
	PinOnly:   true,
	TLSConfig: nil,
	Reporter: func(p *hpkp.PinFailure, reportUri string) {
		// TODO: report on PIN failure
		fmt.Println(p)
	},
}

client.Transport = &http.Transport{
	DialTLS: dialConf.NewDialer(),
}
resp, err := client.Get("https://github.com")

References