| 
									
										
										
										
											2019-06-30 16:07:58 -06:00
										 |  |  | // Copyright 2015 Matthew Holt and The Caddy Authors | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License. | 
					
						
							|  |  |  | // You may obtain a copy of the License at | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0 | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and | 
					
						
							|  |  |  | // limitations under the License. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | package caddytls | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"crypto/tls" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-09-30 01:17:48 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2024-09-25 08:00:48 -04:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 12:37:06 -06:00
										 |  |  | 	"github.com/caddyserver/caddy/v2" | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							| 
									
										
										
										
											2019-08-21 10:46:35 -06:00
										 |  |  | 	caddy.RegisterModule(FileLoader{}) | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 12:05:47 -06:00
										 |  |  | // FileLoader loads certificates and their associated keys from disk. | 
					
						
							|  |  |  | type FileLoader []CertKeyFilePair | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 19:23:15 +03:00
										 |  |  | // Provision implements caddy.Provisioner. | 
					
						
							|  |  |  | func (fl FileLoader) Provision(ctx caddy.Context) error { | 
					
						
							|  |  |  | 	repl, ok := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		repl = caddy.NewReplacer() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for k, pair := range fl { | 
					
						
							|  |  |  | 		for i, tag := range pair.Tags { | 
					
						
							|  |  |  | 			pair.Tags[i] = repl.ReplaceKnown(tag, "") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		fl[k] = CertKeyFilePair{ | 
					
						
							|  |  |  | 			Certificate: repl.ReplaceKnown(pair.Certificate, ""), | 
					
						
							|  |  |  | 			Key:         repl.ReplaceKnown(pair.Key, ""), | 
					
						
							|  |  |  | 			Format:      repl.ReplaceKnown(pair.Format, ""), | 
					
						
							|  |  |  | 			Tags:        pair.Tags, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-21 10:46:35 -06:00
										 |  |  | // CaddyModule returns the Caddy module information. | 
					
						
							|  |  |  | func (FileLoader) CaddyModule() caddy.ModuleInfo { | 
					
						
							|  |  |  | 	return caddy.ModuleInfo{ | 
					
						
							| 
									
										
										
										
											2019-12-10 13:36:46 -07:00
										 |  |  | 		ID:  "tls.certificates.load_files", | 
					
						
							|  |  |  | 		New: func() caddy.Module { return new(FileLoader) }, | 
					
						
							| 
									
										
										
										
											2019-08-21 10:46:35 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | // CertKeyFilePair pairs certificate and key file names along with their | 
					
						
							|  |  |  | // encoding format so that they can be loaded from disk. | 
					
						
							|  |  |  | type CertKeyFilePair struct { | 
					
						
							| 
									
										
										
										
											2019-12-10 13:36:46 -07:00
										 |  |  | 	// Path to the certificate (public key) file. | 
					
						
							|  |  |  | 	Certificate string `json:"certificate"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Path to the private key file. | 
					
						
							|  |  |  | 	Key string `json:"key"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// The format of the cert and key. Can be "pem". Default: "pem" | 
					
						
							|  |  |  | 	Format string `json:"format,omitempty"` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Arbitrary values to associate with this certificate. | 
					
						
							|  |  |  | 	// Can be useful when you want to select a particular | 
					
						
							|  |  |  | 	// certificate when there may be multiple valid candidates. | 
					
						
							|  |  |  | 	Tags []string `json:"tags,omitempty"` | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadCertificates returns the certificates to be loaded by fl. | 
					
						
							| 
									
										
										
										
											2019-08-09 12:05:47 -06:00
										 |  |  | func (fl FileLoader) LoadCertificates() ([]Certificate, error) { | 
					
						
							| 
									
										
										
										
											2020-04-09 00:31:51 +03:00
										 |  |  | 	certs := make([]Certificate, 0, len(fl)) | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 	for _, pair := range fl { | 
					
						
							| 
									
										
										
										
											2021-09-30 01:17:48 +08:00
										 |  |  | 		certData, err := os.ReadFile(pair.Certificate) | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-09-30 01:17:48 +08:00
										 |  |  | 		keyData, err := os.ReadFile(pair.Key) | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var cert tls.Certificate | 
					
						
							|  |  |  | 		switch pair.Format { | 
					
						
							|  |  |  | 		case "": | 
					
						
							|  |  |  | 			fallthrough | 
					
						
							| 
									
										
										
										
											2024-09-25 08:00:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 		case "pem": | 
					
						
							| 
									
										
										
										
											2024-09-25 08:00:48 -04:00
										 |  |  | 			// if the start of the key file looks like an encrypted private key, | 
					
						
							|  |  |  | 			// reject it with a helpful error message | 
					
						
							|  |  |  | 			if strings.Contains(string(keyData[:40]), "ENCRYPTED") { | 
					
						
							|  |  |  | 				return nil, fmt.Errorf("encrypted private keys are not supported; please decrypt the key first") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 			cert, err = tls.X509KeyPair(certData, keyData) | 
					
						
							| 
									
										
										
										
											2024-09-25 08:00:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("unrecognized certificate/key encoding format: %s", pair.Format) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-24 12:16:10 -06:00
										 |  |  | 		certs = append(certs, Certificate{Certificate: cert, Tags: pair.Tags}) | 
					
						
							| 
									
										
										
										
											2019-04-25 13:54:48 -06:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return certs, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Interface guard | 
					
						
							| 
									
										
										
										
											2023-12-04 19:23:15 +03:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	_ CertificateLoader = (FileLoader)(nil) | 
					
						
							|  |  |  | 	_ caddy.Provisioner = (FileLoader)(nil) | 
					
						
							|  |  |  | ) |