github.com/secure-build/gitlab-runner@v12.5.0+incompatible/helpers/certificate/x509.go (about)

     1  package certificate
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/rsa"
     6  	"crypto/tls"
     7  	"crypto/x509"
     8  	"crypto/x509/pkix"
     9  	"encoding/pem"
    10  	"errors"
    11  	"math/big"
    12  	"net"
    13  	"time"
    14  )
    15  
    16  const (
    17  	x509CertificatePrivateKeyBits = 2048
    18  	x509CertificateExpiryInYears  = 2
    19  	x509CertificateSerialNumber   = 1
    20  	x509CertificateOrganization   = "GitLab Runner"
    21  )
    22  
    23  type X509Generator struct{}
    24  
    25  func (c X509Generator) Generate(host string) (tls.Certificate, []byte, error) {
    26  	priv, err := rsa.GenerateKey(rand.Reader, x509CertificatePrivateKeyBits)
    27  	if err != nil {
    28  		return tls.Certificate{}, []byte{}, err
    29  	}
    30  
    31  	template := x509.Certificate{
    32  		SerialNumber: big.NewInt(x509CertificateSerialNumber),
    33  		NotBefore:    time.Now(),
    34  		NotAfter:     time.Now().AddDate(x509CertificateExpiryInYears, 0, 0),
    35  		Subject: pkix.Name{
    36  			Organization: []string{x509CertificateOrganization},
    37  		},
    38  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageDataEncipherment,
    39  		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
    40  		BasicConstraintsValid: true,
    41  	}
    42  
    43  	if ip := net.ParseIP(host); ip != nil {
    44  		template.IPAddresses = append(template.IPAddresses, ip)
    45  	} else {
    46  		template.DNSNames = append(template.DNSNames, host)
    47  	}
    48  
    49  	publicKeyBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv)
    50  	if err != nil {
    51  		return tls.Certificate{}, []byte{}, errors.New("failed to create certificate")
    52  	}
    53  
    54  	publicKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: publicKeyBytes})
    55  	privateKeyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
    56  
    57  	parsedCertificate, err := tls.X509KeyPair(publicKeyPEM, privateKeyPEM)
    58  	if err != nil {
    59  		return tls.Certificate{}, []byte{}, err
    60  	}
    61  
    62  	return parsedCertificate, publicKeyPEM, nil
    63  }