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 ¶
- Constants
- Variables
- func ParseDomain(domain string, scheme bool) (string, error)
- func ParseHostPort(domain string) (string, string, error)
- func ResolveEndpointToIPs(domain string, opts ...Options) ([]string, error)
- type CipherData
- type CipherStrength
- type DomainResult
- type EncryptionAlgo
- type HTTPResult
- type Hash
- type KeyExchange
- type Options
- type Signature
- type TLSConnection
- type TLSResult
- type TLSVersions
Examples ¶
Constants ¶
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 )
const LinkCSInfo = "https://ciphersuite.info/cs/%s"
Variables ¶
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, } )
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, } )
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, } )
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, } )
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.
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.
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 ¶
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 ¶
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
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 ¶
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.