// Copyright (c) 2011 The Grumble Authors // The use of this source code is goverened by a BSD-style // license that can be found in the LICENSE-file. package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "log" "os" "path/filepath" "time" ) // Generate a 2048-bit RSA keypair and a Grumble auto-generated X509 // certificate. Output PEM-encoded DER representations of the resulting // certificate and private key to certpath and keypath. func GenerateSelfSignedCert(certpath, keypath string) (err os.Error) { now := time.Seconds() tmpl := &x509.Certificate{ SerialNumber: []byte{0}, Subject: x509.Name{ CommonName: "Grumble Autogenerated Certificate", }, NotBefore: time.SecondsToUTC(now - 300), NotAfter: time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year. SubjectKeyId: []byte{1, 2, 3, 4}, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, } priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } certbuf, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &priv.PublicKey, priv) if err != nil { log.Printf("Error: %v", err) return err } certblk := pem.Block{ Type: "CERTIFICATE", Bytes: certbuf, } keybuf := x509.MarshalPKCS1PrivateKey(priv) keyblk := pem.Block{ Type: "RSA PRIVATE KEY", Bytes: keybuf, } certfn := filepath.Join(*datadir, "cert") file, err := os.OpenFile(certfn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0700) if err != nil { return err } defer file.Close() err = pem.Encode(file, &certblk) if err != nil { return err } keyfn := filepath.Join(*datadir, "key") file, err = os.OpenFile(keyfn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0700) if err != nil { return err } defer file.Close() err = pem.Encode(file, &keyblk) if err != nil { return err } return nil }