github.com/iDigitalFlame/xmt@v0.5.4/com/tls.go (about)

     1  // Copyright (C) 2020 - 2023 iDigitalFlame
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  //
    16  
    17  package com
    18  
    19  import (
    20  	"crypto/tls"
    21  	"crypto/x509"
    22  
    23  	"github.com/iDigitalFlame/xmt/util/xerr"
    24  )
    25  
    26  // ErrInvalidTLSConfig is returned when attempting to use the default TLS Connector
    27  // as a listener. This error is also returned when attempting to use a TLS
    28  // configuration that does not have a valid server certificates.
    29  var ErrInvalidTLSConfig = xerr.Sub("invalid or missing TLS certificates", 0x2D)
    30  
    31  // NewTLSConfig generates a new 'tls.Config' struct from the provided TLS details.
    32  // This can be used to generate mTLS or just simple CA-based TLS server/clients
    33  // Connectors.
    34  //
    35  // The provided ca bytes (in PEM format) can be used to validate client certificates
    36  // while the pem and key bytes (in PEM format) are used for the listening socket.
    37  //
    38  // The 'ver' integer represents the TLS-min version requirement. Setting it to zero
    39  // will default to TLSv1. SSLv3 is NOT SUPPORTED!
    40  //
    41  // This function returns an error if the ca, pem and/or key are empty.
    42  // The 'mu' bool will determine if mTLS should be enforced.
    43  //
    44  // mTLS insights sourced from: https://kofo.dev/how-to-mtls-in-golang
    45  func NewTLSConfig(mu bool, ver uint16, ca, pem, key []byte) (*tls.Config, error) {
    46  	var c tls.Config
    47  	switch {
    48  	case ver > 0 && ver < 0xFF:
    49  		c.MinVersion = ver + tls.VersionTLS10
    50  	case ver > tls.VersionTLS10:
    51  		c.MinVersion = ver
    52  	default:
    53  		c.MinVersion = tls.VersionTLS12
    54  	}
    55  	if len(pem) > 0 && len(key) > 0 {
    56  		x, err := tls.X509KeyPair(pem, key)
    57  		if err != nil {
    58  			return nil, err
    59  		}
    60  		c.Certificates = []tls.Certificate{x}
    61  	}
    62  	if len(ca) > 0 {
    63  		if c.RootCAs = x509.NewCertPool(); !c.RootCAs.AppendCertsFromPEM(ca) {
    64  			return nil, ErrInvalidTLSConfig
    65  		}
    66  		if mu {
    67  			c.ClientCAs = c.RootCAs
    68  			c.ClientAuth = tls.RequireAndVerifyClientCert
    69  		}
    70  	}
    71  	return &c, nil
    72  }