github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/xcrypto/xcrypto.go (about) 1 package xcrypto 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "crypto/rsa" 7 "crypto/tls" 8 "crypto/x509" 9 "crypto/x509/pkix" 10 "encoding/pem" 11 "io/ioutil" 12 "math/big" 13 "net" 14 "strings" 15 "time" 16 ) 17 18 func generateRSA(isCA bool, template, parent *x509.Certificate, rootKey *rsa.PrivateKey, commonName string, dnsNames []string, ipAddresses []net.IP, bits int) (cert *x509.Certificate, privKey *rsa.PrivateKey, certPEM, privPEM []byte, err error) { 19 privKey, err = rsa.GenerateKey(rand.Reader, bits) 20 if err != nil { 21 return 22 } 23 24 if parent == nil { 25 parent = template 26 } 27 if rootKey == nil { 28 rootKey = privKey 29 } 30 certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, &privKey.PublicKey, rootKey) 31 if err != nil { 32 return 33 } 34 cert, err = x509.ParseCertificate(certBytes) 35 if err != nil { 36 return 37 } 38 39 certBuffer := &bytes.Buffer{} 40 certBlock := &pem.Block{Type: "CERTIFICATE", Bytes: certBytes} 41 pem.Encode(certBuffer, certBlock) 42 certPEM = certBuffer.Bytes() 43 44 privBuffer := &bytes.Buffer{} 45 privBlock := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privKey)} 46 pem.Encode(privBuffer, privBlock) 47 privPEM = privBuffer.Bytes() 48 return 49 } 50 51 func GenerateRootCA(org []string, name string, bits int) (cert *x509.Certificate, privKey *rsa.PrivateKey, certPEM, privPEM []byte, err error) { 52 template := &x509.Certificate{ 53 SerialNumber: big.NewInt(1), 54 Subject: pkix.Name{ 55 Organization: org, 56 CommonName: name, 57 }, 58 NotBefore: time.Now(), 59 NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10), 60 KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature, 61 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, 62 BasicConstraintsValid: true, 63 IsCA: true, 64 MaxPathLen: 2, 65 } 66 cert, privKey, certPEM, privPEM, err = generateRSA(true, template, nil, nil, name, nil, nil, bits) 67 return 68 } 69 70 // func GenerateDistCA(parent *x509.Certificate, rootKey *rsa.PrivateKey, name string, bits int) (cert *x509.Certificate, privKey *rsa.PrivateKey, certPEM, privPEM []byte, err error) { 71 // cert, privKey, certPEM, privPEM, err = generateRSA(true, parent, rootKey, name, nil, nil, bits) 72 // return 73 // } 74 75 func GenerateCert(parent *x509.Certificate, rootKey *rsa.PrivateKey, ext []x509.ExtKeyUsage, org []string, commonName string, dnsNames []string, ipAddresses []net.IP, bits int) (cert *x509.Certificate, privKey *rsa.PrivateKey, certPEM, privPEM []byte, err error) { 76 template := &x509.Certificate{ 77 SerialNumber: big.NewInt(1), 78 Subject: pkix.Name{ 79 Organization: org, 80 CommonName: commonName, 81 }, 82 NotBefore: time.Now(), 83 NotAfter: time.Now().Add(time.Hour * 24 * 365 * 10), 84 KeyUsage: x509.KeyUsageDigitalSignature, 85 ExtKeyUsage: ext, 86 BasicConstraintsValid: true, 87 IsCA: false, 88 DNSNames: dnsNames, 89 IPAddresses: ipAddresses, 90 } 91 cert, privKey, certPEM, privPEM, err = generateRSA(false, template, parent, rootKey, commonName, dnsNames, ipAddresses, bits) 92 return 93 } 94 95 // GenerateWeb will generate web cert 96 func GenerateWeb(parent *x509.Certificate, rootKey *rsa.PrivateKey, client bool, org, domain, ip string, bits int) (cert tls.Certificate, certPEM, privPEM []byte, err error) { 97 domains := strings.Split(domain, ",") 98 ipAddress := []net.IP{} 99 if len(ip) > 0 { 100 ips := strings.Split(ip, ",") 101 for _, v := range ips { 102 ipAddress = append(ipAddress, net.ParseIP(v)) 103 } 104 } 105 keyUsage := []x509.ExtKeyUsage{} 106 if client { 107 keyUsage = append(keyUsage, x509.ExtKeyUsageClientAuth) 108 } else { 109 keyUsage = append(keyUsage, x509.ExtKeyUsageServerAuth) 110 } 111 _, _, certPEM, privPEM, err = GenerateCert(parent, rootKey, keyUsage, []string{org}, domain, domains, ipAddress, bits) 112 if err == nil { 113 cert, err = tls.X509KeyPair(certPEM, privPEM) 114 } 115 return 116 } 117 118 func GenerateWebServerClient(org string, ca, domain, ip string, bits int) ( 119 rootCert *x509.Certificate, rootKey *rsa.PrivateKey, rootCertPEM, rootKeyPEM []byte, 120 server tls.Certificate, serverCertPEM, serverKeyPEM []byte, 121 client tls.Certificate, clientCertPEM, clientKeyPEM []byte, 122 err error, 123 ) { 124 rootCert, rootKey, rootCertPEM, rootKeyPEM, err = GenerateRootCA([]string{org}, ca, bits) 125 if err != nil { 126 return 127 } 128 server, serverCertPEM, serverKeyPEM, err = GenerateWeb(rootCert, rootKey, false, org, domain, ip, bits) 129 if err != nil { 130 return 131 } 132 client, clientCertPEM, clientKeyPEM, err = GenerateWeb(rootCert, rootKey, true, org, domain, ip, bits) 133 return 134 } 135 136 func LoadX509KeyPair(certFile, keyFile string) (cert *x509.Certificate, priv *rsa.PrivateKey, err error) { 137 certPEM, err := ioutil.ReadFile(certFile) 138 if err != nil { 139 return 140 } 141 keyPEM, err := ioutil.ReadFile(keyFile) 142 if err != nil { 143 return 144 } 145 // 146 certBlock, _ := pem.Decode(certPEM) 147 keyBlock, _ := pem.Decode(keyPEM) 148 cert, err = x509.ParseCertificate(certBlock.Bytes) 149 if err == nil { 150 priv, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes) 151 } 152 return 153 }