247 lines
7.8 KiB
Go
247 lines
7.8 KiB
Go
package cryptparse
|
|
|
|
import (
|
|
`crypto/tls`
|
|
|
|
`github.com/go-playground/validator/v10`
|
|
)
|
|
|
|
var (
|
|
tlsVerNmToUint map[string]uint16
|
|
tlsCipherNmToUint map[string]uint16
|
|
tlsCurveNmToCurve map[string]tls.CurveID
|
|
)
|
|
|
|
const (
|
|
dfltStructTag string = "tlsUri"
|
|
)
|
|
|
|
const (
|
|
MaxTlsCipher uint16 = tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
|
MaxCurveId tls.CurveID = tls.X25519 // 29
|
|
MinTlsVer uint16 = tls.VersionSSL30
|
|
MaxTlsVer uint16 = tls.VersionTLS13
|
|
DefaultNetType string = "tcp"
|
|
)
|
|
|
|
const (
|
|
// KeyLogEnv specifies the TLS key log file.
|
|
// !! ONLY USE THIS FOR DEBUGGING !!
|
|
KeyLogEnv string = "SSLKEYLOGFILE"
|
|
/*
|
|
KeyLogEnvVal specifies the special ParamKeylog value to use the
|
|
value of the environment variable as named in KeyLogEnv.
|
|
*/
|
|
KeyLogEnvVal string = "_env_"
|
|
// KeyLogBufVal specifies the special ParamKeylog value to use an in-memory buffer.
|
|
KeyLogBufVal string = "_buf_"
|
|
)
|
|
|
|
//go:generate go run ./internal/constmap
|
|
|
|
/*
|
|
TlsUriParam* specifiy URL query parameters to parse a tls:// URI, and are used by TlsUri methods.
|
|
|
|
NOTE: If these consts' type or "Param*" prefix changes, internal/constmap/consts.go will also need to be changed.
|
|
The above go:generate creates (within this main module namespace):
|
|
tlsUriParamStrMap (a map of string(<tlsUriParam> const name) => <parameter>)
|
|
tlsUriStrParamMap (a map of <parameter> => string(<tlsUriParam> const name))
|
|
*/
|
|
const (
|
|
/*
|
|
ParamCa specifies a path to a CA certificate PEM-encded DER file.
|
|
|
|
If not specified, the system's roots/trust anchors are used.
|
|
Files specified here will be included *in addition to* any
|
|
embedded root anchors found in the ParamCert parameter's
|
|
value, if using concatenated cert chains.
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamCa tlsUriParam = "pki_ca"
|
|
/*
|
|
ParamCert specifies a path to a leaf certificate PEM-encded DER file.
|
|
|
|
It may (and should/must) include any intermediate certificates necessary for
|
|
validation chain on the remote end.
|
|
It may include trust anchors, which will be considered *in addition to*
|
|
any ParamCa.
|
|
It may include a corresponding private key, which will be included for consideration
|
|
*in addition to* any ParamKey.
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamCert tlsUriParam = "pki_cert"
|
|
/*
|
|
ParamCipher specifies one (or more) cipher(s)
|
|
to specify for the TLS connection cipher negotiation.
|
|
Note that TLS 1.3 has a fixed set of ciphers, and
|
|
this list may not be respected by the remote end.
|
|
|
|
The string may either be the name (as per
|
|
https://www.iana.org/assignments/tls-parameters/tls-parameters.xml)
|
|
or an int (normal, hex, etc. string representation).
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamCipher tlsUriParam = "cipher"
|
|
/*
|
|
ParamCurve specifies one (or more) curve(s)
|
|
to specify for the TLS connection cipher negotiation.
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamCurve tlsUriParam = "curve"
|
|
/*
|
|
ParamIgnoreMissing, if `1`, `yes`, `y`, or `true` indicates
|
|
that missing cert/ca/key files should not return an error if they do not exist.
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamIgnoreMissing tlsUriParam = "ignore_missing"
|
|
/*
|
|
ParamKey specifies a path to a private key as a PEM-encded file.
|
|
|
|
It may be PKCS#1, PKCS#8, or PEM-encoded ASN.1 DER EC key.
|
|
|
|
Supported private key types are RSA, ED25519, and ECDSA.
|
|
(Technically ECDH keys are supported, but cannot be paired with certificates
|
|
so trying to use them may result in errors or undefined behavior.
|
|
Future versions may support this as a parameter for *kex* in a TLS
|
|
*connection*, but this is unplanned at the moment.)
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamKey tlsUriParam = "pki_key"
|
|
/*
|
|
ParamKeylog is a way to specify the SSLKEYLOGFILE.
|
|
|
|
This parameter's value can be:
|
|
|
|
* a filepath; parent directories will attempt to be created if
|
|
they do not exist, and the file will be truncated if it exists.
|
|
The consumer/downstream is responsible for calling .Close()
|
|
on it when done.
|
|
* the special string as defined by KeyLogEnvVal to use the filepath
|
|
of whatever is set in the environment variable as defined by
|
|
KeyLogEnv (which is likely the default variable name).
|
|
It is assumed to be a filepath.
|
|
The consumer/downstream is responsible for calling .Close()
|
|
on it when done.
|
|
* the special string as defined by KeyLogBufVal to use an in-memory
|
|
buffer instead
|
|
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
!! DO NOT, UNDER ANY CIRCUMSTANCES, ENABLE THIS UNLESS YOU ARE !!
|
|
!! ABSOLUTELY SURE WHAT YOU ARE DOING. !!
|
|
!! IT SEVERELY COMPROMISES SECURITY !!
|
|
!! AND IS ONLY INTENDED FOR DEBUGGING PURPOSES! !!
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
See https://www.ietf.org/archive/id/draft-thomson-tls-keylogfile-00.html
|
|
for details.
|
|
|
|
The exact type of the returned tls.Config.KeyLogWriter will be:
|
|
|
|
* an *os.File if a filepath or the KeyLogEnvVal value was specified
|
|
* a *bytes.Buffer if the KeyLogBufVal value was specified
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamKeylog tlsUriParam = "debug_keylog"
|
|
/*
|
|
ParamMaxTls defines the minimum version of the
|
|
TLS protocol to use.
|
|
|
|
See ParamMinTls for syntax of the value.
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamMaxTls tlsUriParam = "max_tls"
|
|
/*
|
|
ParamMinTls defines the minimum version of the
|
|
TLS protocol to use.
|
|
It is recommended to use "TLS_1.3".
|
|
|
|
Supported syntax formats include:
|
|
|
|
* TLS_1.3
|
|
* 1.3
|
|
* v1.3
|
|
* TLSv1.3
|
|
* 0x0304 (legacy_version, see RFC8446 § 4.1.2)
|
|
* 774 (0x0304 in int form)
|
|
* 0o1404 (0x0304 in octal form)
|
|
|
|
All evaluate to TLS 1.3 in this example.
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamMinTls tlsUriParam = "min_tls"
|
|
/*
|
|
ParamMtlsCa specifies a path to a CA certificate PEM-encoded DER file.
|
|
|
|
Unlike ParamCa, this is explicitly used to validate clients
|
|
(see ParamMtlsMode).
|
|
|
|
If not specified (and ParamMtlsMode is anything *but* `NoClientCert`/`0`),
|
|
the same evaluated roots/trust anchors used for ParamCa will be used.
|
|
|
|
It may be specified multiple times in a TLS URI.
|
|
*/
|
|
ParamMtlsCa tlsUriParam = "mtls_ca"
|
|
/*
|
|
ParamMtlsMode specifies if TLS client certificate auth should be used or not,
|
|
and what mode/type of requirement.
|
|
This is only useful if running a server/listener with mTLS auth.
|
|
Clients should leave it empty.
|
|
Servers/listeners should leave it empty if they do not wish to use
|
|
mTLS auth for clients.
|
|
|
|
The string may either be the name (as per
|
|
https://pkg.go.dev/crypto/tls#ClientAuthType)
|
|
or an int (normal, hex, etc. string representation) of the constant's value.
|
|
|
|
See also ParamMtlsCa.
|
|
*/
|
|
ParamMtlsMode tlsUriParam = "mtls_auth"
|
|
/*
|
|
ParamNet is used by TlsUri.ToConn and TlsUri.ToTlsConn to explicitly specify a network.
|
|
|
|
The default is "tcp".
|
|
|
|
See net.Dial()'s "network" parameter for valid network types.
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamNet tlsUriParam = "net"
|
|
/*
|
|
ParamNoVerify, if `1`, `yes`, `y`, or `true` indicates
|
|
that the TLS connection should not require verification of
|
|
the remote end (e.g. hostname matches, trusted chain, etc.).
|
|
|
|
Any other value for this parameter will be parsed as "False"
|
|
(meaning the remote end's certificate SHOULD be verified).
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamNoVerify tlsUriParam = "no_verify"
|
|
/*
|
|
ParamSni indicates that the TLS connection should expect this hostname
|
|
instead of the hostname specified in the URI itself.
|
|
|
|
Only the first defined instance is parsed.
|
|
*/
|
|
ParamSni tlsUriParam = "sni"
|
|
)
|
|
|
|
var (
|
|
paramBoolValsTrue []string = []string{
|
|
"true", "yes", "y", "1",
|
|
}
|
|
paramBoolValsFalse []string = []string{
|
|
"false", "no", "n", "0",
|
|
}
|
|
validate *validator.Validate = validator.New(validator.WithRequiredStructEnabled())
|
|
)
|