mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
This patch moves the test helper binaries to a "one directory per helper" layout, and also makes them to be ignored in the coverage build instead of all builds. With this change, "go build ./..." will build all binaries including the test helpers, which helps make sure that module manage automation also considers them. In particular, this makes "go mod tidy" work fine.
169 lines
4.5 KiB
Go
169 lines
4.5 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build !coverage
|
|
// +build !coverage
|
|
|
|
// Generate a self-signed X.509 certificate for a TLS server. Outputs to
|
|
// 'cert.pem' and 'key.pem' and will overwrite existing files.
|
|
|
|
package main
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"math/big"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"golang.org/x/net/idna"
|
|
)
|
|
|
|
var (
|
|
host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
|
|
validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
|
|
validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
|
|
isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
|
|
rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
|
|
ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521")
|
|
)
|
|
|
|
func publicKey(priv interface{}) interface{} {
|
|
switch k := priv.(type) {
|
|
case *rsa.PrivateKey:
|
|
return &k.PublicKey
|
|
case *ecdsa.PrivateKey:
|
|
return &k.PublicKey
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func pemBlockForKey(priv interface{}) *pem.Block {
|
|
switch k := priv.(type) {
|
|
case *rsa.PrivateKey:
|
|
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
|
|
case *ecdsa.PrivateKey:
|
|
b, err := x509.MarshalECPrivateKey(k)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
|
|
os.Exit(2)
|
|
}
|
|
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
if len(*host) == 0 {
|
|
log.Fatalf("Missing required --host parameter")
|
|
}
|
|
|
|
var priv interface{}
|
|
var err error
|
|
switch *ecdsaCurve {
|
|
case "":
|
|
priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
|
|
case "P224":
|
|
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
|
case "P256":
|
|
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
case "P384":
|
|
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
|
case "P521":
|
|
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve)
|
|
os.Exit(1)
|
|
}
|
|
if err != nil {
|
|
log.Fatalf("failed to generate private key: %s", err)
|
|
}
|
|
|
|
var notBefore time.Time
|
|
if len(*validFrom) == 0 {
|
|
notBefore = time.Now()
|
|
} else {
|
|
notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
notAfter := notBefore.Add(*validFor)
|
|
|
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
|
if err != nil {
|
|
log.Fatalf("failed to generate serial number: %s", err)
|
|
}
|
|
|
|
template := x509.Certificate{
|
|
SerialNumber: serialNumber,
|
|
Subject: pkix.Name{
|
|
Organization: []string{"Acme Co"},
|
|
},
|
|
NotBefore: notBefore,
|
|
NotAfter: notAfter,
|
|
|
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
BasicConstraintsValid: true,
|
|
}
|
|
|
|
hosts := strings.Split(*host, ",")
|
|
for _, h := range hosts {
|
|
if ip := net.ParseIP(h); ip != nil {
|
|
template.IPAddresses = append(template.IPAddresses, ip)
|
|
} else {
|
|
// We use IDNA-encoded DNS names, otherwise the TLS library won't
|
|
// load the certificates.
|
|
ih, err := idna.ToASCII(h)
|
|
if err != nil {
|
|
log.Fatalf("host %q cannot be IDNA-encoded: %v", h, err)
|
|
}
|
|
template.DNSNames = append(template.DNSNames, ih)
|
|
}
|
|
}
|
|
|
|
if *isCA {
|
|
template.IsCA = true
|
|
template.KeyUsage |= x509.KeyUsageCertSign
|
|
}
|
|
|
|
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create certificate: %s", err)
|
|
}
|
|
|
|
certOut, err := os.Create("fullchain.pem")
|
|
if err != nil {
|
|
log.Fatalf("failed to open fullchain.pem for writing: %s", err)
|
|
}
|
|
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
|
certOut.Close()
|
|
|
|
keyOut, err := os.OpenFile("privkey.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
|
if err != nil {
|
|
log.Fatalf("failed to open privkey.pem for writing: %s", err)
|
|
return
|
|
}
|
|
pem.Encode(keyOut, pemBlockForKey(priv))
|
|
keyOut.Close()
|
|
}
|