// setupTLS sets up the TLS configuration and installs certificates that // are specified by the user in the config file. All the automatic HTTPS // stuff comes later outside of this function. func setupTLS(c *caddy.Controller) error { configGetter, ok := configGetters[c.ServerType()] if !ok { return fmt.Errorf("no caddytls.ConfigGetter for %s server type; must call RegisterConfigGetter", c.ServerType()) } config := configGetter(c) if config == nil { return fmt.Errorf("no caddytls.Config to set up for %s", c.Key) } config.Enabled = true for c.Next() { var certificateFile, keyFile, loadDir, maxCerts string args := c.RemainingArgs() switch len(args) { case 1: // even if the email is one of the special values below, // it is still necessary for future analysis that we store // that value in the ACMEEmail field. config.ACMEEmail = args[0] // user can force-disable managed TLS this way if args[0] == "off" { config.Enabled = false return nil } // user might want a temporary, in-memory, self-signed cert if args[0] == "self_signed" { config.SelfSigned = true } case 2: certificateFile = args[0] keyFile = args[1] config.Manual = true } // Optional block with extra parameters var hadBlock bool for c.NextBlock() { hadBlock = true switch c.Val() { case "key_type": arg := c.RemainingArgs() value, ok := supportedKeyTypes[strings.ToUpper(arg[0])] if !ok { return c.Errf("Wrong key type name or key type not supported: '%s'", c.Val()) } config.KeyType = value case "protocols": args := c.RemainingArgs() if len(args) == 1 { value, ok := supportedProtocols[strings.ToLower(args[0])] if !ok { return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0]) } config.ProtocolMinVersion, config.ProtocolMaxVersion = value, value } else { value, ok := supportedProtocols[strings.ToLower(args[0])] if !ok { return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[0]) } config.ProtocolMinVersion = value value, ok = supportedProtocols[strings.ToLower(args[1])] if !ok { return c.Errf("Wrong protocol name or protocol not supported: '%s'", args[1]) } config.ProtocolMaxVersion = value if config.ProtocolMinVersion > config.ProtocolMaxVersion { return c.Errf("Minimum protocol version cannot be higher than maximum (reverse the order)") } } case "ciphers": for c.NextArg() { value, ok := supportedCiphersMap[strings.ToUpper(c.Val())] if !ok { return c.Errf("Wrong cipher name or cipher not supported: '%s'", c.Val()) } config.Ciphers = append(config.Ciphers, value) } case "clients": clientCertList := c.RemainingArgs() if len(clientCertList) == 0 { return c.ArgErr() } listStart, mustProvideCA := 1, true switch clientCertList[0] { case "request": config.ClientAuth = tls.RequestClientCert mustProvideCA = false case "require": config.ClientAuth = tls.RequireAnyClientCert mustProvideCA = false case "verify_if_given": config.ClientAuth = tls.VerifyClientCertIfGiven default: config.ClientAuth = tls.RequireAndVerifyClientCert listStart = 0 } if mustProvideCA && len(clientCertList) <= listStart { return c.ArgErr() } config.ClientCerts = clientCertList[listStart:] case "load": c.Args(&loadDir) config.Manual = true case "max_certs": c.Args(&maxCerts) config.OnDemand = true case "dns": args := c.RemainingArgs() if len(args) != 1 { return c.ArgErr() } dnsProvName := args[0] if _, ok := dnsProviders[dnsProvName]; !ok { return c.Errf("Unsupported DNS provider '%s'", args[0]) } config.DNSProvider = args[0] case "storage": args := c.RemainingArgs() if len(args) != 1 { return c.ArgErr() } storageProvName := args[0] if _, ok := storageProviders[storageProvName]; !ok { return c.Errf("Unsupported Storage provider '%s'", args[0]) } config.StorageProvider = args[0] default: return c.Errf("Unknown keyword '%s'", c.Val()) } } // tls requires at least one argument if a block is not opened if len(args) == 0 && !hadBlock { return c.ArgErr() } // set certificate limit if on-demand TLS is enabled if maxCerts != "" { maxCertsNum, err := strconv.Atoi(maxCerts) if err != nil || maxCertsNum < 1 { return c.Err("max_certs must be a positive integer") } config.OnDemandState.MaxObtain = int32(maxCertsNum) } // don't try to load certificates unless we're supposed to if !config.Enabled || !config.Manual { continue } // load a single certificate and key, if specified if certificateFile != "" && keyFile != "" { err := cacheUnmanagedCertificatePEMFile(certificateFile, keyFile) if err != nil { return c.Errf("Unable to load certificate and key files for '%s': %v", c.Key, err) } log.Printf("[INFO] Successfully loaded TLS assets from %s and %s", certificateFile, keyFile) } // load a directory of certificates, if specified if loadDir != "" { err := loadCertsInDir(c, loadDir) if err != nil { return err } } } SetDefaultTLSParams(config) // generate self-signed cert if needed if config.SelfSigned { err := makeSelfSignedCert(config) if err != nil { return fmt.Errorf("self-signed: %v", err) } } return nil }