istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/test/csrctrl/signer/signer.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package signer implements a CA signer that uses keys stored on local disk. 16 package signer 17 18 import ( 19 "bytes" 20 "crypto/x509" 21 "encoding/pem" 22 "fmt" 23 "time" 24 25 capi "k8s.io/api/certificates/v1" 26 27 "istio.io/istio/pkg/test/csrctrl/authority" 28 "istio.io/istio/security/pkg/pki/util" 29 ) 30 31 type Signer struct { 32 caProvider *caProvider 33 CertTTL time.Duration 34 } 35 36 func NewSigner(signerRoot, signerName string, certificateDuration time.Duration) (*Signer, error) { 37 caProvider, err := newCAProvider(signerRoot, signerName) 38 if err != nil { 39 return nil, err 40 } 41 42 ret := &Signer{ 43 caProvider: caProvider, 44 CertTTL: certificateDuration, 45 } 46 return ret, nil 47 } 48 49 func (s *Signer) Sign(x509cr *x509.CertificateRequest, usages []capi.KeyUsage, requestedLifetime time.Duration, appendRootCert bool) ([]byte, error) { 50 currCA, err := s.caProvider.currentCA() 51 if err != nil { 52 return nil, err 53 } 54 der, err := currCA.Sign(x509cr.Raw, authority.PermissiveSigningPolicy{ 55 TTL: requestedLifetime, 56 Usages: usages, 57 }) 58 if err != nil { 59 return nil, err 60 } 61 62 _, err = x509.ParseCertificate(der) 63 if err != nil { 64 return nil, fmt.Errorf("error decoding DER certificate bytes: %s", err.Error()) 65 } 66 67 pemBytes := bytes.NewBuffer([]byte{}) 68 err = pem.Encode(pemBytes, &pem.Block{Type: "CERTIFICATE", Bytes: der}) 69 if err != nil { 70 return nil, fmt.Errorf("error encoding certificate PEM: %s", err.Error()) 71 } 72 73 intermediateCerts, err := util.AppendRootCerts(pemBytes.Bytes(), s.caProvider.caIntermediate.CertFile) 74 if err != nil { 75 return nil, fmt.Errorf("failed to append intermediate certificates (%v)", err) 76 } 77 if appendRootCert { 78 rootCerts, err := util.AppendRootCerts(intermediateCerts, s.caProvider.caLoader.CertFile) 79 if err != nil { 80 return nil, fmt.Errorf("failed to append root certificates (%v)", err) 81 } 82 return rootCerts, nil 83 } 84 return intermediateCerts, nil 85 } 86 87 func (s *Signer) GetRootCerts() string { 88 return s.caProvider.caLoader.CertFile 89 }