github.com/openshift/installer@v1.4.17/pkg/asset/tls/certkey.go (about) 1 package tls 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rsa" 7 "crypto/x509" 8 "os" 9 10 "github.com/pkg/errors" 11 "github.com/sirupsen/logrus" 12 13 "github.com/openshift/installer/pkg/asset" 14 ) 15 16 // CertInterface contains cert. 17 type CertInterface interface { 18 // Cert returns the certificate. 19 Cert() []byte 20 } 21 22 // CertKeyInterface contains a private key and the associated cert. 23 type CertKeyInterface interface { 24 CertInterface 25 // Key returns the private key. 26 Key() []byte 27 } 28 29 // CertKey contains the private key and the cert. 30 type CertKey struct { 31 CertRaw []byte 32 KeyRaw []byte 33 FileList []*asset.File 34 } 35 36 // Cert returns the certificate. 37 func (c *CertKey) Cert() []byte { 38 return c.CertRaw 39 } 40 41 // Key returns the private key. 42 func (c *CertKey) Key() []byte { 43 return c.KeyRaw 44 } 45 46 // Files returns the files generated by the asset. 47 func (c *CertKey) Files() []*asset.File { 48 return c.FileList 49 } 50 51 // CertFile returns the certificate file. 52 func (c *CertKey) CertFile() *asset.File { 53 return c.FileList[1] 54 } 55 56 func (c *CertKey) generateFiles(filenameBase string) { 57 c.FileList = []*asset.File{ 58 { 59 Filename: assetFilePath(filenameBase + ".key"), 60 Data: c.KeyRaw, 61 }, 62 { 63 Filename: assetFilePath(filenameBase + ".crt"), 64 Data: c.CertRaw, 65 }, 66 } 67 } 68 69 // Load is a no-op because TLS assets are not written to disk. 70 func (c *CertKey) Load(asset.FileFetcher) (bool, error) { 71 return false, nil 72 } 73 74 func (c *CertKey) loadCertKey(f asset.FileFetcher, filenameBase string) (bool, error) { 75 if os.Getenv("OPENSHIFT_INSTALL_LOAD_CLUSTER_CERTS") != "true" { 76 return c.Load(f) 77 } 78 79 loadFile := func(suffix string) (*asset.File, error) { 80 file, err := f.FetchByName(assetFilePath(filenameBase + suffix)) 81 if err != nil { 82 if os.IsNotExist(err) { 83 return nil, nil 84 } 85 return nil, err 86 } 87 return file, err 88 } 89 90 key, err := loadFile(".key") 91 if key == nil { 92 return false, err 93 } 94 95 cert, err := loadFile(".crt") 96 if cert == nil { 97 return false, err 98 } 99 100 c.KeyRaw = key.Data 101 c.CertRaw = cert.Data 102 c.FileList = []*asset.File{key, cert} 103 104 return true, nil 105 } 106 107 // AppendParentChoice dictates whether the parent's cert is to be added to the 108 // cert. 109 type AppendParentChoice bool 110 111 const ( 112 // AppendParent indicates that the parent's cert should be added. 113 AppendParent AppendParentChoice = true 114 // DoNotAppendParent indicates that the parent's cert should not be added. 115 DoNotAppendParent AppendParentChoice = false 116 ) 117 118 // SignedCertKey contains the private key and the cert that's 119 // signed by the parent CA. 120 type SignedCertKey struct { 121 CertKey 122 } 123 124 // Generate generates a cert/key pair signed by the specified parent CA. 125 func (c *SignedCertKey) Generate(_ context.Context, 126 cfg *CertCfg, 127 parentCA CertKeyInterface, 128 filenameBase string, 129 appendParent AppendParentChoice, 130 ) error { 131 var key *rsa.PrivateKey 132 var crt *x509.Certificate 133 var err error 134 135 caKey, err := PemToPrivateKey(parentCA.Key()) 136 if err != nil { 137 logrus.Debugf("Failed to parse RSA private key: %s", err) 138 return errors.Wrap(err, "failed to parse rsa private key") 139 } 140 141 caCert, err := PemToCertificate(parentCA.Cert()) 142 if err != nil { 143 logrus.Debugf("Failed to parse x509 certificate: %s", err) 144 return errors.Wrap(err, "failed to parse x509 certificate") 145 } 146 147 key, crt, err = GenerateSignedCertificate(caKey, caCert, cfg) 148 if err != nil { 149 logrus.Debugf("Failed to generate signed cert/key pair: %s", err) 150 return errors.Wrap(err, "failed to generate signed cert/key pair") 151 } 152 153 c.KeyRaw = PrivateKeyToPem(key) 154 c.CertRaw = CertToPem(crt) 155 156 if appendParent { 157 c.CertRaw = bytes.Join([][]byte{c.CertRaw, CertToPem(caCert)}, []byte("\n")) 158 } 159 160 c.generateFiles(filenameBase) 161 162 return nil 163 } 164 165 // SelfSignedCertKey contains the private key and the cert that's self-signed. 166 type SelfSignedCertKey struct { 167 CertKey 168 } 169 170 // Generate generates a cert/key pair signed by the specified parent CA. 171 func (c *SelfSignedCertKey) Generate(_ context.Context, 172 cfg *CertCfg, 173 filenameBase string, 174 ) error { 175 key, crt, err := GenerateSelfSignedCertificate(cfg) 176 if err != nil { 177 return errors.Wrap(err, "failed to generate self-signed cert/key pair") 178 } 179 180 c.KeyRaw = PrivateKeyToPem(key) 181 c.CertRaw = CertToPem(crt) 182 183 c.generateFiles(filenameBase) 184 185 return nil 186 }