intransport

package module
v2.1.1 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2022 License: MIT Imports: 14 Imported by: 0

README

GoDoc Go Report Card Build Status

Package intransport implements the http RoundTripper interface. This can be used with, for example, http.Client and httputil.ReverseProxy. This package is meant to allow secure communications with remote hosts that may not fully specify their intermediate certificates on the TLS handshake. Most browsers support communication with these hosts by using the issuing certificate URL from the Authority Information Access extension of the cert to fetch any missing intermediates. Each intermediate is fetched in turn until it can either complete the chain back to a trusted root or give up after all avenues have been exhausted, in which case it displays an error. Go's default transport does not fetch intermediates and will fail on mis-configured hosts. This package attempts to emulate browser behavior by attempting to complete the chain to a trusted root by fetching any missing intermediates.

Additionally, this will validate any stapled OCSP responses, and in the case where the certificate was created with the Must Staple extension set, it will fail in the absence of a validated OCSP response.

In order to use this, for most use cases, will be simply:

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	
	it "github.com/nathanejohnson/intransport/v2"
)

func main() {
	c := it.NewInTransportHTTPClient(nil)
	resp, err := c.Get("https://something.org")
	if err != nil {
		fmt.Println("boo, hiss! ", err)
		os.Exit(1)
	}
	body, err := ioutil.ReadAll(resp.Body)
	_ = resp.Body.Close()
	if err != nil {		
		fmt.Println("ba dum, tiss! ", err)
		os.Exit(1)
	}
	fmt.Printf("got response:\n%s", string(body))
}

Note: v2 package supports only go 1.15 and newer due to the use of tls VerifyConn.

Documentation

Overview

Package intransport implements the http RoundTripper interface. This can be used with, for example, http.Client and httputil.ReverseProxy. This package is meant to allow secure communications with remote hosts that may not fully specify their intermediate certificates on the tlsc handshake. Most browsers support communication with these hosts by using the issuing certificate URL from the Authority Information Access extension of the cert to fetch any missing intermediates. Each intermediate is fetched in turn until it can either complete the chain back to a trusted root or give up after all avenues have been exhausted, in which case it displays an error. Go's default transport does not fetch intermediates and will fail on mis-configured hosts. This package attempts to emulate browser behavior by attempting to complete the chain to a trusted root by fetching any missing intermediates.

Additionally, this will validate any stapled OCSP responses, and in the case where the certificate was created with the Must Staple extension set, it will fail in the absence of a validated OCSP response.

Index

Constants

View Source
const StatusRequestExtension = 5

StatusRequestExtension - status_request

Variables

View Source
var (
	// ErrNoPeerCerts - this is returned when there are no peer certs presented.
	ErrNoPeerCerts = errors.New("no peer certificates presented")

	// ErrInvalidChainLength - this is returned when the chain length is less than 2 for a "chains" entry,
	// IOW there must be at leat one peer cert in addition to the leaf.
	ErrInvalidChainLength = errors.New("invalid chain length")

	// ErrInvalidChainsLength - this is returned when the chains length is less than 1
	ErrInvalidChainsLength = errors.New("invalid chains length")

	// ErrOCSPNotStapled - this is returned when the OCSP Must Staple extension is present but a valid
	// OCSP staple was not found.
	ErrOCSPNotStapled = errors.New("certificate was marked with OCSP must-staple and no staple could be verified")

	// ErrNoCertificates - this is returned in the unlikely event that no
	// peer certificates are provided whatsoever.  This should never be
	// seen.
	ErrNoCertificates = errors.New("no certificates supplied")

	// MustStapleValue is the value in the MustStaple extension.
	// DER encoding of []int{5}.
	// https://tools.ietf.org/html/rfc6066#section-1.1
	MustStapleValue, _ = asn1.Marshal([]int{StatusRequestExtension})

	// MustStapleOID is the OID of the must staple.
	// Must staple oid is id-pe-tlsfeature  as defined here
	// https://tools.ietf.org/html/rfc7633#section-6
	MustStapleOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24}
)

Functions

func NewInTransportHTTPClient

func NewInTransportHTTPClient(tlsc *tls.Config) *http.Client

NewInTransportHTTPClient - generate an http client with sensible defaults. Optionally pass a *tls.Config that will be used as a basis for tls configuration.

Types

type Cacher added in v2.1.0

type Cacher interface {
	// LockedCachedCert will be called for a key, and this should
	// return a locked entry.
	LockedCachedCert(key string) LockedCachedCertRepresenter
}

Cacher - interface for caching x509 entries.

func NewMapCache added in v2.1.0

func NewMapCache() Cacher

NewMapCache - returns a Cacher implementation based on a go map and mutexes.

func NewNopCache added in v2.1.0

func NewNopCache() Cacher

NewNopCache - this returns a nop cache, which can be used to disable caching of certificates.

type InTransport added in v2.1.1

type InTransport struct {
	// Specify this method in the situation where you might otherwise have wanted to
	// install your own VerifyPeerCertificate hook into tls.Config.  If specified,
	// This method will be called after a successful InTransport verification,
	// and verifiedChains will contain appropriate data including any intermediates
	// that needed to be downloaded.  This is also set when a VerifyPeerCertificate
	// method is present on the passed tls.Config to one of the New methods above.
	NextVerifyPeerCertificate peerCertViewer

	// NextVerifyConnection is similar to NextVerityPeerCertificate, but for the VerifyConnection instead.
	// Similarly to above, this is automatically set if VerifyConnection is set on
	// tls.Config passed to any of the New methods above.
	NextVerifyConnection func(cs tls.ConnectionState) error

	// IntermediateHTTPClient is an http client used for fetching intermediate certs
	// that are missing.  The default created with the New* methods is probably
	// sane for almost all use cases, but exporting this just in case.  If
	// you need to set this, do it before you start using InTransport as an
	// http.Roundtripper.
	IntermediateHTTPClient *http.Client
	// contains filtered or unexported fields
}

InTransport - this implements an http.RoundTripper and handles the fetching of missing intermediate certificates, and verifying OCSP stapling, and in the event there is a "must staple" set on the certificate it will fail on missing staple.

func NewInTransport

func NewInTransport(tlsc *tls.Config) *InTransport

NewInTransport - create a new http transport suitable for client connections. InTransport implements http.RoundTripper, and can be used like so:

it := intransport.NewInTranport(nil)
c := &http.Client{
    Transport: it,
}

func NewInTransportFromTransport

func NewInTransportFromTransport(t *http.Transport, dialer *net.Dialer, tlsc *tls.Config) *InTransport

NewInTransportFromTransport - use t, dialer and tlsc as templates. Any can be nil and sane defaults will be used. If tlsc.VerifyPeerCertificate is specified, it will be called with the same semantics as before, but after we fetch intermediates and validate chains (if necessary). Similarly, if tlsc.VerifyConnection is specified, it will be called with the same semantics as before, but after we validate stapled ocsp.

func NewInTransportFromTransportWithCache added in v2.1.0

func NewInTransportFromTransportWithCache(t *http.Transport, dialer *net.Dialer, tlsc *tls.Config, cache Cacher) *InTransport

NewInTransportFromTransportWithCache - Same as NewInTransportFromTransport, with the option of specifying a cache implementation for fetched intermediates. If nil, the default cacher will use the map cache implementation.

func (*InTransport) RoundTrip added in v2.1.1

func (it *InTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip - implement http.RoundTripper interface

type LockedCachedCertRepresenter added in v2.1.0

type LockedCachedCertRepresenter interface {
	// Cert is the getter function and will be called on a locked entry.
	// A nil value is valid as a return, and signals we need to fetch the certificate.
	Cert() *x509.Certificate

	// SetCert is the certificate setter function and will be called on a locked entry.
	SetCert(cert *x509.Certificate)

	// Unlock will be called after fetching and / or setting the value.  Once Unlock is called,
	// no other calls will be made.  For subsequent access, Cacher.LockedCachedCert will be called again.
	Unlock()
}

LockedCachedCertRepresenter - awkwardly named interface for a cached and locked certificate entry.

Jump to

Keyboard shortcuts

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