2 * Copyright 2018 Intel Corporation, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 pkgerrors "github.com/pkg/errors"
30 // GetTLSConfig initializes a tlsConfig using the CA's certificate
31 // This config is then used to enable the server for mutual TLS
32 func GetTLSConfig(caCertFile string, certFile string, keyFile string) (*tls.Config, error) {
34 // Initialize tlsConfig once
35 caCert, err := ioutil.ReadFile(caCertFile)
38 return nil, pkgerrors.Wrap(err, "Read CA Cert file")
41 caCertPool := x509.NewCertPool()
42 caCertPool.AppendCertsFromPEM(caCert)
44 tlsConfig := &tls.Config{
45 // Change to RequireAndVerify once we have mandatory certs
46 ClientAuth: tls.VerifyClientCertIfGiven,
47 ClientCAs: caCertPool,
48 MinVersion: tls.VersionTLS12,
51 certPEMBlk, err := readPEMBlock(certFile)
53 return nil, pkgerrors.Wrap(err, "Read Cert File")
56 keyPEMBlk, err := readPEMBlock(keyFile)
58 return nil, pkgerrors.Wrap(err, "Read Key File")
61 tlsConfig.Certificates = make([]tls.Certificate, 1)
62 tlsConfig.Certificates[0], err = tls.X509KeyPair(certPEMBlk, keyPEMBlk)
64 return nil, pkgerrors.Wrap(err, "Load x509 cert and key")
67 tlsConfig.BuildNameToCertificate()
71 func readPEMBlock(filename string) ([]byte, error) {
73 pemData, err := ioutil.ReadFile(filename)
75 return nil, pkgerrors.Wrap(err, "Read PEM File")
78 pemBlock, rest := pem.Decode(pemData)
80 log.Println("Pemfile has extra data")
83 if x509.IsEncryptedPEMBlock(pemBlock) {
84 password, err := ioutil.ReadFile(filename + ".pass")
86 return nil, pkgerrors.Wrap(err, "Read Password File")
89 pByte, err := base64.StdEncoding.DecodeString(string(password))
91 return nil, pkgerrors.Wrap(err, "Decode PEM Password")
94 pemData, err = x509.DecryptPEMBlock(pemBlock, pByte)
96 return nil, pkgerrors.Wrap(err, "Decrypt PEM Data")
98 var newPEMBlock pem.Block
99 newPEMBlock.Type = pemBlock.Type
100 newPEMBlock.Bytes = pemData
101 // Converting back to PEM from DER data you get from
103 pemData = pem.EncodeToMemory(&newPEMBlock)