github.com/symfony-cli/symfony-cli@v0.0.0-20240514161054-ece2df437dfa/local/proxy/cert_store.go (about) 1 /* 2 * Copyright (c) 2021-present Fabien Potencier <fabien@symfony.com> 3 * 4 * This file is part of Symfony CLI project 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as 8 * published by the Free Software Foundation, either version 3 of the 9 * License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package proxy 21 22 import ( 23 "crypto/tls" 24 "sync" 25 26 "github.com/hashicorp/golang-lru/arc/v2" 27 "github.com/symfony-cli/cert" 28 ) 29 30 type certStore struct { 31 proxyCfg *Config 32 ca *cert.CA 33 lock sync.Mutex 34 cache *arc.ARCCache[string, tls.Certificate] 35 } 36 37 // newCertStore creates a store to keep SSL certificates in memory 38 func (p *Proxy) newCertStore(ca *cert.CA) *certStore { 39 cache, _ := arc.NewARC[string, tls.Certificate](1024) 40 return &certStore{ 41 proxyCfg: p.Config, 42 ca: ca, 43 cache: cache, 44 } 45 } 46 47 // getCertificate returns a valid certificate for the given domain name 48 func (c *certStore) getCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { 49 c.lock.Lock() 50 defer c.lock.Unlock() 51 name := c.proxyCfg.NormalizeDomain(clientHello.ServerName) 52 if val, ok := c.cache.Get(name); ok { 53 cert := val 54 return &cert, nil 55 } 56 cert, err := c.ca.CreateCert([]string{name}) 57 if err != nil { 58 return nil, err 59 } 60 c.cache.Add(name, cert) 61 return &cert, nil 62 }