@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 108 lines 2.97 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package caddytls
16
17 import (
18 "crypto/x509"
19 "encoding/pem"
20 "fmt"
21 "os"
22
23 "github.com/caddyserver/caddy/v2"
24 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
25 )
26
27 func init() {
28 caddy.RegisterModule(LeafFileLoader{})
29 }
30
31 // LeafFileLoader loads leaf certificates from disk.
32 type LeafFileLoader struct {
33 Files []string `json:"files,omitempty"`
34 }
35
36 // CaddyModule returns the Caddy module information.
37 func (LeafFileLoader) CaddyModule() caddy.ModuleInfo {
38 return caddy.ModuleInfo{
39 ID: "tls.leaf_cert_loader.file",
40 New: func() caddy.Module { return new(LeafFileLoader) },
41 }
42 }
43
44 // Provision implements caddy.Provisioner.
45 func (fl *LeafFileLoader) Provision(ctx caddy.Context) error {
46 repl, ok := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
47 if !ok {
48 repl = caddy.NewReplacer()
49 }
50 for k, path := range fl.Files {
51 fl.Files[k] = repl.ReplaceKnown(path, "")
52 }
53 return nil
54 }
55
56 // UnmarshalCaddyfile implements caddyfile.Unmarshaler.
57 func (fl *LeafFileLoader) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
58 d.NextArg()
59 fl.Files = append(fl.Files, d.RemainingArgs()...)
60 return nil
61 }
62
63 // LoadLeafCertificates returns the certificates to be loaded by fl.
64 func (fl LeafFileLoader) LoadLeafCertificates() ([]*x509.Certificate, error) {
65 certificates := make([]*x509.Certificate, 0, len(fl.Files))
66 for _, path := range fl.Files {
67 ders, err := convertPEMFilesToDERBytes(path)
68 if err != nil {
69 return nil, err
70 }
71 certs, err := x509.ParseCertificates(ders)
72 if err != nil {
73 return nil, err
74 }
75 certificates = append(certificates, certs...)
76 }
77 return certificates, nil
78 }
79
80 func convertPEMFilesToDERBytes(filename string) ([]byte, error) {
81 certDataPEM, err := os.ReadFile(filename)
82 if err != nil {
83 return nil, err
84 }
85 var ders []byte
86 // while block is not nil, we have more certificates in the file
87 for block, rest := pem.Decode(certDataPEM); block != nil; block, rest = pem.Decode(rest) {
88 if block.Type != "CERTIFICATE" {
89 return nil, fmt.Errorf("no CERTIFICATE pem block found in %s", filename)
90 }
91 ders = append(
92 ders,
93 block.Bytes...,
94 )
95 }
96 // if we decoded nothing, return an error
97 if len(ders) == 0 {
98 return nil, fmt.Errorf("no CERTIFICATE pem block found in %s", filename)
99 }
100 return ders, nil
101 }
102
103 // Interface guard
104 var (
105 _ LeafCertificateLoader = (*LeafFileLoader)(nil)
106 _ caddy.Provisioner = (*LeafFileLoader)(nil)
107 _ caddyfile.Unmarshaler = (*LeafFileLoader)(nil)
108 )