160 lines
3.4 KiB
Go
160 lines
3.4 KiB
Go
|
package cryptparse
|
||
|
|
||
|
import (
|
||
|
`crypto`
|
||
|
`crypto/tls`
|
||
|
`net/url`
|
||
|
`os`
|
||
|
`strings`
|
||
|
)
|
||
|
|
||
|
/*
|
||
|
ToTlsConfig returns a *tls.Config from a TlsUri.
|
||
|
|
||
|
Unfortunately it's not possible for this library to do the reverse, as CA certificates are not able to be extracted from an x509.CertPool.
|
||
|
*/
|
||
|
func (t *TlsUri) ToTlsConfig() (cfg *tls.Config, err error) {
|
||
|
|
||
|
if cfg, err = ParseTlsUri(t.URL); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ToTlsFlat returns a *TlsFlat from a TlsUri.
|
||
|
func (t *TlsUri) ToTlsFlat() (tlsFlat *TlsFlat, err error) {
|
||
|
|
||
|
var b []byte
|
||
|
var params url.Values
|
||
|
var paramMap map[string][]string
|
||
|
// These also have maps so they can backmap filenames.
|
||
|
var privKeys []crypto.PrivateKey
|
||
|
var privKeyMap map[string][]crypto.PrivateKey
|
||
|
var tlsCerts []tls.Certificate
|
||
|
var tlsCertMap map[string][]tls.Certificate
|
||
|
var isMatch bool
|
||
|
var fCert *TlsFlatCert
|
||
|
var val string
|
||
|
var f TlsFlat = TlsFlat{
|
||
|
SniName: t.Hostname(),
|
||
|
SkipVerify: false,
|
||
|
Certs: nil,
|
||
|
CaFiles: nil,
|
||
|
CipherSuites: nil,
|
||
|
MinTlsProtocol: nil,
|
||
|
MaxTlsProtocol: nil,
|
||
|
Curves: nil,
|
||
|
}
|
||
|
|
||
|
params = t.Query()
|
||
|
paramMap = params
|
||
|
|
||
|
if params == nil {
|
||
|
tlsFlat = &f
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// CA cert(s).
|
||
|
if t.Query().Has(TlsUriParamCa) {
|
||
|
f.CaFiles = append(f.CaFiles, paramMap[TlsUriParamCa]...)
|
||
|
}
|
||
|
|
||
|
// Keys and Certs. These are done first so we can match to a client certificate.
|
||
|
if t.Query().Has(TlsUriParamKey) {
|
||
|
privKeyMap = make(map[string][]crypto.PrivateKey)
|
||
|
for _, kFile := range paramMap[TlsUriParamKey] {
|
||
|
if b, err = os.ReadFile(kFile); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if privKeyMap[kFile], err = ParsePrivateKey(b); err != nil {
|
||
|
return
|
||
|
}
|
||
|
privKeys = append(privKeys, privKeyMap[kFile]...)
|
||
|
}
|
||
|
}
|
||
|
if t.Query().Has(TlsUriParamCert) {
|
||
|
tlsCertMap = make(map[string][]tls.Certificate)
|
||
|
for _, cFile := range paramMap[TlsUriParamCert] {
|
||
|
if b, err = os.ReadFile(cFile); err != nil {
|
||
|
return
|
||
|
}
|
||
|
if tlsCertMap[cFile], err = ParseLeafCert(b, privKeys); err != nil {
|
||
|
return
|
||
|
}
|
||
|
tlsCerts = append(tlsCerts, tlsCertMap[cFile]...)
|
||
|
}
|
||
|
}
|
||
|
// We then correlate. Whew, lads.
|
||
|
for cFile, c := range tlsCertMap {
|
||
|
for _, cert := range c {
|
||
|
for kFile, k := range privKeyMap {
|
||
|
if isMatch, err = IsMatchedPair(k, cert.Leaf); err != nil {
|
||
|
return
|
||
|
} else if isMatch {
|
||
|
fCert = &TlsFlatCert{
|
||
|
CertFile: cFile,
|
||
|
KeyFile: new(string),
|
||
|
}
|
||
|
*fCert.KeyFile = kFile
|
||
|
f.Certs = append(f.Certs, fCert)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Hostname.
|
||
|
if t.Query().Has(TlsUriParamSni) {
|
||
|
f.SniName = t.Query().Get(TlsUriParamSni)
|
||
|
}
|
||
|
|
||
|
// Disable verification.
|
||
|
if t.Query().Has(TlsUriParamNoVerify) {
|
||
|
val = strings.ToLower(t.Query().Get(TlsUriParamNoVerify))
|
||
|
for _, i := range paramBoolValsTrue {
|
||
|
if val == i {
|
||
|
f.SkipVerify = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Ciphers.
|
||
|
if t.Query().Has(TlsUriParamCipher) {
|
||
|
f.CipherSuites = params[TlsUriParamCipher]
|
||
|
}
|
||
|
|
||
|
// Minimum TLS Protocol Version.
|
||
|
if t.Query().Has(TlsUriParamMinTls) {
|
||
|
f.MinTlsProtocol = new(string)
|
||
|
*f.MinTlsProtocol = t.Query().Get(TlsUriParamMinTls)
|
||
|
}
|
||
|
|
||
|
// Maximum TLS Protocol Version.
|
||
|
if t.Query().Has(TlsUriParamMaxTls) {
|
||
|
f.MaxTlsProtocol = new(string)
|
||
|
*f.MaxTlsProtocol = t.Query().Get(TlsUriParamMaxTls)
|
||
|
}
|
||
|
|
||
|
// Curves.
|
||
|
if t.Query().Has(TlsUriParamCurve) {
|
||
|
f.Curves = params[TlsUriParamCurve]
|
||
|
}
|
||
|
|
||
|
tlsFlat = &f
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ToURL returns the *url.URL representation of a TlsUri.
|
||
|
func (t *TlsUri) ToURL() (u *url.URL) {
|
||
|
|
||
|
if t == nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
u = t.URL
|
||
|
|
||
|
return
|
||
|
}
|