This commit is contained in:
Julien Vehent 2017-05-22 15:46:12 -04:00
Родитель afccdf2f64
Коммит 8d08731b0f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: A3D652173B763E8F
2 изменённых файлов: 150 добавлений и 0 удалений

66
cmd/makecert/main.go Normal file
Просмотреть файл

@ -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)
}

84
cmd/makecert/x509.go Normal file
Просмотреть файл

@ -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
}