README

PkgGoDev Go Report Card

BadCerts

BadCerts is a Go library to deal with bad ssl cert(s) (e.g. self-signed certificates).

NOTE: For self-signed certs, a better approach to deal with them is to use x509.CertPool, which is faster than using BadCerts library. An example can be found here (Thanks to /u/loosecanonsandvich). BadCerts library is still kinda useful to deal with other types of bad certs, like expired certs or certs with wrong common names.

Example

// This is the cert fingerprint from https://self-signed.badssl.com/
myCertFingerprint := "9SLklscvzMYj8f+52lp5ze/hY0CFHyLSPQzSpYYIBm8="

client := &http.Client{
	Transport: &http.Transport{
		DialTLS: badcerts.DialTLSWithWhitelistCerts(
			badcerts.IsSelfSignedError,
			myCertFingerprint,
		),
	},
}

// Now client can handle https://self-signed.badssl.com/ just fine:

_, err := client.Get("https://self-signed.badssl.com/")
if err != nil {
	panic(err)
}
fmt.Println("Everything is awesome.")

// And it will still return error for other bad certificates.

FAQs

But I could just disable certificate verification?

Yes you can, but then you won't know if it's replaced by a different, malicious MITM cert. Or you could use the same http client with sites with legit certs and now you are losing protection.

BadCerts library still have all the normal certificate verification protections, it just trust the whitelisted certificate(s) additionally, but nothing more.

How do I get the fingerprint for my self-signed cert?

It comes with a command line tool badcerts-fingerprint.

Aren't those certs bad?

Yes they are. You should use Let's Encrypt on your site. This is more for the sites you cannot control and have to deal with.

Acknowledges

This library is inspired by tam7t/hpkp

License

BSD 3-Clause.

Expand ▾ Collapse ▴

Documentation

Overview

Package badcerts is a library to handle bad (e.g. self-signed) certificates.

It provides a function you could use in your http.Client, to handle the case that you do not want to disable https certificate validation altogether, but you want to whitelist one (or more) bad (self-signed, expired, wrong common name, etc.) cert(s) because you have to. ¯\_(ツ)_/¯

This library is inspired by https://github.com/tam7t/hpkp

Example

Code:

package main

import (
	"net/http"

	"go.yhsif.com/badcerts"
)

func main() {
	// This is the cert fingerprint from https://self-signed.badssl.com/
	//
	// You can get it by:
	//
	//     go get -u go.yhsif.com/badcerts/cmd/badcerts-fingerprint
	//     badcerts-fingerprint -url https://self-signed.badssl.com/
	myCertFingerprint := "9SLklscvzMYj8f+52lp5ze/hY0CFHyLSPQzSpYYIBm8="

	client := &http.Client{
		Transport: &http.Transport{
			DialTLS: badcerts.DialTLSWithWhitelistCerts(
				badcerts.IsSelfSignedError,
				myCertFingerprint,
			),
		},
	}

	// Now client can handle https://self-signed.badssl.com/ just fine:
	//
	// _, err := client.Get("https://self-signed.badssl.com/")
	// if err != nil {
	//	panic(err)
	// }
	// fmt.Println("Everything is awesome.")
	//
	// And it will still return error for other bad certificates.

	// Satisfy compiler
	_ = client
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DialTLSWithWhitelistCerts

func DialTLSWithWhitelistCerts(
	errorFunc ErrorFunc,
	certFingerprints ...string,
) func(network, addr string) (net.Conn, error)

DialTLSWithWhitelistCerts returns a DialTLS implementation.

First it tries standard tls.Dial. If nothing is wrong, it returns the result directly.

If the error satisfies errorFunc, it dials again without cert verification, then checks the fingerprint of the cert against the given certs. If the fingerprint matches it returns the connection without error, otherwise it returns the original error when calling standard tls.Dial.

As a result this function works with all the standard trusted root CAs plus the ones with matching cert fingerprints, and nothing else.

func Fingerprint

func Fingerprint(cert *x509.Certificate) string

Fingerprint returns the sha256 of an x509 certificate signature, encoded with standard base64.

func IsSelfSignedError

func IsSelfSignedError(err error) bool

IsSelfSignedError is an ErrorFunc returns true for self-signed certs.

Types

type ErrorFunc

type ErrorFunc func(err error) bool

ErrorFunc defines the function to determine whether an error is cert error that should retry to check against whitelisted cert fingerprints.

Implementations should return true for errors need check fingerprints.

Directories

Path Synopsis
cmd/badcerts-fingerprint Command badcerts-fingerprint provides a tool to get cert fingerprint(s) to be used in badcerts library.