Skip to content

Commit

Permalink
remove tyk/certs as import and uses local interface
Browse files Browse the repository at this point in the history
Change removes TykTechnologies/tyk/certs as import and uses locally
defined interface. This change needs expanding of Tyk Gateway/Dashboard
certificate manager with new function ListAny.
  • Loading branch information
mitjaziv committed Jul 19, 2023
1 parent 7af0945 commit b6c0622
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 937 deletions.
206 changes: 206 additions & 0 deletions cert/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package cert

import (
"crypto"
"crypto/ecdsa"
"crypto/rsa"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/hex"
"encoding/pem"
"errors"
"strings"
"time"

"github.com/patrickmn/go-cache"
"github.com/sirupsen/logrus"

"github.com/TykTechnologies/tyk-identity-broker/providers"
)

const (
cacheDefaultTTL = 300 // 5 minutes.
cacheCleanInterval = 600 // 10 minutes.
)

type (
// CertificateManager interface defines public certificate manager functions.
CertificateManager interface {
ListAny(ids []string) []*tls.Certificate
}

// manager implements CertificateManager interface.
manager struct {
store providers.FileLoader
logger *logrus.Entry
cache *cache.Cache
}
)

var (
logger *logrus.Logger
)

// NewCertificateManager func creates and returns default Tyk Identity Broker certificate manager,
// with FileLoader storage.
func NewCertificateManager() CertificateManager {
if logger == nil {
logger = logrus.New()
}

expirationInterval := time.Duration(cacheDefaultTTL) * time.Second
cleanupInterval := time.Duration(cacheCleanInterval) * time.Second

m := manager{
store: providers.FileLoader{},
logger: logger.WithFields(logrus.Fields{"prefix": "cert_storage"}),
cache: cache.New(expirationInterval, cleanupInterval),
}

return &m
}

// ListAny func returns list of all requested certificates of any kind.
func (m *manager) ListAny(ids []string) []*tls.Certificate {
certs := make([]*tls.Certificate, 0)

for _, id := range ids {
// Read certificate from cache.
if cert, found := m.cache.Get(id); found {
certs = append(certs, cert.(*tls.Certificate))

continue
}

// Read certificate from FileLoader.
val, err := m.store.GetKey("raw-" + id)

cert, err := parsePEMCertificate([]byte(val), "")
if err != nil {
m.logger.Error("error while parsing certificate: ", id, " ", err)
m.logger.Debug("failed certificate: ", val)

certs = append(certs, nil)

continue
}

// Write certificate to cache.
m.cache.Set(id, cert, cache.DefaultExpiration)

certs = append(certs, cert)
}

return certs
}

func parsePEM(data []byte, secret string) ([]*pem.Block, error) {
var pemBlocks []*pem.Block

for {
var block *pem.Block
block, data = pem.Decode(data)

if block == nil {
break
}

if x509.IsEncryptedPEMBlock(block) {
var err error
block.Bytes, err = x509.DecryptPEMBlock(block, []byte(secret))
block.Headers = nil
block.Type = strings.Replace(block.Type, "ENCRYPTED ", "", 1)

if err != nil {
return nil, err
}
}

pemBlocks = append(pemBlocks, block)
}

return pemBlocks, nil
}

func parsePEMCertificate(data []byte, secret string) (*tls.Certificate, error) {
var cert tls.Certificate

blocks, err := parsePEM(data, secret)
if err != nil {
return nil, err
}

var certID string

for _, block := range blocks {
if block.Type == "CERTIFICATE" {
certID = hexSHA256(block.Bytes)

cert.Certificate = append(cert.Certificate, block.Bytes)

continue
}

if strings.HasSuffix(block.Type, "PRIVATE KEY") {
cert.PrivateKey, err = parsePrivateKey(block.Bytes)
if err != nil {
return nil, err
}
continue
}

if block.Type == "PUBLIC KEY" {
// Create a dummny cert just for listing purpose
cert.Certificate = append(cert.Certificate, block.Bytes)
cert.Leaf = &x509.Certificate{Subject: pkix.Name{CommonName: "Public Key: " + hexSHA256(block.Bytes)}}
}
}

if len(cert.Certificate) == 0 {
return nil, errors.New("can't find CERTIFICATE block")
}

if cert.Leaf == nil {
cert.Leaf, err = x509.ParseCertificate(cert.Certificate[0])

if err != nil {
return nil, err
}
}

// Cache certificate fingerprint
cert.Leaf.Extensions = append([]pkix.Extension{{
Value: []byte(certID),
}}, cert.Leaf.Extensions...)

return &cert, nil
}

func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
return key, nil
}

if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
switch key := key.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey:
return key, nil
default:
return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
}
}

if key, err := x509.ParseECPrivateKey(der); err == nil {
return key, nil
}

return nil, errors.New("tls: failed to parse private key")
}

func hexSHA256(cert []byte) string {
certSHA := sha256.Sum256(cert)

return hex.EncodeToString(certSHA[:])
}
52 changes: 2 additions & 50 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.19
require (
github.com/Jeffail/gabs v1.4.0
github.com/TykTechnologies/storage v1.0.5
github.com/TykTechnologies/tyk v1.9.2-0.20230530103800-06c018df3563
github.com/crewjam/saml v0.4.12
github.com/go-ldap/ldap/v3 v3.2.3
github.com/go-redis/redis/v8 v8.11.5
Expand All @@ -15,6 +14,7 @@ require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/markbates/goth v1.64.2
github.com/matryer/is v1.4.0
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.1
github.com/x-cray/logrus-prefixed-formatter v0.5.2
Expand All @@ -24,87 +24,39 @@ require (

require (
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Shopify/sarama v1.29.1 // indirect
github.com/TykTechnologies/gojsonschema v0.0.0-20170222154038-dcb3e4bb7990 // indirect
github.com/TykTechnologies/graphql-go-tools v1.6.2-0.20230511060858-40d3318e20b1 // indirect
github.com/TykTechnologies/murmur3 v0.0.0-20230310161213-aad17efd5632 // indirect
github.com/beevik/etree v1.1.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/clbanning/mxj v1.8.4 // indirect
github.com/crewjam/httperr v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/eapache/go-resiliency v1.2.0 // indirect
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
github.com/eapache/queue v1.1.0 // indirect
github.com/eclipse/paho.mqtt.golang v1.2.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.1 // indirect
github.com/golang-jwt/jwt/v4 v4.4.3 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.2 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
github.com/jcmturner/gofork v1.0.0 // indirect
github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
github.com/jensneuse/abstractlogger v0.0.4 // indirect
github.com/jensneuse/byte-template v0.0.0-20200214152254-4f3cf06e5c68 // indirect
github.com/jensneuse/pipeline v0.0.0-20200117120358-9fb4de085cd6 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/lonelycode/go-uuid v0.0.0-20141202165402-ed3ca8a15a93 // indirect
github.com/lonelycode/osin v0.0.0-20160423095202-da239c9dacb6 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c // indirect
github.com/nats-io/nats.go v1.11.1-0.20210623165838-4b75fc59ae30 // indirect
github.com/nats-io/nkeys v0.3.0 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pierrec/lz4 v2.6.0+incompatible // indirect
github.com/onsi/gomega v1.20.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmylund/go-cache v2.1.0+incompatible // indirect
github.com/qri-io/jsonpointer v0.1.1 // indirect
github.com/qri-io/jsonschema v0.2.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/russellhaering/goxmldsig v1.2.0 // indirect
github.com/tidwall/gjson v1.11.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/sjson v1.0.4 // indirect
github.com/uber/jaeger-client-go v2.30.1-0.20220110192849-8d8e8fcfd04d+incompatible // indirect
github.com/uber/jaeger-lib v2.4.2-0.20210604143007-135cf5605a6d+incompatible // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.mongodb.org/mongo-driver v1.11.2 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.18.1 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/appengine v1.6.6 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
Expand Down
Loading

0 comments on commit b6c0622

Please sign in to comment.