@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 118 lines 3.2 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/tls"
19 "fmt"
20 "strings"
21
22 "github.com/caddyserver/certmagic"
23
24 "github.com/caddyserver/caddy/v2"
25 )
26
27 func init() {
28 caddy.RegisterModule(StorageLoader{})
29 }
30
31 // StorageLoader loads certificates and their associated keys
32 // from the globally configured storage module.
33 type StorageLoader struct {
34 // A list of pairs of certificate and key file names along with their
35 // encoding format so that they can be loaded from storage.
36 Pairs []CertKeyFilePair `json:"pairs,omitempty"`
37
38 // Reference to the globally configured storage module.
39 storage certmagic.Storage
40
41 ctx caddy.Context
42 }
43
44 // CaddyModule returns the Caddy module information.
45 func (StorageLoader) CaddyModule() caddy.ModuleInfo {
46 return caddy.ModuleInfo{
47 ID: "tls.certificates.load_storage",
48 New: func() caddy.Module { return new(StorageLoader) },
49 }
50 }
51
52 // Provision loads the storage module for sl.
53 func (sl *StorageLoader) Provision(ctx caddy.Context) error {
54 sl.storage = ctx.Storage()
55 sl.ctx = ctx
56
57 repl, ok := ctx.Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
58 if !ok {
59 repl = caddy.NewReplacer()
60 }
61 for k, pair := range sl.Pairs {
62 for i, tag := range pair.Tags {
63 pair.Tags[i] = repl.ReplaceKnown(tag, "")
64 }
65 sl.Pairs[k] = CertKeyFilePair{
66 Certificate: repl.ReplaceKnown(pair.Certificate, ""),
67 Key: repl.ReplaceKnown(pair.Key, ""),
68 Format: repl.ReplaceKnown(pair.Format, ""),
69 Tags: pair.Tags,
70 }
71 }
72 return nil
73 }
74
75 // LoadCertificates returns the certificates to be loaded by sl.
76 func (sl StorageLoader) LoadCertificates() ([]Certificate, error) {
77 certs := make([]Certificate, 0, len(sl.Pairs))
78 for _, pair := range sl.Pairs {
79 certData, err := sl.storage.Load(sl.ctx, pair.Certificate)
80 if err != nil {
81 return nil, err
82 }
83 keyData, err := sl.storage.Load(sl.ctx, pair.Key)
84 if err != nil {
85 return nil, err
86 }
87
88 var cert tls.Certificate
89 switch pair.Format {
90 case "":
91 fallthrough
92
93 case "pem":
94 // if the start of the key file looks like an encrypted private key,
95 // reject it with a helpful error message
96 if strings.Contains(string(keyData[:40]), "ENCRYPTED") {
97 return nil, fmt.Errorf("encrypted private keys are not supported; please decrypt the key first")
98 }
99
100 cert, err = tls.X509KeyPair(certData, keyData)
101
102 default:
103 return nil, fmt.Errorf("unrecognized certificate/key encoding format: %s", pair.Format)
104 }
105 if err != nil {
106 return nil, err
107 }
108
109 certs = append(certs, Certificate{Certificate: cert, Tags: pair.Tags})
110 }
111 return certs, nil
112 }
113
114 // Interface guard
115 var (
116 _ CertificateLoader = (*StorageLoader)(nil)
117 _ caddy.Provisioner = (*StorageLoader)(nil)
118 )