clean up keygen and actually zip files within su3
This commit is contained in:
@@ -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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ 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)
|
||||||
|
|||||||
2
main.go
2
main.go
@@ -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{}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user