| 152 | } |
| 153 | |
| 154 | func makeCert( |
| 155 | parent *tls.Certificate, |
| 156 | name string, |
| 157 | ) (*tls.Certificate, error) { |
| 158 | |
| 159 | // start by generating private key |
| 160 | privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 161 | if err != nil { |
| 162 | return nil, fmt.Errorf("failed to generate private key: %v", err) |
| 163 | } |
| 164 | |
| 165 | // create certificate structure with proper values |
| 166 | notBefore := time.Now() |
| 167 | notAfter := notBefore.Add(365 * 24 * time.Hour) |
| 168 | serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) |
| 169 | serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) |
| 170 | if err != nil { |
| 171 | return nil, fmt.Errorf("failed to generate serial number: %v", err) |
| 172 | } |
| 173 | |
| 174 | cert := &x509.Certificate{ |
| 175 | SerialNumber: serialNumber, |
| 176 | Subject: pkix.Name{ |
| 177 | Organization: []string{"Puma-dev Signed"}, |
| 178 | CommonName: name, |
| 179 | }, |
| 180 | NotBefore: notBefore, |
| 181 | NotAfter: notAfter, |
| 182 | KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
| 183 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
| 184 | } |
| 185 | |
| 186 | cert.DNSNames = append(cert.DNSNames, name) |
| 187 | |
| 188 | x509parent, err := x509.ParseCertificate(parent.Certificate[0]) |
| 189 | if err != nil { |
| 190 | return nil, err |
| 191 | } |
| 192 | |
| 193 | derBytes, err := x509.CreateCertificate( |
| 194 | rand.Reader, cert, x509parent, privKey.Public(), parent.PrivateKey) |
| 195 | |
| 196 | if err != nil { |
| 197 | return nil, fmt.Errorf("could not create certificate: %v", err) |
| 198 | } |
| 199 | |
| 200 | tlsCert := &tls.Certificate{ |
| 201 | Certificate: [][]byte{derBytes}, |
| 202 | PrivateKey: privKey, |
| 203 | Leaf: cert, |
| 204 | } |
| 205 | |
| 206 | return tlsCert, nil |
| 207 | } |