Add makecert cmd line
This commit is contained in:
Родитель
afccdf2f64
Коммит
8d08731b0f
|
@ -0,0 +1,66 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"go.mozilla.org/digigo"
|
||||
)
|
||||
|
||||
var (
|
||||
host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
|
||||
ou = flag.String("ou", "Cloud Services", "Organizational Unit")
|
||||
org = flag.String("org", "Mozilla Corporation", "Organization")
|
||||
loc = flag.String("loc", "Mountain View", "Locality")
|
||||
st = flag.String("st", "California", "State")
|
||||
country = flag.String("c", "US", "Country")
|
||||
email = flag.String("email", "hostmaster@mozilla.com", "Email")
|
||||
rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate, default to rsa 2048, ignored if --ecdsa-curve is set")
|
||||
ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key, valid values are P256 and P384")
|
||||
valYears = flag.Int("validity-years", 1, "Years of validity of the signed certificate: 1 (default), 2 or 3")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if len(*host) == 0 {
|
||||
log.Fatalf("Missing required --host parameter")
|
||||
}
|
||||
// Create and test the connection to Digicert
|
||||
cli, err := digigo.NewClient(os.Getenv("DIGICERT_API_TOKEN"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = cli.ViewProductList()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Step 1: make a certificate request and a private key
|
||||
csr, csrPEM, _, err := makeCSRAndKey()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Step 2: submit an order to digicert
|
||||
var order digigo.Order
|
||||
order.Certificate.CommonName = csr.Subject.CommonName
|
||||
order.Certificate.Csr = csrPEM
|
||||
order.Certificate.OrganizationUnits = csr.Subject.OrganizationalUnit
|
||||
order.Certificate.ServerPlatform.ID = 45 // nginx, aka. standard PEM
|
||||
order.ValidityYears = *valYears
|
||||
switch csr.SignatureAlgorithm {
|
||||
case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
|
||||
order.Certificate.SignatureHash = "sha384"
|
||||
case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
|
||||
order.Certificate.SignatureHash = "sha512"
|
||||
default:
|
||||
order.Certificate.SignatureHash = "sha256"
|
||||
}
|
||||
// FIXME: actually call ListOrganizations
|
||||
order.Organization.ID = 110462 // mozilla org ID
|
||||
orderID, err := cli.SubmitOrder(order, "ssl_plus")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println(orderID)
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func makeCSRAndKey() (csr x509.CertificateRequest, csrPEM, privKeyPEM string, err error) {
|
||||
var priv interface{}
|
||||
switch *ecdsaCurve {
|
||||
case "":
|
||||
priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
|
||||
case "P256":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
case "P384":
|
||||
priv, err = ecdsa.GenerateKey(elliptic.P384(), 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)
|
||||
}
|
||||
hosts := strings.Split(*host, ",")
|
||||
template := x509.CertificateRequest{
|
||||
Subject: pkix.Name{
|
||||
CommonName: hosts[0],
|
||||
Organization: []string{*org},
|
||||
OrganizationalUnit: []string{*ou},
|
||||
Country: []string{*country},
|
||||
Province: []string{*st},
|
||||
Locality: []string{*loc},
|
||||
},
|
||||
}
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, h)
|
||||
}
|
||||
}
|
||||
csrB, err := x509.CreateCertificateRequest(rand.Reader, &template, priv)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to generate CSR")
|
||||
return
|
||||
}
|
||||
// convert the CSR bytes to PEM
|
||||
var csrBuf bytes.Buffer
|
||||
pem.Encode(&csrBuf, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrB})
|
||||
csrPEM = string(csrBuf.Bytes())
|
||||
// convert the private key to PEM
|
||||
privKeyPEM, err = getPrivateKeyPEM(priv)
|
||||
return csr, csrPEM, privKeyPEM, err
|
||||
}
|
||||
|
||||
func getPrivateKeyPEM(priv interface{}) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
switch k := priv.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
pem.Encode(&buf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)})
|
||||
case *ecdsa.PrivateKey:
|
||||
b, err := x509.MarshalECPrivateKey(k)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "unable to marshal ECDSA private key")
|
||||
}
|
||||
pem.Encode(&buf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
|
||||
default:
|
||||
return "", errors.Errorf("unknown private key type %T", priv)
|
||||
}
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
Загрузка…
Ссылка в новой задаче