Skip to content

Commit

Permalink
证书管理
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzeyi committed Nov 2, 2022
1 parent 0b7c76b commit c54d009
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 38 deletions.
48 changes: 34 additions & 14 deletions certs/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package certs

import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"github.com/eolinker/eosc/common/bean"
Expand All @@ -19,36 +20,55 @@ var errorCertificateNotExit = errors.New("not exist cert")

type ICert interface {
GetCertificateFunc(certs []*config.Certificate, dir string) func(info *tls.ClientHelloInfo) (*tls.Certificate, error)
SaveCert(certificate *tls.Certificate)
DelCert(cert *tls.Certificate)
SaveCert(workerId string, cert *tls.Certificate, certificate *x509.Certificate)
DelCert(workerId string)
}

type cert struct {
certFunc func(info *tls.ClientHelloInfo) (*tls.Certificate, error)
certs map[string]*tls.Certificate
lock *sync.RWMutex
certs map[string]*tls.Certificate
workerMaps map[string]map[string]*tls.Certificate
lock *sync.RWMutex
}

func (c *cert) DelCert(cert *tls.Certificate) {
func (c *cert) DelCert(workerId string) {
c.lock.Lock()
defer c.lock.Unlock()

if cert != nil {
delete(c.certs, cert.Leaf.Subject.CommonName)
for _, name := range cert.Leaf.DNSNames {
delete(c.certs, name)
delCerts := c.workerMaps[workerId]
delete(c.workerMaps, workerId)

//删除组装后的证书信息
for key, _ := range delCerts {
delete(c.certs, key)
}

//为防止把其他worker的证书也删除了,重新组装
for _, certs := range c.workerMaps {
for k, v := range certs {
c.certs[k] = v
}
}
}

func (c *cert) SaveCert(cert *tls.Certificate) {
func (c *cert) SaveCert(workerId string, cert *tls.Certificate, certificate *x509.Certificate) {
c.lock.Lock()
defer c.lock.Unlock()
c.certs[cert.Leaf.Subject.CommonName] = cert

for _, dnsName := range cert.Leaf.DNSNames {
c.certs[dnsName] = cert
//每次save都是覆盖操作
certsMap := make(map[string]*tls.Certificate)

certsMap[certificate.Subject.CommonName] = cert
for _, dnsName := range certificate.DNSNames {
certsMap[dnsName] = cert
}

c.workerMaps[workerId] = certsMap

//将最新的证书组装好
for k, v := range certsMap {
c.certs[k] = v
}

}

func (c *cert) GetCertificateFunc(certs []*config.Certificate, dir string) func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
Expand Down
15 changes: 8 additions & 7 deletions drivers/certs/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package certs

import (
"crypto/tls"
"crypto/x509"
"errors"
"github.com/eolinker/apinto/certs"
"github.com/eolinker/eosc"
Expand All @@ -23,8 +24,8 @@ func init() {

type IController interface {
Store(id string)
Del(id string, cert *tls.Certificate)
Save(cert *tls.Certificate)
Del(id string)
Save(id string, cert *tls.Certificate, certificate *x509.Certificate)
}
type Controller struct {
profession string
Expand All @@ -37,15 +38,15 @@ func (c *Controller) Store(id string) {
c.all[id] = struct{}{}
}

func (c *Controller) Del(id string, cert *tls.Certificate) {
func (c *Controller) Del(id string) {

delete(c.all, id)

c.iCerts.DelCert(cert)
c.iCerts.DelCert(id)
}

func (c *Controller) Save(cert *tls.Certificate) {
c.iCerts.SaveCert(cert)
func (c *Controller) Save(id string, cert *tls.Certificate, certificate *x509.Certificate) {
c.iCerts.SaveCert(id, cert, certificate)
}

func (c *Controller) ConfigType() reflect.Type {
Expand Down Expand Up @@ -76,7 +77,7 @@ func (c *Controller) Check(cfg interface{}) (profession, name, driver, desc stri
return
}

_, err = parseCert(conf.Key, conf.Pem)
_, _, err = parseCert(conf.Key, conf.Pem)
if err != nil {
return "", "", "", "", err
}
Expand Down
30 changes: 13 additions & 17 deletions drivers/certs/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,22 @@ type Worker struct {
drivers.WorkerBase
config *Config
isRunning bool
cert *tls.Certificate
}

func (w *Worker) Destroy() error {
controller.Del(w.Id(), w.cert)
controller.Del(w.Id())
return nil
}

func (w *Worker) Start() error {
w.isRunning = true

cert, err := parseCert(w.config.Key, w.config.Pem)
cert, certificate, err := parseCert(w.config.Key, w.config.Pem)
if err != nil {
return err
}

w.cert = cert

controller.Save(w.cert)
controller.Save(w.Id(), cert, certificate)

return nil
}
Expand All @@ -46,15 +43,15 @@ func (w *Worker) Reset(conf interface{}, _ map[eosc.RequireId]eosc.IWorker) erro

config := conf.(*Config)

cert, err := parseCert(config.Key, config.Pem)
cert, certificate, err := parseCert(config.Key, config.Pem)
if err != nil {
return err
}

w.config = config

if w.isRunning {
controller.Save(cert)
controller.Save(w.Id(), cert, certificate)
}

return nil
Expand All @@ -69,22 +66,22 @@ func (w *Worker) CheckSkill(string) bool {
return false
}

func parseCert(privateKey, pemValue string) (*tls.Certificate, error) {
func parseCert(privateKey, pemValue string) (*tls.Certificate, *x509.Certificate, error) {
var err error
privateKey, err = utils.B64Decode(privateKey)
if err != nil {
return nil, err
return nil, nil, err
}
pemValue, err = utils.B64Decode(pemValue)
if err != nil {
return nil, err
return nil, nil, err
}

var cert tls.Certificate
//获取下一个pem格式证书数据 -----BEGIN CERTIFICATE----- -----END CERTIFICATE-----
certDERBlock, restPEMBlock := pem.Decode([]byte(pemValue))
if certDERBlock == nil {
return nil, errors.New("证书解析失败")
return nil, nil, errors.New("证书解析失败")
}
//附加数字证书到返回
cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
Expand All @@ -98,7 +95,7 @@ func parseCert(privateKey, pemValue string) (*tls.Certificate, error) {
//解码pem格式的私钥------BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
keyDERBlock, _ := pem.Decode([]byte(privateKey))
if keyDERBlock == nil {
return nil, errors.New("证书解析失败")
return nil, nil, errors.New("证书解析失败")
}
var key interface{}
var errParsePK error
Expand All @@ -111,15 +108,14 @@ func parseCert(privateKey, pemValue string) (*tls.Certificate, error) {
}

if errParsePK != nil {
return nil, errors.New("证书解析失败")
return nil, nil, errors.New("证书解析失败")
} else {
cert.PrivateKey = key
}
//第一个叶子证书就是我们https中使用的证书
x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
if err != nil {
return nil, err
return nil, nil, err
}
cert.Leaf = x509Cert
return &cert, nil
return &cert, x509Cert, nil
}

0 comments on commit c54d009

Please sign in to comment.