clean up keygen and actually zip files within su3

This commit is contained in:
Matt Drollette
2014-12-14 16:49:58 -06:00
parent 39fc022ac8
commit a443d7c2a2
6 changed files with 71 additions and 70 deletions

View File

@@ -4,28 +4,29 @@ import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"math/big" "strings"
"os"
"time"
"github.com/MDrollette/go-i2p/reseed" "github.com/MDrollette/go-i2p/su3"
"github.com/codegangsta/cli" "github.com/codegangsta/cli"
) )
func NewKeygenCommand() cli.Command { func NewKeygenCommand() cli.Command {
return cli.Command{ return cli.Command{
Name: "keygen", Name: "keygen",
Usage: "Generate keys for reseed SU3 signing", Usage: "Generate keys for reseed su3 signing and TLS serving.",
Description: "Generate keys for reseed SU3 signing", Action: keygenAction,
Action: keygenAction,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "signer", Name: "signer",
Usage: "Your SU3 signing ID (your email address)", Usage: "Your su3 signing ID (ex. something@mail.i2p)",
},
cli.StringFlag{
Name: "host",
Usage: "Hostname to use for self-signed TLS certificate",
}, },
}, },
} }
@@ -38,66 +39,26 @@ func keygenAction(c *cli.Context) {
return return
} }
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{
BasicConstraintsValid: true,
IsCA: true,
SubjectKeyId: []byte(signerId),
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"I2P Anonymous Network"},
OrganizationalUnit: []string{"I2P"},
Locality: []string{"XX"},
StreetAddress: []string{"XX"},
Country: []string{"XX"},
CommonName: signerId,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
// generate private key // generate private key
fmt.Println("Generating keys. This may take a moment...") fmt.Println("Generating keys. This may take a moment...")
privatekey, err := rsa.GenerateKey(rand.Reader, 4096) signerKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
publickey := &privatekey.PublicKey signerCert, err := su3.NewSigningCertificate(signerId, signerKey)
// create a self-signed certificate. template = parent
var parent = template
cert, err := x509.CreateCertificate(rand.Reader, template, parent, publickey, privatekey)
if err != nil {
log.Fatalln(err)
}
// save private key // save private key
pemfile, err := os.Create("reseed_private.pem") privFile := strings.Replace(signerId, "@", "_at_", 1) + ".pem"
if err != nil { if ioutil.WriteFile(privFile, pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(signerKey)}), 0600); err != nil {
log.Fatalf("failed to open reseed_cert.pem for writing: %s", err) log.Fatalln(err)
} }
var pemkey = &pem.Block{ fmt.Println("private key saved to:", privFile)
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(privatekey)}
pem.Encode(pemfile, pemkey)
pemfile.Close()
fmt.Println("private key saved to reseed_private.pem")
// save cert // save cert
filename := reseed.SignerFilename(signerId) certFile := strings.Replace(signerId, "@", "_at_", 1) + ".crt"
certOut, err := os.Create(filename) if ioutil.WriteFile(certFile, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: signerCert}), 0755); err != nil {
if err != nil { log.Fatalln(err)
log.Fatalf("failed to open %s for writing: %s", filename, err)
} }
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cert}) fmt.Println("certificate saved to", certFile)
certOut.Close()
fmt.Println("certificate saved to", filename)
} }

View File

@@ -13,14 +13,13 @@ import (
func NewReseedCommand() cli.Command { func NewReseedCommand() cli.Command {
return cli.Command{ return cli.Command{
Name: "reseed", Name: "reseed",
Usage: "Start a reseed server", Usage: "Start a reseed server",
Description: "Start a reseed server", Action: reseedAction,
Action: reseedAction,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "signer", Name: "signer",
Usage: "Your SU3 signing ID (your email address)", Usage: "Your su3 signing ID (ex. something@mail.i2p)",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "netdb", Name: "netdb",
@@ -76,6 +75,7 @@ func NewReseedCommand() cli.Command {
} }
func reseedAction(c *cli.Context) { func reseedAction(c *cli.Context) {
// validate flags
netdbDir := c.String("netdb") netdbDir := c.String("netdb")
if netdbDir == "" { if netdbDir == "" {
fmt.Println("--netdb is required") fmt.Println("--netdb is required")
@@ -93,13 +93,12 @@ func reseedAction(c *cli.Context) {
log.Fatalf("'%s' is not a valid time interval.\n", reloadIntvl) log.Fatalf("'%s' is not a valid time interval.\n", reloadIntvl)
} }
// use at most half of the cores // use all cores
cpus := runtime.NumCPU() cpus := runtime.NumCPU()
runtime.GOMAXPROCS(cpus) runtime.GOMAXPROCS(cpus)
log.Printf("Using %d CPU cores.\n", cpus) log.Printf("Using %d CPU cores.\n", cpus)
// load our signing privKey // load our signing privKey
// @todo: generate a new signing key if one doesn't exist
privKey, err := loadPrivateKey(c.String("keyfile")) privKey, err := loadPrivateKey(c.String("keyfile"))
if nil != err { if nil != err {
log.Fatalln(err) log.Fatalln(err)

View File

@@ -9,7 +9,7 @@ import (
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "i2p" app.Name = "go-i2p"
app.Version = "0.1.0" app.Version = "0.1.0"
app.Usage = "I2P commands" app.Usage = "I2P commands"
app.Flags = []cli.Flag{} app.Flags = []cli.Flag{}

View File

@@ -24,5 +24,5 @@ func (ks *KeyStore) ReseederCertificate(signer []byte) (*x509.Certificate, error
} }
func SignerFilename(signer string) string { func SignerFilename(signer string) string {
return strings.Replace(signer, "@", "_at_", 2) + ".crt" return strings.Replace(signer, "@", "_at_", 1) + ".crt"
} }

View File

@@ -16,7 +16,7 @@ func zipSeeds(seeds Seeds) ([]byte, error) {
// Add some files to the archive. // Add some files to the archive.
for _, file := range seeds { for _, file := range seeds {
fileHeader := &zip.FileHeader{Name: file.Name} fileHeader := &zip.FileHeader{Name: file.Name, Method: zip.Deflate}
fileHeader.SetModTime(time.Now().UTC()) fileHeader.SetModTime(time.Now().UTC())
zipFile, err := zipWriter.CreateHeader(fileHeader) zipFile, err := zipWriter.CreateHeader(fileHeader)
if err != nil { if err != nil {

View File

@@ -4,11 +4,14 @@ import (
"crypto" "crypto"
"crypto/dsa" "crypto/dsa"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix"
"encoding/asn1" "encoding/asn1"
"errors" "errors"
"math/big" "math/big"
"time"
) )
type dsaSignature struct { type dsaSignature struct {
@@ -72,3 +75,41 @@ func checkSignature(c *x509.Certificate, algo x509.SignatureAlgorithm, signed, s
} }
return x509.ErrUnsupportedAlgorithm return x509.ErrUnsupportedAlgorithm
} }
func NewSigningCertificate(signerId string, privateKey *rsa.PrivateKey) ([]byte, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return nil, err
}
template := &x509.Certificate{
BasicConstraintsValid: true,
IsCA: true,
SubjectKeyId: []byte(signerId),
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"I2P Anonymous Network"},
OrganizationalUnit: []string{"I2P"},
Locality: []string{"XX"},
StreetAddress: []string{"XX"},
Country: []string{"XX"},
CommonName: signerId,
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
publicKey := &privateKey.PublicKey
// create a self-signed certificate. template = parent
var parent = template
cert, err := x509.CreateCertificate(rand.Reader, template, parent, publicKey, privateKey)
if err != nil {
return nil, err
}
return cert, nil
}