httptls

package
v0.0.0-...-c4c212f Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2025 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Overview

Package httptls is a library which contains functionality for testing HTTP versions, TLS versions, and TLS ciphersuites.

The library is used by the `http` and `tls` subcommands of the `devsec-tools` CLI.

This package leverages concurrency to test multiple versions of HTTP and TLS simultaneously. The library also provides a `ParseDomain` function to parse a domain from a URL-like string.

Index

Examples

Constants

View Source
const (

	// VersionTLS10 represents the TLS 1.0 protocol version.
	VersionTLS10 = 0x0301

	// VersionTLS11 represents the TLS 1.1 protocol version.
	VersionTLS11 = 0x0302

	// VersionTLS12 represents the TLS 1.2 protocol version.
	VersionTLS12 = 0x0303

	// VersionTLS13 represents the TLS 1.3 protocol version.
	VersionTLS13 = 0x0304
)
View Source
const LinkCSInfo = "https://ciphersuite.info/cs/%s"

Variables

View Source
var (
	// EncryptionAlgoList is a map of encryption algorithms to their human-readable names.
	EncryptionAlgoList = map[EncryptionAlgo]string{
		Encrypt28147CNT:       "28147-CNT",
		Encrypt3DESEDECBC:     "3DES-EDE-CBC",
		EncryptAES128CBC:      "AES-128-CBC",
		EncryptAES128CCM:      "AES-128-CCM",
		EncryptAES128CCM8:     "AES-128-CCM-8",
		EncryptAES128GCM:      "AES-128-GCM",
		EncryptAES256CBC:      "AES-256-CBC",
		EncryptAES256CCM:      "AES-256-CCM",
		EncryptAES256CCM8:     "AES-256-CCM-8",
		EncryptAES256GCM:      "AES-256-GCM",
		EncryptARIA128CBC:     "ARIA-128-CBC",
		EncryptARIA128GCM:     "ARIA-128-GCM",
		EncryptARIA256CBC:     "ARIA-256-CBC",
		EncryptARIA256GCM:     "ARIA-256-GCM",
		EncryptCamellia128CBC: "Camellia-128-CBC",
		EncryptCamellia128GCM: "Camellia-128-GCM",
		EncryptCamellia256CBC: "Camellia-256-CBC",
		EncryptCamellia256GCM: "Camellia-256-GCM",
		EncryptChaChaPoly:     "CHACHA20-POLY1305",
		EncryptDES40CBC:       "DES-40-CBC",
		EncryptDESCBC:         "DES-CBC",
		EncryptDESCBC40:       "DES-CBC-40",
		EncryptIDEACBC:        "IDEA-CBC",
		EncryptKuznyechikCTR:  "Kuznyechik-CTR",
		EncryptKuznyechikMGML: "Kuznyechik-MGM-L",
		EncryptKuznyechikMGMS: "Kuznyechik-MGM-S",
		EncryptMagmaCTR:       "Magma-CTR",
		EncryptMagmaMGML:      "Magma-MGM-L",
		EncryptMagmaMGMS:      "Magma-MGM-S",
		EncryptNULL:           "NULL",
		EncryptRC2CBC40:       "RC2-CBC-40",
		EncryptRC2CBC56:       "RC2-CBC-56",
		EncryptRC4128:         "RC4-128",
		EncryptRC440:          "RC4-40",
		EncryptRC456:          "RC4-56",
		EncryptSEEDCBC:        "SEED-CBC",
		EncryptSM4CCM:         "SM4-CCM",
		EncryptSM4GCM:         "SM4-GCM",
	}

	// AEADList is a map of Authenticated Encryption with Associated Data (AEAD)
	// encryption modes of operation. AEAD offers a much higher degree of security
	// than traditional encryption algorithms. They consist of GCM, CCM, and
	// Poly1305 modes.
	AEADList = map[EncryptionAlgo]bool{
		EncryptAES128CCM:      true,
		EncryptAES128CCM8:     true,
		EncryptAES128GCM:      true,
		EncryptAES256CCM:      true,
		EncryptAES256CCM8:     true,
		EncryptAES256GCM:      true,
		EncryptARIA128GCM:     true,
		EncryptARIA256GCM:     true,
		EncryptCamellia128GCM: true,
		EncryptCamellia256GCM: true,
		EncryptChaChaPoly:     true,
		EncryptSM4CCM:         true,
		EncryptSM4GCM:         true,
	}

	// NIST_SP_800_52EncList is oddly-named, but more understandable in this
	// format. As opposed to AEAD or PFS, the NIST SP 800-52 list requires
	// cipher suites which are a combination of cipher suites sections (key
	// exchange + auth sig + encryption + hash).
	//
	// See §3.3.1.1.1 Cipher Suites for ECDSA Certificates
	// See §3.3.1.1.2 Cipher Suites for RSA Certificates
	NIST_SP_800_52EncList = map[EncryptionAlgo]bool{
		EncryptAES128CBC:  true,
		EncryptAES128CCM:  true,
		EncryptAES128CCM8: true,
		EncryptAES128GCM:  true,
		EncryptAES256CBC:  true,
		EncryptAES256CCM:  true,
		EncryptAES256CCM8: true,
		EncryptAES256GCM:  true,
	}
)
View Source
var (
	// HashList is a map of hashing functions to their human-readable names.
	HashList = map[Hash]string{
		HashNone:   "None",
		HashMD5:    "MD5",
		HashSHA1:   "SHA-1",
		HashSHA224: "SHA-2, 224 bits",
		HashSHA256: "SHA-2, 256 bits",
		HashSHA384: "SHA-2, 384 bits",
		HashSHA512: "SHA-2, 512 bits",
		HashGOSTR:  "GOST R 34.10-2012 (Imitovstavka)",
		HashNULL:   "NULL",
		HashSM3:    "ShangMi-3 (SM3)",
	}

	// NIST_SP_800_52HashList is oddly-named, but more understandable in this
	// format. As opposed to AEAD or PFS, the NIST SP 800-52 list requires
	// cipher suites which are a combination of cipher suites sections (key
	// exchange + auth sig + encryption + hash).
	//
	// See §3.3.1.1.1 Cipher Suites for ECDSA Certificates
	// See §3.3.1.1.2 Cipher Suites for RSA Certificates
	NIST_SP_800_52HashList = map[Hash]bool{
		HashSHA256: true,
		HashSHA384: true,
	}
)
View Source
var (
	// KeyExchangeList is a map of key exchange algorithms to their human-readable names.
	KeyExchangeList = map[KeyExchange]string{
		KexNone:        "None",
		KexDH:          "Diffie-Hellman (Non-Ephemeral) (ECDH)",
		KexDHE:         "Diffie-Hellman (Ephemeral) (ECDHE)",
		KexECCPWD:      "ECCPWD",
		KexECDH:        "Elliptic Curve Diffie-Hellman (Non-Ephemeral) (ECDH)",
		KexECDHE:       "Elliptic Curve Diffie-Hellman (Ephemeral) (ECDHE)",
		KexGOSTR341094: "GOST R 34.10-1994",
		KexGOSTR341001: "GOST R 34.10-2001",
		KexKRB5:        "Kerberos (KRB5)",
		KexNULL:        "NULL",
		KexPSK:         "Pre-Shared Keys (PSK)",
		KexRSA:         "RSA",
		KexSRP:         "Secure Remote Password (SRP)",
		KexSM2:         "ShangMi-2 (SM2)",
	}

	// PFSList is a map of key exchange algorithms which fall under the definition
	// of Perfect Forward Secrecy (PFS). Perfect Forward Secrecy (PFS) is a property
	// of secure communication protocols in which compromise of long-term keys does
	// not compromise past session keys.
	PFSList = map[KeyExchange]bool{
		KexDHE:   true,
		KexECDHE: true,
	}

	// NIST_SP_800_52KexList is oddly-named, but more understandable in this
	// format. As opposed to AEAD or PFS, the NIST SP 800-52 list requires
	// cipher suites which are a combination of cipher suites sections (key
	// exchange + auth sig + encryption + hash).
	//
	// See §3.3.1.1.1 Cipher Suites for ECDSA Certificates
	// See §3.3.1.1.2 Cipher Suites for RSA Certificates
	NIST_SP_800_52KexList = map[KeyExchange]bool{
		KexDHE:   true,
		KexECDHE: true,
	}
)
View Source
var (
	// AuthenticationList is a map of signature algorithms to their human-readable names.
	AuthenticationList = map[Signature]string{
		SigAnonymous:   "Anonymous",
		SigDSA:         "NIST Digital Signature (DSA)",
		SigECCPWD:      "ECCPWD",
		SigECDSA:       "Elliptic Curve Digital Signature (ECDSA)",
		SigED25519:     "Edwards-curve Digital Signature (ED25519)",
		SigED448:       "Edwards-curve Digital Signature (ED448)",
		SigGOST256:     "Russian GOST 256-bit",
		SigGOST512:     "Russian GOST 512-bit",
		SigGOSTR341001: "GOST R 34.10-2001 (GOSTR341001)",
		SigGOSTR341094: "GOST R 34.10-1994 (GOSTR341094)",
		SigKRB5:        "Kerberos",
		SigNULL:        "NULL",
		SigPSK:         "Pre-Shared Keys (PSK)",
		SigRSA:         "RSA",
		SigSHA1:        "Secure Hash Algorithm 1 (SHA-1)",
		SigSHA1DSS:     "Secure Hash Algorithm 1 (SHA-1) with NIST DSS (SHA-1 DSS)",
		SigSHA1RSA:     "Secure Hash Algorithm 1 (SHA-1) with RSA (SHA-1 RSA)",
		SigSHA256:      "Secure Hash Algorithm 256 (SHA-256)",
		SigSHA384:      "Secure Hash Algorithm 384 (SHA-384)",
		SigSM2:         "ShangMi-2 (SM2)",
	}

	// NIST_SP_800_52AuthList is oddly-named, but more understandable in this
	// format. As opposed to AEAD or PFS, the NIST SP 800-52 list requires
	// cipher suites which are a combination of cipher suites sections (key
	// exchange + auth sig + encryption + hash).
	//
	// See §3.3.1.1.1 Cipher Suites for ECDSA Certificates
	// See §3.3.1.1.2 Cipher Suites for RSA Certificates
	NIST_SP_800_52AuthList = map[Signature]bool{
		SigECDSA: true,
		SigRSA:   true,
	}

	// FIPS-186 defines an allowed set of signature authentication algorithms.
	FIPS186List = map[Signature]bool{
		SigECDSA: true,
		SigRSA:   true,
	}
)
View Source
var CipherList = map[uint16]CipherData{}/* 342 elements not displayed */

CipherList is a map of all IANA-identified cipher suites to their respective data. The blocks that are commented-out are the ones that are not supported by our underlying library.

https://www.iana.org/assignments/tls-parameters/tls-parameters.xml is the official source for this information.

View Source
var StrengthList = map[CipherStrength]string{
	StrengthInsecure:    "Insecure",
	StrengthWeak:        "Weak",
	StrengthSecure:      "Secure",
	StrengthRecommended: "Recommended",
}

StrengthList is a map of cipher strengths to their human-readable names.

View Source
var TLSVersion = map[uint16]string{
	0x0002: "SSLv2",
	0x0300: "SSLv3",
	0x0301: "TLSv1.0",
	0x0302: "TLSv1.1",
	0x0303: "TLSv1.2",
	0x0304: "TLSv1.3",
}

TLSVersion is a map of TLS versions to their human-readable names.

Functions

func ParseDomain

func ParseDomain(domain string, scheme bool) (string, error)

ParseDomain parses a URL-like string and returns the domain/hostname with an `https:` scheme.

Example
domain, _ := ParseDomain("example.com", true)
fmt.Println(domain)
Output:

https://example.com
Example (NoScheme)
domain, _ := ParseDomain("https://example.com", false)
fmt.Println(domain)
Output:

example.com
Example (Path)
domain, _ := ParseDomain("example.com/abc/123", true)
fmt.Println(domain)
Output:

https://example.com
Example (Port)
domain, _ := ParseDomain("http://example.com:8080", true)
fmt.Println(domain)
Output:

http://example.com:8080
Example (Scheme)
domain, _ := ParseDomain("http://example.com", true)
fmt.Println(domain)
Output:

http://example.com

func ParseHostPort

func ParseHostPort(domain string) (string, string, error)

ParseHostPort parses a domain string and returns the hostname and port. An `https:` scheme will return port 443, and an `http:` scheme will return port 80.

If a custom port is specified in the domain string, it will be returned as the port.

Example (Defacto)
domain, port, _ := ParseHostPort("example.com")
fmt.Println(domain, port)
Output:

example.com 443
Example (Http)
domain, port, _ := ParseHostPort("http://example.com")
fmt.Println(domain, port)
Output:

example.com 80
Example (Port)
domain, port, _ := ParseHostPort("example.com:22")
fmt.Println(domain, port)
Output:

example.com 22

func ResolveEndpointToIPs

func ResolveEndpointToIPs(domain string, opts ...Options) ([]string, error)

ResolveEndpointToIPs resolves a domain to the IPv4 and IPv6 addresses which are used to serve it.

Accepts an optional Options struct to configure the logger and other connectivity settings.

Types

type CipherData

type CipherData struct {
	// IANAName represents the official name of the cipher suite.
	IANAName string `json:"ianaName,omitempty"`

	// OpenSSLName represents the name of the cipher suite used by the
	// OpenSSL library.
	OpenSSLName string `json:"opensslName,omitempty"`

	// GNUTLSName represents the name of the cipher suite used by the
	// GNU-TLS library.
	GNUTLSName string `json:"gnutlsName,omitempty"`

	// URL is a link to the Cipher Suite's information page.
	URL string `json:"url,omitempty"`

	// Strength is a string representation of the strength of the cipher
	// suite.
	Strength string `json:"strength"`

	// KeyExchange is a string representation of the key exchange algorithm.
	KeyExchange string `json:"keyExchange"`

	// Authentication is a string representation of the key authentication
	// algorithm.
	Authentication string `json:"authentication"`

	// EncryptionAlgoisastring representation of the encryption
	// algorithm.
	EncryptionAlgo string `json:"encryption"`

	// Hash is a string representation of the hashing function.
	Hash string `json:"hash"`

	// IsPFS is a boolean indicating whether the cipher suite provides Perfect
	// Forward Secrecy.
	IsPFS bool `json:"isPFS"`

	// IsAEAD is a boolean indicating whether the cipher suite provides AEAD.
	IsAEAD bool `json:"isAEAD"`

	// IsNIST_SP_800_52 is a boolean indicating whether the cipher suite is
	// permitted by NIST SP 800-52.
	//
	// https://doi.org/10.6028/NIST.SP.800-52r2
	IsNIST_SP_800_52 bool `json:"isNISTSP80052"`

	// IsFIPS186 is a boolean indicating whether the cipher suite is permitted
	// by NIST FIPS 186 Digital Signature Standard.
	//
	// https://doi.org/10.6028/NIST.FIPS.186-5
	// https://doi.org/10.6028/NIST.SP.800-186
	IsFIPS186 bool `json:"isFIPS186"`
	// contains filtered or unexported fields
}

CipherData represents the data associated with a cipher suite.

func (*CipherData) Populate

func (c *CipherData) Populate()

Populate populates the CipherData struct with human-readable values, based on integer values that are collected during scanning.

type CipherStrength

type CipherStrength int
const (
	// Cipher strength groupings
	StrengthInsecure CipherStrength = iota
	StrengthWeak
	StrengthSecure
	StrengthRecommended
)

type DomainResult

type DomainResult struct {
	// Hostname represents the hostname of the connection.
	Hostname string `json:"hostname"`
}

DomainResult represents the results of stripping down a domain.

type EncryptionAlgo

type EncryptionAlgo int
const (
	// Encryption algorithms
	Encrypt28147CNT EncryptionAlgo = iota
	Encrypt3DESEDECBC
	EncryptAES128CBC
	EncryptAES128CCM
	EncryptAES128CCM8
	EncryptAES128GCM
	EncryptAES256CBC
	EncryptAES256CCM
	EncryptAES256CCM8
	EncryptAES256GCM
	EncryptARIA128CBC
	EncryptARIA128GCM
	EncryptARIA256CBC
	EncryptARIA256GCM
	EncryptCamellia128CBC
	EncryptCamellia128GCM
	EncryptCamellia256CBC
	EncryptCamellia256GCM
	EncryptChaChaPoly
	EncryptDES40CBC
	EncryptDESCBC
	EncryptDESCBC40
	EncryptIDEACBC
	EncryptKuznyechikCTR
	EncryptKuznyechikMGML
	EncryptKuznyechikMGMS
	EncryptMagmaCTR
	EncryptMagmaMGML
	EncryptMagmaMGMS
	EncryptNULL
	EncryptRC2CBC40
	EncryptRC2CBC56
	EncryptRC4128
	EncryptRC440
	EncryptRC456
	EncryptSEEDCBC
	EncryptSM4CCM
	EncryptSM4GCM
)

type HTTPResult

type HTTPResult struct {
	// Hostname represents the hostname of the connection.
	Hostname string `json:"hostname"`

	// HTTP11 represents whether or not the connection supports HTTP/1.1.
	HTTP11 bool `json:"http11"`

	// HTTP2 represents whether or not the connection supports HTTP/2.
	HTTP2 bool `json:"http2"`

	// HTTP3 represents whether or not the connection supports HTTP/3.
	HTTP3 bool `json:"http3"`
}

HTTPResult represents the results of an HTTP check.

func GetSupportedHTTPVersions

func GetSupportedHTTPVersions(domain string, opts ...Options) (HTTPResult, error)

GetSupportedHTTPVersions checks a domain for supported HTTP versions. HTTP 1.1, 2, and 3 are checked.

Goroutines are used to check each version concurrently. The results are then collected and returned.

type Hash

type Hash int
const (
	// Hashing functions
	HashNone      Hash = 0x0000
	HashMD5       Hash = 0x0001
	HashSHA1      Hash = 0x0002
	HashSHA224    Hash = 0x0003
	HashSHA256    Hash = 0x0004
	HashSHA384    Hash = 0x0005
	HashSHA512    Hash = 0x0006
	HashReserved  Hash = 0x0007
	HashIntrinsic Hash = 0x0008

	// The following are not assigned real values from the IANA.
	HashGOSTR Hash = 0x0100
	HashNULL  Hash = 0x0101
	HashSM3   Hash = 0x0102
)

type KeyExchange

type KeyExchange int
const (
	// Key exchange algorithms
	KexNone KeyExchange = iota
	KexDH
	KexDHE
	KexECCPWD
	KexECDH
	KexECDHE
	KexGOSTR341094
	KexGOSTR341001
	KexKRB5
	KexNULL
	KexPSK
	KexRSA
	KexSRP
	KexSM2
)

type Options

type Options struct {
	// Logger is an instance of the charmbracelet/log logger.
	Logger *log.Logger

	// TimeoutSeconds is the number of seconds to wait before timing out.
	TimeoutSeconds int

	// ValkeyClient is an instance of the Valkey client.
	ValkeyClient *valkey.Client
}

Options is used to pass options to the HTTP and TLS functions.

type Signature

type Signature int
const (
	// Signature algorithms
	SigAnonymous Signature = 0x0000
	SigRSA       Signature = 0x0001
	SigDSA       Signature = 0x0002
	SigECDSA     Signature = 0x0003
	// 0x0004-0x0006   Reserved
	SigED25519 Signature = 0x0007
	SigED448   Signature = 0x0008
	// 0x0009-0x003F   Reserved
	SigGOST256 Signature = 0x0040
	SigGOST512 Signature = 0x0041

	// The following are not assigned real values from the IANA.
	SigNULL Signature = 0x0100

	SigECCPWD      Signature = 0x0101
	SigKRB5        Signature = 0x0102
	SigPSK         Signature = 0x0103
	SigSHA1        Signature = 0x0104
	SigSHA1DSS     Signature = 0x0105
	SigSHA1RSA     Signature = 0x0106
	SigSHA256      Signature = 0x0107
	SigSHA384      Signature = 0x0108
	SigSM2         Signature = 0x0109
	SigGOSTR341094 Signature = 0x0110
	SigGOSTR341001 Signature = 0x0111
)

type TLSConnection

type TLSConnection struct {
	// VersionID represents the version of TLS as an integer.
	VersionID int `json:"versionId,omitempty"`

	// Version represents the version of TLS.
	Version string `json:"version,omitempty"`

	// CipherSuite represents the cipher suites that the connection advertises.
	CipherSuites []CipherData `json:"cipherSuites,omitempty"`
}

TLSConnection represents a single TLS connection, and is part of the TLSResult struct.

type TLSResult

type TLSResult struct {
	// Hostname represents the hostname of the connection.
	Hostname string `json:"hostname"`

	TLSVersions TLSVersions `json:"tlsVersions"`

	// TLSConnections represents the TLS connections that the connection advertises.
	TLSConnections []TLSConnection `json:"tlsConnections,omitempty"`
}

TLSResult represents the results of a TLS check.

func GetSupportedTLSVersions

func GetSupportedTLSVersions(domain, port string, opts ...Options) (TLSResult, error)

GetSupportedTLSVersions checks a domain for supported TLS versions. TLS 1.0, TLS 1.1, TLS 1.2, and TLS 1.3 are checked.

Goroutines are used to check each version and ciphersuite concurrently. The results are then collected and returned.

type TLSVersions

type TLSVersions struct {
	TLSv13 bool `json:"tls13"`
	TLSv12 bool `json:"tls12"`
	TLSv11 bool `json:"tls11"`
	TLSv10 bool `json:"tls10"`
}

Jump to

Keyboard shortcuts

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