From 77a85a4f845981640fbf5dcd37fa35d2c2c6eddb Mon Sep 17 00:00:00 2001 From: brent saner Date: Thu, 8 Aug 2024 19:40:11 -0400 Subject: [PATCH] v1.5.0 ADDED: * cryptpartse.TlsUri now has methods to returned dialed net.Conn and tls.Conn, or can use WithConn to add TLS to an already-dialed net.Conn. --- cryptparse/consts.go | 21 +++++++--- cryptparse/funcs_tlsuri.go | 81 +++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/cryptparse/consts.go b/cryptparse/consts.go index 2201ad5..0b3577a 100644 --- a/cryptparse/consts.go +++ b/cryptparse/consts.go @@ -13,13 +13,14 @@ var ( ) 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 + 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" ) -// TlsUriParam* specifiy URL query parameters to parse a tls:// URI. +// TlsUriParam* specifiy URL query parameters to parse a tls:// URI, and are used by TlsUri methods. const ( /* TlsUriParamCa specifies a path to a CA certificate PEM-encded DER file. @@ -110,6 +111,16 @@ const ( Only the first defined instance is parsed. */ TlsUriParamMaxTls string = "max_tls" + /* + TlsUriParamNet 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. + */ + TlsUriParamNet string = "net" ) var ( diff --git a/cryptparse/funcs_tlsuri.go b/cryptparse/funcs_tlsuri.go index 482c264..6b16e0d 100644 --- a/cryptparse/funcs_tlsuri.go +++ b/cryptparse/funcs_tlsuri.go @@ -3,11 +3,59 @@ package cryptparse import ( `crypto` `crypto/tls` + `net` `net/url` `os` `strings` ) +/* + WithConn returns a (crypto/)tls.Conn from an existing/already dialed net.Conn. + + underlying should be a "bare" net.Conn; behavior is undefined/unknown if the underlying conn is already a (crypto/)tls.Conn. +*/ +func (t *TlsUri) WithConn(underlying net.Conn) (conn *tls.Conn, err error) { + + var cfg *tls.Config + + if cfg, err = t.ToTlsConfig(); err != nil { + return + } + + conn = tls.Client(underlying, cfg) + + return +} + +/* + ToConn returns a "bare" net.Conn (already dialed) from a TlsUri. + + Note that this does NOT include the TLS configured or initialized; use TlsUri.ToTlsConn for that. + (A (crypto/)tls.Conn conforms to net.Conn.) + + An error will be returned if no port is explicitly defined in the TlsUri. +*/ +func (t *TlsUri) ToConn() (conn net.Conn, err error) { + + var ok bool + var params map[string][]string + var netType string = DefaultNetType + + params = t.Query() + + if params != nil { + if _, ok = params[TlsUriParamNet]; ok { + netType = params[TlsUriParamNet][0] + } + } + + if conn, err = net.Dial(netType, t.Host); err != nil { + return + } + + return +} + /* ToTlsConfig returns a *tls.Config from a TlsUri. @@ -22,6 +70,37 @@ func (t *TlsUri) ToTlsConfig() (cfg *tls.Config, err error) { return } +/* + ToTlsConn returns a (crypto/)tls.Conn (already dialed) from a TlsUri. + + An error will be returned if no port is explicitly defined in the TlsUri. +*/ +func (t *TlsUri) ToTlsConn() (conn *tls.Conn, err error) { + + var ok bool + var cfg *tls.Config + var params map[string][]string + var netType string = DefaultNetType + + if cfg, err = t.ToTlsConfig(); err != nil { + return + } + + params = t.Query() + + if params != nil { + if _, ok = params[TlsUriParamNet]; ok { + netType = params[TlsUriParamNet][0] + } + } + + if conn, err = tls.Dial(netType, t.Host, cfg); err != nil { + return + } + + return +} + // ToTlsFlat returns a *TlsFlat from a TlsUri. func (t *TlsUri) ToTlsFlat() (tlsFlat *TlsFlat, err error) { @@ -146,7 +225,7 @@ func (t *TlsUri) ToTlsFlat() (tlsFlat *TlsFlat, err error) { return } -// ToURL returns the *url.URL representation of a TlsUri. +// ToURL returns the *url.URL representation of a TlsUri. Note that the params will remain, so remove them explicitly if needed. func (t *TlsUri) ToURL() (u *url.URL) { if t == nil {