| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- // Copyright 2019 Yunion
- //
- // 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.
- package seclib2
- import (
- "bytes"
- "crypto/tls"
- "crypto/x509"
- "encoding/pem"
- "io/ioutil"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- )
- var CERT_SEP = []byte("-END CERTIFICATE-")
- func findCertEndIndex(certBytes []byte) int {
- endpos := bytes.Index(certBytes, CERT_SEP)
- if endpos < 0 {
- return endpos
- }
- endpos += len(CERT_SEP)
- for endpos < len(certBytes) && certBytes[endpos] != '\n' {
- endpos += 1
- }
- return endpos
- }
- func splitCert(certBytes []byte) [][]byte {
- ret := make([][]byte, 0)
- for {
- endpos := findCertEndIndex(certBytes)
- if endpos > 0 {
- ret = append(ret, certBytes[:endpos])
- for endpos < len(certBytes) && certBytes[endpos] != '-' {
- endpos += 1
- }
- if endpos < len(certBytes) {
- certBytes = certBytes[endpos:]
- } else {
- break
- }
- }
- }
- return ret
- }
- func InitTLSConfigWithCA(certFile, keyFile, caCertFile string) (*tls.Config, error) {
- cert, err := NewCert(certFile, keyFile, nil)
- if err != nil {
- return nil, err
- }
- cfg := &tls.Config{}
- cfg.RootCAs, err = NewCertPool([]string{caCertFile})
- if err != nil {
- return nil, err
- }
- cfg.Certificates = []tls.Certificate{*cert}
- return cfg, nil
- }
- // NewCertPool creates x509 certPool with provided CA files.
- func NewCertPool(CAFiles []string) (*x509.CertPool, error) {
- certPool := x509.NewCertPool()
- for _, CAFile := range CAFiles {
- pemByte, err := ioutil.ReadFile(CAFile)
- if err != nil {
- return nil, err
- }
- for {
- var block *pem.Block
- block, pemByte = pem.Decode(pemByte)
- if block == nil {
- break
- }
- cert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- return nil, err
- }
- certPool.AddCert(cert)
- }
- }
- return certPool, nil
- }
- // NewCert generates TLS cert by using the given cert,key and parse function.
- func NewCert(certfile, keyfile string, parseFunc func([]byte, []byte) (tls.Certificate, error)) (*tls.Certificate, error) {
- cert, err := ioutil.ReadFile(certfile)
- if err != nil {
- return nil, err
- }
- key, err := ioutil.ReadFile(keyfile)
- if err != nil {
- return nil, err
- }
- if parseFunc == nil {
- parseFunc = tls.X509KeyPair
- }
- tlsCert, err := parseFunc(cert, key)
- if err != nil {
- return nil, err
- }
- return &tlsCert, nil
- }
- func InitTLSConfig(certFile, keyFile string) (*tls.Config, error) {
- allCertPEM, err := ioutil.ReadFile(certFile)
- if err != nil {
- log.Errorf("read tls certfile fail %s", err)
- return nil, err
- }
- certPEMs := splitCert(allCertPEM)
- keyPEM, err := ioutil.ReadFile(keyFile)
- if err != nil {
- log.Errorf("read tls keyfile fail %s", err)
- return nil, err
- }
- cert, err := tls.X509KeyPair(certPEMs[0], keyPEM)
- if err != nil {
- return nil, err
- }
- caCertPool := x509.NewCertPool()
- for i := 1; i < len(certPEMs); i += 1 {
- caCertPool.AppendCertsFromPEM(certPEMs[i])
- }
- tlsConfig := &tls.Config{
- Certificates: []tls.Certificate{cert},
- RootCAs: caCertPool,
- }
- // tlsConfig.ServerName = "CN=*"
- tlsConfig.BuildNameToCertificate()
- return tlsConfig, nil
- }
- func InitTLSConfigByData(caCertBlock, certPEMBlock, keyPEMBlock []byte) (*tls.Config, error) {
- cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
- if err != nil {
- return nil, err
- }
- caCertPool := x509.NewCertPool()
- for {
- var block *pem.Block
- block, caCertBlock = pem.Decode(caCertBlock)
- if block == nil {
- break
- }
- caCert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- return nil, errors.Wrap(err, "parse caCert data")
- }
- caCertPool.AddCert(caCert)
- }
- tlsConfig := &tls.Config{
- Certificates: []tls.Certificate{cert},
- RootCAs: caCertPool,
- }
- tlsConfig.BuildNameToCertificate()
- return tlsConfig, nil
- }
|