goint there

This commit is contained in:
didier.amyot committed 2014-07-30 15:02:28 -04:00
1 parent 776c73b91c
commit c94a2042f1
7 files changed
+287 -31

No files matched your search

+38 -2
View File
@@ -3,7 +3,11 @@ package main
import ( import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"encoding/json"
"errors" "errors"
"github.com/didiercrunch/ecrypto/shared"
"os"
"path"
) )
type KeyGenerator struct { type KeyGenerator struct {
@@ -11,6 +15,38 @@ type KeyGenerator struct {
privateKey *PrivateKey privateKey *PrivateKey
} }
func (this *KeyGenerator) ensureDirectoryExists(dir string) error {
stat, err := os.Stat(dir)
if os.IsNotExist(err) {
return os.Mkdir(dir, 0700)
} else if err != nil {
return err
} else if !stat.IsDir() {
return errors.New(dir + " is not a directory")
}
return nil
}
func (this *KeyGenerator) saveKeyAsJSON(key interface{}, filepath string) error {
w, err := os.Create(filepath)
if err != nil {
return err
}
enc := json.NewEncoder(w)
return enc.Encode(key)
}
func (this *KeyGenerator) saveKeys(dirPath string) error {
if err := this.ensureDirectoryExists(dirPath); err != nil {
return err
}
if err := this.saveKeyAsJSON(this.publicKey, path.Join(dirPath, "publickey.json")); err != nil {
return err
}
return this.saveKeyAsJSON(this.privateKey, path.Join(dirPath, "privatekey.json"))
}
func (this *KeyGenerator) createRSAKey(size int) error { func (this *KeyGenerator) createRSAKey(size int) error {
rsaPrivateKey, err := rsa.GenerateKey(rand.Reader, size) rsaPrivateKey, err := rsa.GenerateKey(rand.Reader, size)
if err != nil { if err != nil {
@@ -24,9 +60,9 @@ func (this *KeyGenerator) createRSAKey(size int) error {
return nil return nil
} }
func (this *KeyGenerator) CreateNewKey(size int, password string) error { func (this *KeyGenerator) CreateNewKey(size int) error {
if err := this.createRSAKey(size); err != nil { if err := this.createRSAKey(size); err != nil {
return err return err
} }
return nil return this.saveKeys(shared.GetEcryptoDir())
} }
+55
View File
@@ -1,6 +1,11 @@
package main package main
import ( import (
"encoding/json"
"io/ioutil"
"os"
"path"
"reflect"
"testing" "testing"
) )
@@ -16,3 +21,53 @@ func TestCreateRSAKey(t *testing.T) {
t.Fail() t.Fail()
} }
} }
func TestSaveKeyAsJSON(t *testing.T) {
kc := new(KeyGenerator)
if err := kc.CreateNewKey(100); err != nil {
t.Error(err)
return
}
file, err := ioutil.TempFile(os.TempDir(), "prefix")
if err != nil {
t.Error(err)
return
}
defer os.Remove(file.Name())
if err := kc.saveKeyAsJSON(kc.privateKey, file.Name()); err != nil {
t.Error(err)
}
data, err := ioutil.ReadFile(file.Name())
if err != nil {
t.Error(err)
return
}
pk := new(PrivateKey)
if err := json.Unmarshal(data, pk); err != nil {
t.Error(err)
return
}
if !reflect.DeepEqual(pk.Key, kc.privateKey.Key) {
t.Fail()
}
}
func TestEnsureDirectoryExists(t *testing.T) {
kc := new(KeyGenerator)
fooDir := path.Join(os.TempDir(), "fds89d")
defer os.Remove(fooDir)
if err := kc.ensureDirectoryExists(fooDir); err != nil {
t.Error(err)
return
}
if _, err := os.Stat(fooDir); err != nil {
t.Error(err)
return
}
if err := kc.ensureDirectoryExists(fooDir); err != nil {
t.Error(err)
}
}
+4 -2
View File
@@ -17,7 +17,10 @@ var createKeyCommand = cli.Command{
}, },
Action: func(c *cli.Context) { Action: func(c *cli.Context) {
keyGenerator := new(KeyGenerator) keyGenerator := new(KeyGenerator)
keyGenerator.CreateNewKey(c.Int("size"), c.String("password")) fmt.Println("creating key")
if err := keyGenerator.CreateNewKey(c.Int("size")); err != nil {
fmt.Println("error while creating the key\n", err)
}
}, },
} }
@@ -29,6 +32,5 @@ func main() {
createKeyCommand, createKeyCommand,
} }
fmt.Println(os.Args)
app.Run(os.Args) app.Run(os.Args)
} }
+99 -11
View File
@@ -2,6 +2,9 @@ package main
import ( import (
"crypto/rsa" "crypto/rsa"
"encoding/json"
"errors"
"fmt"
"math/big" "math/big"
) )
@@ -12,20 +15,16 @@ const (
) )
type PrivateKey struct { type PrivateKey struct {
Name string
Description string
Type string // rsa, el gamal,...
Version string Version string
Key interface{} Type string // rsa, el gamal,...
Key *RSAPrivateKey
Accept *AcceptMethods Accept *AcceptMethods
} }
type PublicKey struct { type PublicKey struct {
Name string
Description string
Type string // rsa, el gamal,... Type string // rsa, el gamal,...
Version string Version string
Key interface{} Key *RSAPublicKey
Accept *AcceptMethods Accept *AcceptMethods
} }
@@ -35,13 +34,102 @@ type RSAPublicKey struct {
} }
type RSAPrivateKey struct { type RSAPrivateKey struct {
N *big.Int N *big.Int `json:"n,omitempty"`
P *big.Int P *big.Int `json:"p,omitempty"`
Q *big.Int Q *big.Int `json:"q,omitempty"`
D *big.Int D *big.Int `json:"d,omitempty"`
E int `json:"e,omitempty"`
}
type encodingRSAKey struct {
N string
P string
Q string
D string
E int E int
} }
func (this *encodingRSAKey) CreateFromRSAPrivateKey(key *RSAPrivateKey) *encodingRSAKey {
this.N = fmt.Sprintf("%x", key.N)
this.P = fmt.Sprintf("%x", key.P)
this.Q = fmt.Sprintf("%x", key.Q)
this.D = fmt.Sprintf("%x", key.D)
this.E = key.E
return this
}
func (this *encodingRSAKey) CreateFromRSAPublicKey(key *RSAPublicKey) *encodingRSAKey {
this.N = fmt.Sprintf("%x", key.N)
this.E = key.E
return this
}
func (this *encodingRSAKey) SetRSAPrivateKey(key *RSAPrivateKey) (*RSAPrivateKey, error) {
if i, ok := new(big.Int).SetString(this.N, 16); !ok {
return nil, errors.New("cannot parse string has hexadecimal string")
} else {
key.N = i
}
if i, ok := new(big.Int).SetString(this.P, 16); !ok {
return nil, errors.New("cannot parse string has hexadecimal string")
} else {
key.P = i
}
if i, ok := new(big.Int).SetString(this.Q, 16); !ok {
return nil, errors.New("cannot parse string has hexadecimal string")
} else {
key.Q = i
}
if i, ok := new(big.Int).SetString(this.D, 16); !ok {
return nil, errors.New("cannot parse string has hexadecimal string")
} else {
key.D = i
}
key.E = this.E
return key, nil
}
func (this *encodingRSAKey) SetRSAPublicKey(key *RSAPublicKey) (*RSAPublicKey, error) {
if i, ok := new(big.Int).SetString(this.N, 16); !ok {
return nil, errors.New("cannot parse string has hexadecimal string")
} else {
key.N = i
}
key.E = this.E
return key, nil
}
func (this *RSAPrivateKey) MarshalJSON() ([]byte, error) {
e := new(encodingRSAKey)
return json.Marshal(e.CreateFromRSAPrivateKey(this))
}
func (this *RSAPrivateKey) UnmarshalJSON(data []byte) error {
obj := new(encodingRSAKey)
if err := json.Unmarshal(data, obj); err != nil {
return err
}
_, err := obj.SetRSAPrivateKey(this)
return err
}
func (this *RSAPublicKey) MarshalJSON() ([]byte, error) {
e := new(encodingRSAKey)
return json.Marshal(e.CreateFromRSAPublicKey(this))
}
func (this *RSAPublicKey) UnmarshalJSON(data []byte) error {
obj := new(encodingRSAKey)
if err := json.Unmarshal(data, obj); err != nil {
return err
}
_, err := obj.SetRSAPublicKey(this)
return err
}
type AcceptMethods struct { type AcceptMethods struct {
BlocCypher string BlocCypher string
BlockCypherMode string BlockCypherMode string
+43 -16
View File
@@ -2,7 +2,9 @@ package main
import ( import (
"crypto/rsa" "crypto/rsa"
"encoding/json"
"math/big" "math/big"
"reflect"
"testing" "testing"
) )
@@ -13,15 +15,11 @@ func b(x int64) *big.Int {
func TestGetDefaultRSAPublicKey(t *testing.T) { func TestGetDefaultRSAPublicKey(t *testing.T) {
key := &rsa.PublicKey{b(31 * 11), 3} key := &rsa.PublicKey{b(31 * 11), 3}
pk := GetDefaultRSAPublicKey(key) pk := GetDefaultRSAPublicKey(key)
niceKey, ok := pk.Key.(*RSAPublicKey)
if !ok { if big.NewInt(31*11).Cmp(pk.Key.N) != 0 {
t.Error("bad key type")
return
}
if big.NewInt(31*11).Cmp(niceKey.N) != 0 {
t.Error("bad N") t.Error("bad N")
} }
if 3 != niceKey.E { if 3 != pk.Key.E {
t.Error("bad e") t.Error("bad e")
} }
} }
@@ -37,21 +35,50 @@ func TestGetDefaultRSAPrivateKey(t *testing.T) {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
niceKey, ok := pk.Key.(*RSAPrivateKey) if pk.Key.D.Int64() != 3 {
if !ok {
t.Error("bad key type")
return
}
if niceKey.D.Int64() != 3 {
t.Error("bad D") t.Error("bad D")
} }
if niceKey.E != 7 { if pk.Key.E != 7 {
t.Error("bad D") t.Error("bad D")
} }
if niceKey.P.Int64() != 3 { if pk.Key.P.Int64() != 3 {
t.Error("bad D") t.Error("bad D")
} }
if niceKey.Q.Int64() != 11 { if pk.Key.Q.Int64() != 11 {
t.Error("bad D") t.Error("bad D")
} }
} }
func TestRSAPrivateKeyJsonification(t *testing.T) {
key := &RSAPrivateKey{b(1023), b(2112), b(328723), b(2332), 89}
data, err := json.Marshal(key)
if err != nil {
t.Error(err)
return
}
key2 := new(RSAPrivateKey)
if err := json.Unmarshal(data, key2); err != nil {
t.Error(err)
return
}
if !reflect.DeepEqual(key, key2) {
t.Fail()
}
}
func TestRSAPublicKeyJsonification(t *testing.T) {
key := &RSAPublicKey{b(1023), 89}
data, err := json.Marshal(key)
if err != nil {
t.Error(err)
return
}
key2 := new(RSAPublicKey)
if err := json.Unmarshal(data, key2); err != nil {
t.Error(err)
return
}
if !reflect.DeepEqual(key, key2) {
t.Fail()
}
}
+9
View File
@@ -0,0 +1,9 @@
package shared
import (
"os"
)
const DIRECTORY_PERMISSION os.FileMode = 0700
const PUBLIC_KEY_PERMISSION os.FileMode = 0644
const PRIVATE_KEY_PERMISSION os.FileMode = 0600
+39
View File
@@ -0,0 +1,39 @@
package shared
import (
"errors"
"fmt"
"os"
"path"
)
var ecryptoDir string
func ensureEcryptoDirectoryIsOkay(dir string) error {
stat, err := os.Stat(dir)
if os.IsNotExist(err) {
return os.Mkdir(dir, DIRECTORY_PERMISSION)
} else if err != nil {
return err
} else if !stat.IsDir() {
return errors.New(dir + " is not a directory")
} else if perm := stat.Mode().Perm(); perm != DIRECTORY_PERMISSION {
msg := fmt.Sprintf("root folder has bad file permission. should be set to %v but vas %v", DIRECTORY_PERMISSION, perm)
return errors.New(msg)
}
return nil
}
func init() {
ecryptoDir = path.Join(os.Getenv("HOME"), ".ecrypto")
if err := ensureEcryptoDirectoryIsOkay(ecryptoDir); err != nil {
fmt.Println("cannot work with eCrypto directory", err)
os.Exit(1)
}
}
func GetEcryptoDir() string {
return ecryptoDir
}