github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/util/tls/tls.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/util/tls/tls.go 14 15 package tls 16 17 import ( 18 "bytes" 19 "crypto/ecdsa" 20 "crypto/elliptic" 21 "crypto/rand" 22 "crypto/tls" 23 "crypto/x509" 24 "crypto/x509/pkix" 25 "encoding/pem" 26 "math/big" 27 "net" 28 "time" 29 ) 30 31 func Certificate(host ...string) (tls.Certificate, error) { 32 priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) 33 if err != nil { 34 return tls.Certificate{}, err 35 } 36 37 notBefore := time.Now() 38 notAfter := notBefore.Add(time.Hour * 24 * 365) 39 40 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 41 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 42 if err != nil { 43 return tls.Certificate{}, err 44 } 45 46 template := x509.Certificate{ 47 SerialNumber: serialNumber, 48 Subject: pkix.Name{ 49 Organization: []string{"Acme Co"}, 50 }, 51 NotBefore: notBefore, 52 NotAfter: notAfter, 53 54 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 55 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 56 BasicConstraintsValid: true, 57 } 58 59 for _, h := range host { 60 if ip := net.ParseIP(h); ip != nil { 61 template.IPAddresses = append(template.IPAddresses, ip) 62 } else { 63 template.DNSNames = append(template.DNSNames, h) 64 } 65 } 66 67 template.IsCA = true 68 template.KeyUsage |= x509.KeyUsageCertSign 69 70 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 71 if err != nil { 72 return tls.Certificate{}, err 73 } 74 75 // create public key 76 certOut := bytes.NewBuffer(nil) 77 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 78 79 // create private key 80 keyOut := bytes.NewBuffer(nil) 81 b, err := x509.MarshalECPrivateKey(priv) 82 if err != nil { 83 return tls.Certificate{}, err 84 } 85 pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}) 86 87 return tls.X509KeyPair(certOut.Bytes(), keyOut.Bytes()) 88 }