IssueServerCert issues a TLS server certificate signed by this CA, using a freshly generated RSA-2048 key pair owned by the returned tls.Certificate. The certificate's CommonName is set to cn and its SAN list is populated from sans (DNS names and/or IP literals; IPs are detected via net.ParseIP). T
(cn string, sans []string, ttl time.Duration)
| 259 | // trust the NodeCA (delivered via enroll response), so they will accept any |
| 260 | // server cert chained to it without extra trust configuration. |
| 261 | func (ca *NodeCA) IssueServerCert(cn string, sans []string, ttl time.Duration) (tls.Certificate, error) { |
| 262 | if cn == "" { |
| 263 | return tls.Certificate{}, fmt.Errorf("common name is required") |
| 264 | } |
| 265 | if ttl <= 0 { |
| 266 | return tls.Certificate{}, fmt.Errorf("ttl must be positive") |
| 267 | } |
| 268 | |
| 269 | priv, err := rsa.GenerateKey(rand.Reader, 2048) |
| 270 | if err != nil { |
| 271 | return tls.Certificate{}, fmt.Errorf("generate server key: %w", err) |
| 272 | } |
| 273 | |
| 274 | serial, err := randomSerial() |
| 275 | if err != nil { |
| 276 | return tls.Certificate{}, err |
| 277 | } |
| 278 | |
| 279 | dnsNames := make([]string, 0, len(sans)) |
| 280 | ipAddrs := make([]net.IP, 0) |
| 281 | for _, s := range sans { |
| 282 | if s == "" { |
| 283 | continue |
| 284 | } |
| 285 | if ip := net.ParseIP(s); ip != nil { |
| 286 | ipAddrs = append(ipAddrs, ip) |
| 287 | } else { |
| 288 | dnsNames = append(dnsNames, s) |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | now := time.Now() |
| 293 | template := &x509.Certificate{ |
| 294 | SerialNumber: serial, |
| 295 | Subject: pkix.Name{ |
| 296 | CommonName: cn, |
| 297 | Organization: []string{"pulse"}, |
| 298 | }, |
| 299 | NotBefore: now.Add(-time.Minute), |
| 300 | NotAfter: now.Add(ttl), |
| 301 | KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, |
| 302 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, |
| 303 | BasicConstraintsValid: true, |
| 304 | IsCA: false, |
| 305 | DNSNames: dnsNames, |
| 306 | IPAddresses: ipAddrs, |
| 307 | } |
| 308 | |
| 309 | der, err := x509.CreateCertificate(rand.Reader, template, ca.cert, &priv.PublicKey, ca.key) |
| 310 | if err != nil { |
| 311 | return tls.Certificate{}, fmt.Errorf("sign server certificate: %w", err) |
| 312 | } |
| 313 | |
| 314 | leaf, err := x509.ParseCertificate(der) |
| 315 | if err != nil { |
| 316 | return tls.Certificate{}, fmt.Errorf("parse issued server cert: %w", err) |
| 317 | } |
| 318 |