github.com/searKing/golang/go@v1.2.117/crypto/tls/cert.go (about) 1 // Copyright 2022 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tls 6 7 import ( 8 "crypto/tls" 9 "crypto/x509" 10 "encoding/base64" 11 "errors" 12 "fmt" 13 ) 14 15 // This code is borrowed from https://github.com/ory/x/blob/master/tlsx/cert.go 16 17 // ErrNoCertificatesConfigured is returned when no TLS configuration was found. 18 var ErrNoCertificatesConfigured = errors.New("no tls configuration was found") 19 20 // ErrInvalidCertificateConfiguration is returned when an invalid TLS configuration was found. 21 var ErrInvalidCertificateConfiguration = errors.New("tls configuration is invalid") 22 23 // LoadCertificates returns loads a TLS LoadCertificates. 24 // certString: Base64 encoded (without padding) string of the TLS certificate (PEM encoded) to be used for HTTP over TLS (HTTPS). 25 // Example: certString="-----BEGIN CERTIFICATE-----\nMIIDZTCCAk2gAwIBAgIEV5xOtDANBgkqhkiG9w0BAQ0FADA0MTIwMAYDVQQDDClP..." 26 // keyString: Base64 encoded (without padding) string of the private key (PEM encoded) to be used for HTTP over TLS (HTTPS). 27 // Example: keyString="-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDg..." 28 // certPath: The path to the TLS certificate (pem encoded). 29 // Example: certPath=~/cert.pem 30 // keyPath: The path to the TLS private key (pem encoded). 31 // Example: keyPath=~/key.pem 32 // certs: certs of tls.Certificate, *tls.Certificate 33 func LoadCertificates( 34 certString, keyString string, 35 certFile, keyFile string, 36 certs ...any, 37 ) ([]tls.Certificate, error) { 38 if certString == "" && keyString == "" && certFile == "" && keyFile == "" && len(certs) == 0 { 39 return nil, ErrNoCertificatesConfigured 40 } 41 if certString != "" && keyString != "" { 42 tlsCertBytes, err := base64.StdEncoding.DecodeString(certString) 43 if err != nil { 44 return nil, fmt.Errorf("unable to base64 decode the TLS certificate: %v", err) 45 } 46 tlsKeyBytes, err := base64.StdEncoding.DecodeString(keyString) 47 if err != nil { 48 return nil, fmt.Errorf("unable to base64 decode the TLS private key: %v", err) 49 } 50 51 cert, err := tls.X509KeyPair(tlsCertBytes, tlsKeyBytes) 52 if err != nil { 53 return nil, fmt.Errorf("unable to load X509 key pair: %v", err) 54 } 55 return []tls.Certificate{cert}, nil 56 } 57 58 if certFile != "" && keyFile != "" { 59 cert, err := tls.LoadX509KeyPair(certFile, keyFile) 60 if err != nil { 61 return nil, fmt.Errorf("unable to load X509 key pair from files: %v", err) 62 } 63 return []tls.Certificate{cert}, nil 64 } 65 var uniformedCerts []tls.Certificate 66 for _, cert := range of(certs...) { 67 switch cert.(type) { 68 case *tls.Certificate: 69 tlsCert := cert.(*tls.Certificate) 70 uniformedCerts = append(uniformedCerts, *tlsCert) 71 case tls.Certificate: 72 tlsCert := cert.(tls.Certificate) 73 uniformedCerts = append(uniformedCerts, tlsCert) 74 default: 75 return nil, fmt.Errorf("unable to load X509 key pair from cert: %v", cert) 76 } 77 } 78 79 return nil, ErrInvalidCertificateConfiguration 80 } 81 82 // LoadX509Certificates returns loads a TLS LoadCertificates of x509. 83 func LoadX509Certificates( 84 certString, keyString string, 85 certFile, keyFile string, 86 ) ([]*x509.Certificate, error) { 87 certs, err := LoadCertificates(certString, keyString, certFile, keyFile) 88 if err != nil { 89 return nil, err 90 } 91 var x509Certs []*x509.Certificate 92 for _, cert := range certs { 93 for _, certBytes := range cert.Certificate { 94 x509Cert, err := x509.ParseCertificate(certBytes) 95 if err != nil { 96 return nil, err 97 } 98 x509Certs = append(x509Certs, x509Cert) 99 } 100 } 101 if len(x509Certs) == 0 { 102 return nil, ErrNoCertificatesConfigured 103 } 104 return x509Certs, nil 105 } 106 107 func LoadCertificateAndPool( 108 certPool *x509.CertPool, 109 certString, keyString string, 110 certFile, keyFile string, 111 ) ([]tls.Certificate, *x509.CertPool, error) { 112 certs, err := LoadCertificates(certString, keyString, certFile, keyFile) 113 if err != nil { 114 return nil, nil, err 115 } 116 certPool, err = LoadX509CertificatePool(certPool, "", "", certs) 117 if err != nil { 118 return nil, nil, err 119 } 120 return certs, certPool, nil 121 122 }