github.com/percona/percona-xtradb-cluster-operator@v1.14.0/pkg/pxctls/pxctls.go (about) 1 package pxctls 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "crypto/rsa" 7 "crypto/x509" 8 "crypto/x509/pkix" 9 "encoding/pem" 10 "fmt" 11 "math/big" 12 "time" 13 ) 14 15 var validityNotAfter = time.Now().Add(time.Hour * 24 * 365) 16 17 // Issue returns CA certificate, TLS certificate and TLS private key 18 func Issue(hosts []string) (caCert []byte, tlsCert []byte, tlsKey []byte, err error) { 19 rsaBits := 2048 20 priv, err := rsa.GenerateKey(rand.Reader, rsaBits) 21 if err != nil { 22 return nil, nil, nil, fmt.Errorf("generate rsa key: %v", err) 23 } 24 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 25 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 26 if err != nil { 27 return nil, nil, nil, fmt.Errorf("generate serial number for root: %v", err) 28 } 29 subject := pkix.Name{ 30 Organization: []string{"Root CA"}, 31 } 32 issuer := pkix.Name{ 33 Organization: []string{"Root CA"}, 34 } 35 caTemplate := x509.Certificate{ 36 SerialNumber: serialNumber, 37 Subject: subject, 38 NotBefore: time.Now(), 39 NotAfter: validityNotAfter, 40 KeyUsage: x509.KeyUsageCertSign, 41 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, 42 BasicConstraintsValid: true, 43 IsCA: true, 44 } 45 46 derBytes, err := x509.CreateCertificate(rand.Reader, &caTemplate, &caTemplate, &priv.PublicKey, priv) 47 if err != nil { 48 return nil, nil, nil, fmt.Errorf("generate CA certificate: %v", err) 49 } 50 certOut := &bytes.Buffer{} 51 err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 52 if err != nil { 53 return nil, nil, nil, fmt.Errorf("encode CA certificate: %v", err) 54 } 55 cert := certOut.Bytes() 56 57 serialNumber, err = rand.Int(rand.Reader, serialNumberLimit) 58 if err != nil { 59 return nil, nil, nil, fmt.Errorf("generate serial number for client: %v", err) 60 } 61 subject = pkix.Name{ 62 Organization: []string{"PXC"}, 63 } 64 tlsTemplate := x509.Certificate{ 65 SerialNumber: serialNumber, 66 Subject: subject, 67 Issuer: issuer, 68 NotBefore: time.Now(), 69 NotAfter: validityNotAfter, 70 DNSNames: hosts, 71 KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, 72 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, 73 BasicConstraintsValid: true, 74 IsCA: false, 75 } 76 clientKey, err := rsa.GenerateKey(rand.Reader, 2048) 77 if err != nil { 78 return nil, nil, nil, fmt.Errorf("generate client key: %v", err) 79 } 80 tlsDerBytes, err := x509.CreateCertificate(rand.Reader, &tlsTemplate, &caTemplate, &clientKey.PublicKey, priv) 81 if err != nil { 82 return nil, nil, nil, err 83 } 84 tlsCertOut := &bytes.Buffer{} 85 err = pem.Encode(tlsCertOut, &pem.Block{Type: "CERTIFICATE", Bytes: tlsDerBytes}) 86 if err != nil { 87 return nil, nil, nil, fmt.Errorf("encode TLS certificate: %v", err) 88 } 89 tlsCert = tlsCertOut.Bytes() 90 91 keyOut := &bytes.Buffer{} 92 block := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(clientKey)} 93 err = pem.Encode(keyOut, block) 94 if err != nil { 95 return nil, nil, nil, fmt.Errorf("encode RSA private key: %v", err) 96 } 97 privKey := keyOut.Bytes() 98 99 return cert, tlsCert, privKey, nil 100 }