hpkp

package module
v0.0.0-...-2b70b40 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2016 License: MIT Imports: 13 Imported by: 28

README

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

Documentation

Overview

Example
package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/tam7t/hpkp"
)

func main() {
	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")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(resp.StatusCode)
}
Output:

200

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Fingerprint

func Fingerprint(c *x509.Certificate) string

Fingerprint returns the hpkp signature of an x509 certificate

Types

type DialerConfig

type DialerConfig struct {
	Storage   StorageReader
	PinOnly   bool
	TLSConfig *tls.Config
	Reporter  PinFailureReporter
}

DialerConfig describes how to verify hpkp info and report failures

func (*DialerConfig) NewDialer

func (c *DialerConfig) NewDialer() func(network, addr string) (net.Conn, error)

NewDialer returns a dialer for making TLS connections with hpkp support

type Header struct {
	Created           int64
	MaxAge            int64
	IncludeSubDomains bool
	Permanent         bool
	Sha256Pins        []string
	ReportURI         string
}

Header holds a domain's hpkp information

func ParseHeader

func ParseHeader(resp *http.Response) *Header

ParseHeader parses the hpkp information from an http.Response.

func ParseReportOnlyHeader

func ParseReportOnlyHeader(resp *http.Response) *Header

ParseReportOnlyHeader parses the hpkp information from an http.Response. The resulting header information should not be cached as max_age is ignored on HPKP-RO headers per the RFC.

func (*Header) Matches

func (h *Header) Matches(pin string) bool

Matches checks whether the provided pin is in the header list

type MemStorage

type MemStorage struct {
	// contains filtered or unexported fields
}

MemStorage is threadsafe hpkp host storage backed by an in-memory map

func NewMemStorage

func NewMemStorage() *MemStorage

NewMemStorage initializes hpkp in-memory datastructure

func (*MemStorage) Add

func (s *MemStorage) Add(host string, d *Header)

Add a domain to hpkp storage

func (*MemStorage) Lookup

func (s *MemStorage) Lookup(host string) *Header

Lookup returns the corresponding hpkp header information for a given host

type PinFailure

type PinFailure struct {
	DateTime                  string   `json:"date-time"`
	Hostname                  string   `json:"hostname"`
	Port                      int      `json:"port"`
	EffectiveExpirationDate   string   `json:"effective-expiration-date"`
	IncludeSubdomains         bool     `json:"include-subdomains"`
	NotedHostname             string   `json:"noted-hostname"`
	ServedCertificateChain    []string `json:"served-certificate-chain"`
	ValidatedCertificateChain []string `json:"validated-certificate-chain"`
	KnownPins                 []string `json:"known-pins"`
}

PinFailure hold fields required for POSTing a pin validation failure JSON message to a host's report-uri.

func NewPinFailure

func NewPinFailure(host string, port int, h *Header, c tls.ConnectionState) (*PinFailure, string)

NewPinFailure creates a struct to report information on failed hpkp connections

type PinFailureReporter

type PinFailureReporter func(p *PinFailure, reportUri string)

PinFailureReporter callback function to keep track and report on PIN failures

type Storage

type Storage interface {
	Lookup(host string) *Header
	Add(host string, d *Header)
}

Storage is threadsafe hpkp storage interface

type StorageReader

type StorageReader interface {
	Lookup(host string) *Header
}

StorageReader is threadsafe hpkp storage interface

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL