selfsigned.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package cert
  2. import (
  3. "crypto"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "crypto/x509/pkix"
  8. "encoding/pem"
  9. "errors"
  10. "fmt"
  11. "math"
  12. "math/big"
  13. "net"
  14. "time"
  15. "k8s.io/client-go/util/cert"
  16. "k8s.io/client-go/util/keyutil"
  17. )
  18. type SelfSignedCertGenerator struct {
  19. caKey []byte
  20. caCert []byte
  21. }
  22. var _ CertGenerator = &SelfSignedCertGenerator{}
  23. // SetCA sets the PEM-encoded CA private key and CA cert for signing the generated serving cert.
  24. func (cp *SelfSignedCertGenerator) SetCA(caKey, caCert []byte) {
  25. cp.caKey = caKey
  26. cp.caCert = caCert
  27. }
  28. // Generate creates and returns a CA certificate, certificate and
  29. // key for the server or client. Key and Cert are used by the server or client
  30. // to establish trust for others, CA certificate is used by the
  31. // client or server to verify the other's authentication chain.
  32. // The cert will be valid for 365 days.
  33. func (cp *SelfSignedCertGenerator) Generate(commonName string) (*Artifacts, error) {
  34. var signingKey *rsa.PrivateKey
  35. var signingCert *x509.Certificate
  36. var valid bool
  37. var err error
  38. valid, signingKey, signingCert = cp.validCACert()
  39. if !valid {
  40. signingKey, err = NewPrivateKey()
  41. if err != nil {
  42. return nil, fmt.Errorf("failed to create the CA private key: %v", err)
  43. }
  44. signingCert, err = cert.NewSelfSignedCACert(cert.Config{CommonName: commonName}, signingKey)
  45. if err != nil {
  46. return nil, fmt.Errorf("failed to create the CA cert: %v", err)
  47. }
  48. }
  49. hostIP := net.ParseIP(commonName)
  50. var altIPs []net.IP
  51. DNSNames := []string{"localhost"}
  52. if hostIP.To4() != nil {
  53. altIPs = append(altIPs, hostIP.To4())
  54. } else {
  55. DNSNames = append(DNSNames, commonName)
  56. }
  57. key, err := NewPrivateKey()
  58. if err != nil {
  59. return nil, fmt.Errorf("failed to create the private key: %v", err)
  60. }
  61. signedCert, err := NewSignedCert(
  62. cert.Config{
  63. CommonName: commonName,
  64. Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
  65. AltNames: cert.AltNames{IPs: altIPs, DNSNames: DNSNames},
  66. },
  67. key, signingCert, signingKey,
  68. )
  69. if err != nil {
  70. return nil, fmt.Errorf("failed to create the cert: %v", err)
  71. }
  72. return &Artifacts{
  73. Key: EncodePrivateKeyPEM(key),
  74. Cert: EncodeCertPEM(signedCert),
  75. CAKey: EncodePrivateKeyPEM(signingKey),
  76. CACert: EncodeCertPEM(signingCert),
  77. }, nil
  78. }
  79. func (cp *SelfSignedCertGenerator) validCACert() (bool, *rsa.PrivateKey, *x509.Certificate) {
  80. if !ValidCACert(cp.caKey, cp.caCert, cp.caCert, "",
  81. time.Now().AddDate(1, 0, 0)) {
  82. return false, nil, nil
  83. }
  84. var ok bool
  85. key, err := keyutil.ParsePrivateKeyPEM(cp.caKey)
  86. if err != nil {
  87. return false, nil, nil
  88. }
  89. privateKey, ok := key.(*rsa.PrivateKey)
  90. if !ok {
  91. return false, nil, nil
  92. }
  93. certs, err := cert.ParseCertsPEM(cp.caCert)
  94. if err != nil {
  95. return false, nil, nil
  96. }
  97. if len(certs) != 1 {
  98. return false, nil, nil
  99. }
  100. return true, privateKey, certs[0]
  101. }
  102. // NewPrivateKey creates an RSA private key
  103. func NewPrivateKey() (*rsa.PrivateKey, error) {
  104. return rsa.GenerateKey(rand.Reader, 2048)
  105. }
  106. // NewSignedCert creates a signed certificate using the given CA certificate and key
  107. func NewSignedCert(cfg cert.Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
  108. serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
  109. if err != nil {
  110. return nil, err
  111. }
  112. if len(cfg.CommonName) == 0 {
  113. return nil, errors.New("must specify a CommonName")
  114. }
  115. if len(cfg.Usages) == 0 {
  116. return nil, errors.New("must specify at least one ExtKeyUsage")
  117. }
  118. certTmpl := x509.Certificate{
  119. Subject: pkix.Name{
  120. CommonName: cfg.CommonName,
  121. Organization: cfg.Organization,
  122. },
  123. DNSNames: cfg.AltNames.DNSNames,
  124. IPAddresses: cfg.AltNames.IPs,
  125. SerialNumber: serial,
  126. NotBefore: caCert.NotBefore,
  127. NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10).UTC(),
  128. KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
  129. ExtKeyUsage: cfg.Usages,
  130. }
  131. certDERBytes, err := x509.CreateCertificate(rand.Reader, &certTmpl, caCert, key.Public(), caKey)
  132. if err != nil {
  133. return nil, err
  134. }
  135. return x509.ParseCertificate(certDERBytes)
  136. }
  137. // EncodePrivateKeyPEM returns PEM-encoded private key data
  138. func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
  139. block := pem.Block{
  140. Type: keyutil.RSAPrivateKeyBlockType,
  141. Bytes: x509.MarshalPKCS1PrivateKey(key),
  142. }
  143. return pem.EncodeToMemory(&block)
  144. }
  145. // EncodeCertPEM returns PEM-encoded certificate data
  146. func EncodeCertPEM(ct *x509.Certificate) []byte {
  147. block := pem.Block{
  148. Type: cert.CertificateBlockType,
  149. Bytes: ct.Raw,
  150. }
  151. return pem.EncodeToMemory(&block)
  152. }