From 209af0d8204f5b7f8d790d335578637985edbbf6 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Sun, 9 Nov 2014 17:13:36 -0800 Subject: [PATCH] going somewhere --- asymetric/constructor.go | 39 +++++++- asymetric/constructor_test.go | 64 ++++++++++++- asymetric/{rsa.go => rsaOaepEncrypter.go} | 17 +--- asymetric/rsaOaepEncrypter_test.go | 60 +++++++++++++ asymetric/rsaPssSigner.go | 37 ++++++++ asymetric/rsaPssSigner_test.go | 64 +++++++++++++ asymetric/rsaUtil_test.go | 19 ++++ asymetric/rsa_test.go | 104 ---------------------- contract/contract_generators.go | 98 ++++++++++++++++++++ contract/contract_generators_test.go | 73 +++++++++++++++ files/encrypt_file.go | 24 ++++- files/encrypt_file_test.go | 3 + helper/helper.go | 27 ++++++ helper/helper_test.go | 22 +++++ integration/enveloppayload_test.go | 15 +++- keys/keys.go | 14 ++- 16 files changed, 549 insertions(+), 131 deletions(-) rename asymetric/{rsa.go => rsaOaepEncrypter.go} (58%) create mode 100644 asymetric/rsaOaepEncrypter_test.go create mode 100644 asymetric/rsaPssSigner.go create mode 100644 asymetric/rsaPssSigner_test.go create mode 100644 asymetric/rsaUtil_test.go delete mode 100644 asymetric/rsa_test.go create mode 100644 contract/contract_generators.go create mode 100644 contract/contract_generators_test.go create mode 100644 files/encrypt_file_test.go diff --git a/asymetric/constructor.go b/asymetric/constructor.go index fb51f2d..48e4672 100644 --- a/asymetric/constructor.go +++ b/asymetric/constructor.go @@ -1,7 +1,11 @@ package asymetric import ( + "crypto/rand" + "errors" + "github.com/didiercrunch/filou/contract" + "github.com/didiercrunch/filou/helper" ) type PublicKeyEncryptor interface { @@ -12,10 +16,37 @@ type Signer interface { Sign(data []byte) ([]byte, error) } -func GetSigner(contract_ contract.AcceptedContract) (Signer, error) { - return nil, nil +func GetSigner(contract_ *contract.AcceptedContract) (Signer, error) { + if contract_.SignatureScheme == "rsa_pss" { + return getRsaPssSignerFromContract(contract_) + } + return nil, errors.New("signature scheme " + contract_.SignatureScheme + " not supported") } -func GetPublicKeyEncryptor(contract_ contract.AcceptedContract) (Signer, error) { - return nil, nil +func GetPublicKeyEncryptor(contract_ *contract.AcceptedContract) (PublicKeyEncryptor, error) { + if contract_.AsynchronousEncryptionScheme == "rsa_oaep" { + return getRsaOaepEncryptorFromContract(contract_) + } else { + return nil, errors.New("asynchronous encryption scheme " + contract_.AsynchronousEncryptionScheme + " not supported") + } +} + +func getRsaPssSignerFromContract(con *contract.AcceptedContract) (*RsaPssSigner, error) { + if privKey, err := con.RsaPrivateKey(); err != nil { + return nil, err + } else if hash, err := helper.GetHashFunctionByLowerCaseName(con.Hash); err != nil { + return nil, err + } else { + return &RsaPssSigner{privKey, con.RsaPublicKey, hash, rand.Reader}, nil + } +} + +func getRsaOaepEncryptorFromContract(con *contract.AcceptedContract) (*RsaOaepEncrypter, error) { + if privKey, err := con.RsaPrivateKey(); err != nil { + return nil, err + } else if hash, err := helper.GetHashFunctionByLowerCaseName(con.Hash); err != nil { + return nil, err + } else { + return &RsaOaepEncrypter{privKey, con.RsaPublicKey, hash, rand.Reader}, nil + } } diff --git a/asymetric/constructor_test.go b/asymetric/constructor_test.go index 73b1165..ad7443b 100644 --- a/asymetric/constructor_test.go +++ b/asymetric/constructor_test.go @@ -1 +1,63 @@ -package asymetric \ No newline at end of file +package asymetric + +import ( + "crypto/rsa" + "testing" + + "github.com/didiercrunch/filou/contract" +) + +func TestGetSignerEmptyContract(t *testing.T) { + c := new(contract.AcceptedContract) + if _, err := GetSigner(c); err == nil { + t.Error("exceptec an error here") + } +} + +func TestGetSignerBadName(t *testing.T) { + c := new(contract.AcceptedContract) + c.SignatureScheme = "bigtits.com" + if _, err := GetSigner(c); err == nil { + t.Error("exceptec an error here") + } +} + +func TestGetSigner(t *testing.T) { + c := new(contract.AcceptedContract) + priv, pub := generateKeyPair() + + c.Hash = "sha256" + c.SignatureScheme = "rsa_pss" + c.RsaPublicKey = pub + + c.RsaPrivateKey = func() (*rsa.PrivateKey, error) { + return priv, nil + } + if _, err := GetSigner(c); err != nil { + t.Error(err) + } +} + +func TestGetPublicKeyEncryptor(t *testing.T) { + c := new(contract.AcceptedContract) + priv, pub := generateKeyPair() + + c.Hash = "sha256" + c.AsynchronousEncryptionScheme = "rsa_oaep" + c.RsaPublicKey = pub + + c.RsaPrivateKey = func() (*rsa.PrivateKey, error) { + return priv, nil + } + if _, err := GetPublicKeyEncryptor(c); err != nil { + t.Error(err) + } +} + +func TestGetPublicKeyEncryptorBadName(t *testing.T) { + c := new(contract.AcceptedContract) + c.AsynchronousEncryptionScheme = "bigtits.com" + if _, err := GetPublicKeyEncryptor(c); err == nil { + t.Error("exceptec an error here") + } +} diff --git a/asymetric/rsa.go b/asymetric/rsaOaepEncrypter.go similarity index 58% rename from asymetric/rsa.go rename to asymetric/rsaOaepEncrypter.go index 3e40ae0..9694f46 100644 --- a/asymetric/rsa.go +++ b/asymetric/rsaOaepEncrypter.go @@ -11,7 +11,7 @@ import ( "io" ) -type RsaOaepPss struct { +type RsaOaepEncrypter struct { PrivateKey *rsa.PrivateKey PublicKey *rsa.PublicKey Hash crypto.Hash @@ -19,7 +19,7 @@ type RsaOaepPss struct { Random io.Reader } -func (this *RsaOaepPss) getHash() (crypto.Hash, error) { +func (this *RsaOaepEncrypter) getHash() (crypto.Hash, error) { if !this.Hash.Available() { return 0, errors.New(fmt.Sprintf("hash function %v is unabailable", this.Hash)) } else { @@ -27,7 +27,7 @@ func (this *RsaOaepPss) getHash() (crypto.Hash, error) { } } -func (this *RsaOaepPss) Encrypt(data []byte) ([]byte, error) { +func (this *RsaOaepEncrypter) Encrypt(data []byte) ([]byte, error) { label := make([]byte, 0) if hash, err := this.getHash(); err != nil { return nil, err @@ -37,7 +37,7 @@ func (this *RsaOaepPss) Encrypt(data []byte) ([]byte, error) { } -func (this *RsaOaepPss) Decrypt(ciphertext []byte) ([]byte, error) { +func (this *RsaOaepEncrypter) Decrypt(ciphertext []byte) ([]byte, error) { label := make([]byte, 0) if hash, err := this.getHash(); err != nil { return nil, err @@ -45,12 +45,3 @@ func (this *RsaOaepPss) Decrypt(ciphertext []byte) ([]byte, error) { return rsa.DecryptOAEP(hash.New(), this.Random, this.PrivateKey, ciphertext, label) } } - -func (this *RsaOaepPss) Sign(hashedData []byte) ([]byte, error) { - ret, err := rsa.SignPSS(this.Random, this.PrivateKey, this.Hash, hashedData, nil) - return ret, err -} - -func (this *RsaOaepPss) VerifySignature(hashedData []byte, signature []byte) error { - return rsa.VerifyPSS(this.PublicKey, this.Hash, hashedData, signature, nil) -} diff --git a/asymetric/rsaOaepEncrypter_test.go b/asymetric/rsaOaepEncrypter_test.go new file mode 100644 index 0000000..0042a8f --- /dev/null +++ b/asymetric/rsaOaepEncrypter_test.go @@ -0,0 +1,60 @@ +package asymetric + +import ( + _ "crypto/sha512" + + "crypto" + "crypto/rsa" + "testing" +) + +func TestRsaOaepEncrypt(t *testing.T) { + bobPrivKey, bobPubKey := generateKeyPair() + + r := &RsaOaepEncrypter{nil, bobPubKey, crypto.SHA384, random} + + ciphertext, err := r.Encrypt([]byte("this is a secret message")) + if err != nil { + t.Error(err) + return + } + orgTest, err := rsa.DecryptOAEP(crypto.SHA384.New(), random, bobPrivKey, ciphertext, []byte{}) + if err != nil { + t.Error(err) + return + } + if string(orgTest) != "this is a secret message" { + t.Error("the decryption of the message does not fit the original message") + } +} + +func TestRsaOaepEncryptDecrypt(t *testing.T) { + bobPrivKey, bobPubKey := generateKeyPair() + + message := "this is a secret message" + + rAlice := &RsaOaepEncrypter{nil, bobPubKey, crypto.SHA384, random} + rBob := &RsaOaepEncrypter{bobPrivKey, nil, crypto.SHA384, random} + + if ciphertext, err := rAlice.Encrypt([]byte(message)); err != nil { + t.Error(err) + return + } else if decryptedText, err := rBob.Decrypt(ciphertext); err != nil { + t.Error(err) + } else if string(decryptedText) != message { + t.Error("the decryption of the message does not fit the original message") + } +} + +func TestRsaOaepAvailableHashes(t *testing.T) { + hashes := map[crypto.Hash]bool{crypto.SHA224: true, crypto.SHA256: true, crypto.SHA384: true, crypto.SHA512: true} + var i crypto.Hash + for i = 0; i < 22; i++ { + r := &RsaOaepEncrypter{Hash: i} + if _, err := r.getHash(); err != nil && hashes[i] { + t.Error("should support", i, "hash type but does not") + } else if err == nil && !hashes[i] { + t.Error("should not support", i, "hash type but does") + } + } +} diff --git a/asymetric/rsaPssSigner.go b/asymetric/rsaPssSigner.go new file mode 100644 index 0000000..ea3948d --- /dev/null +++ b/asymetric/rsaPssSigner.go @@ -0,0 +1,37 @@ +package asymetric + +import ( + _ "crypto/sha256" + _ "crypto/sha512" + + "crypto" + "crypto/rsa" + "errors" + "fmt" + "io" +) + +type RsaPssSigner struct { + PrivateKey *rsa.PrivateKey + PublicKey *rsa.PublicKey + Hash crypto.Hash + + Random io.Reader +} + +func (this *RsaPssSigner) getHash() (crypto.Hash, error) { + if !this.Hash.Available() { + return 0, errors.New(fmt.Sprintf("hash function %v is unabailable", this.Hash)) + } else { + return this.Hash, nil + } +} + +func (this *RsaPssSigner) Sign(hashedData []byte) ([]byte, error) { + ret, err := rsa.SignPSS(this.Random, this.PrivateKey, this.Hash, hashedData, nil) + return ret, err +} + +func (this *RsaPssSigner) VerifySignature(hashedData []byte, signature []byte) error { + return rsa.VerifyPSS(this.PublicKey, this.Hash, hashedData, signature, nil) +} diff --git a/asymetric/rsaPssSigner_test.go b/asymetric/rsaPssSigner_test.go new file mode 100644 index 0000000..50f9a9f --- /dev/null +++ b/asymetric/rsaPssSigner_test.go @@ -0,0 +1,64 @@ +package asymetric + +import ( + _ "crypto/sha512" + + "crypto" + "crypto/rsa" + "testing" +) + +//var random = helper.NewMockRandomReader() + +//func generateKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) { +// if key, err := rsa.GenerateKey(random, 1024); err != nil { +// panic(err) +// } else { +// return key, &key.PublicKey +// } +//} + +func TestRsaPssSign(t *testing.T) { + alicePrivKey, alicePubKey := generateKeyPair() + h := crypto.SHA384.New() + h.Write([]byte("this is a secret message")) + hashedMessage := h.Sum(nil) + + rAlice := &RsaPssSigner{alicePrivKey, nil, crypto.SHA384, random} + signature, err := rAlice.Sign(hashedMessage) + if err != nil { + t.Error(err) + return + } + if err := rsa.VerifyPSS(alicePubKey, crypto.SHA384, hashedMessage, signature, nil); err != nil { + t.Error(err) + } +} + +func TestRsaPssSignAndVerify(t *testing.T) { + alicePrivKey, alicePubKey := generateKeyPair() + h := crypto.SHA384.New() + h.Write([]byte("this is a secret message")) + hashedMessage := h.Sum(nil) + + rAlice := &RsaPssSigner{alicePrivKey, nil, crypto.SHA384, random} + rBob := &RsaPssSigner{nil, alicePubKey, crypto.SHA384, random} + if signature, err := rAlice.Sign(hashedMessage); err != nil { + t.Error(err) + } else if err := rBob.VerifySignature(hashedMessage, signature); err != nil { + t.Error(err) + } +} + +func TestRsaPssAvailableHashes(t *testing.T) { + hashes := map[crypto.Hash]bool{crypto.SHA224: true, crypto.SHA256: true, crypto.SHA384: true, crypto.SHA512: true} + var i crypto.Hash + for i = 0; i < 22; i++ { + r := &RsaPssSigner{Hash: i} + if _, err := r.getHash(); err != nil && hashes[i] { + t.Error("should support", i, "hash type but does not") + } else if err == nil && !hashes[i] { + t.Error("should not support", i, "hash type but does") + } + } +} diff --git a/asymetric/rsaUtil_test.go b/asymetric/rsaUtil_test.go new file mode 100644 index 0000000..5e34252 --- /dev/null +++ b/asymetric/rsaUtil_test.go @@ -0,0 +1,19 @@ +package asymetric + +import ( + _ "crypto/sha512" + + "crypto/rsa" + + "github.com/didiercrunch/filou/helper" +) + +var random = helper.NewMockRandomReader() + +func generateKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) { + if key, err := rsa.GenerateKey(random, 1024); err != nil { + panic(err) + } else { + return key, &key.PublicKey + } +} diff --git a/asymetric/rsa_test.go b/asymetric/rsa_test.go deleted file mode 100644 index 9f300f2..0000000 --- a/asymetric/rsa_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package asymetric - -import ( - _ "crypto/sha512" - - "crypto" - "crypto/rsa" - "testing" - - "github.com/didiercrunch/filou/helper" -) - -var random = helper.NewMockRandomReader() - -func generateKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) { - if key, err := rsa.GenerateKey(random, 1024); err != nil { - panic(err) - } else { - return key, &key.PublicKey - } -} - -func TestEncrypt(t *testing.T) { - bobPrivKey, bobPubKey := generateKeyPair() - - r := &RsaOaepPss{nil, bobPubKey, crypto.SHA384, random} - - ciphertext, err := r.Encrypt([]byte("this is a secret message")) - if err != nil { - t.Error(err) - return - } - orgTest, err := rsa.DecryptOAEP(crypto.SHA384.New(), random, bobPrivKey, ciphertext, []byte{}) - if err != nil { - t.Error(err) - return - } - if string(orgTest) != "this is a secret message" { - t.Error("the decryption of the message does not fit the original message") - } -} - -func TestEncryptDecrypt(t *testing.T) { - bobPrivKey, bobPubKey := generateKeyPair() - - message := "this is a secret message" - - rAlice := &RsaOaepPss{nil, bobPubKey, crypto.SHA384, random} - rBob := &RsaOaepPss{bobPrivKey, nil, crypto.SHA384, random} - - if ciphertext, err := rAlice.Encrypt([]byte(message)); err != nil { - t.Error(err) - return - } else if decryptedText, err := rBob.Decrypt(ciphertext); err != nil { - t.Error(err) - } else if string(decryptedText) != message { - t.Error("the decryption of the message does not fit the original message") - } -} - -func TestSign(t *testing.T) { - alicePrivKey, alicePubKey := generateKeyPair() - h := crypto.SHA384.New() - h.Write([]byte("this is a secret message")) - hashedMessage := h.Sum(nil) - - rAlice := &RsaOaepPss{alicePrivKey, nil, crypto.SHA384, random} - signature, err := rAlice.Sign(hashedMessage) - if err != nil { - t.Error(err) - return - } - if err := rsa.VerifyPSS(alicePubKey, crypto.SHA384, hashedMessage, signature, nil); err != nil { - t.Error(err) - } -} - -func TestSignAndVerify(t *testing.T) { - alicePrivKey, alicePubKey := generateKeyPair() - h := crypto.SHA384.New() - h.Write([]byte("this is a secret message")) - hashedMessage := h.Sum(nil) - - rAlice := &RsaOaepPss{alicePrivKey, nil, crypto.SHA384, random} - rBob := &RsaOaepPss{nil, alicePubKey, crypto.SHA384, random} - if signature, err := rAlice.Sign(hashedMessage); err != nil { - t.Error(err) - } else if err := rBob.VerifySignature(hashedMessage, signature); err != nil { - t.Error(err) - } -} - -func TestAvailableHashes(t *testing.T) { - hashes := map[crypto.Hash]bool{crypto.SHA224: true, crypto.SHA256: true, crypto.SHA384: true, crypto.SHA512: true} - var i crypto.Hash - for i = 0; i < 22; i++ { - r := &RsaOaepPss{Hash: i} - if _, err := r.getHash(); err != nil && hashes[i] { - t.Error("should support", i, "hash type but does not") - } else if err == nil && !hashes[i] { - t.Error("should not support", i, "hash type but does") - } - } -} diff --git a/contract/contract_generators.go b/contract/contract_generators.go new file mode 100644 index 0000000..3d57d09 --- /dev/null +++ b/contract/contract_generators.go @@ -0,0 +1,98 @@ +package contract + +import ( + "crypto/rand" + "crypto/rsa" + "encoding/json" + "errors" + "os" + "path" + + "github.com/didiercrunch/filou/keys" + "github.com/didiercrunch/filou/shared" +) + +type ContractsGenerator struct { + publicKey *keys.RSAPublicKey + privateKey *keys.RSAPrivateKey + + privateContract *PrivateContract + publicContract *PublicContract +} + +func (this *ContractsGenerator) 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 *ContractsGenerator) saveContractAsJSON(contract interface{}, filepath string) error { + w, err := os.Create(filepath) + if err != nil { + return err + } + enc := json.NewEncoder(w) + return enc.Encode(contract) +} + +func (this *ContractsGenerator) saveContracts(dirPath string) error { + if err := this.ensureDirectoryExists(dirPath); err != nil { + return err + } + if err := this.saveContractAsJSON(this.publicContract, path.Join(dirPath, "public_contract.json")); err != nil { + return err + } + return this.saveContractAsJSON(this.privateContract, path.Join(dirPath, "private_contract.json")) +} + +func (this *ContractsGenerator) createRSAKeys(size int) error { + rsaPrivateKey, err := rsa.GenerateKey(rand.Reader, size) + if err != nil { + return errors.New("cannot generate the rsa public/private key pair\n" + err.Error()) + } + + this.privateKey = keys.NewRSAPrivateKey(rsaPrivateKey) + this.publicKey = keys.NewRSAPublicKey(&rsaPrivateKey.PublicKey) + return nil +} + +func (this *ContractsGenerator) createPrivateContractWithGoodDefaultValues(key *keys.RSAPrivateKey) { + this.privateContract = new(PrivateContract) + this.privateContract.AcceptedAsynchronousEncryptionScheme = []string{"rsa_oaep"} + this.privateContract.AcceptedSignatureScheme = []string{"rsa_pss"} + this.privateContract.AcceptedBlockCypherModes = []string{"ofb"} + this.privateContract.AcceptedBlockCyphers = []string{"aes"} + this.privateContract.RSAPrivateKey = []*keys.RSAPrivateKey{key} + this.privateContract.RSAPublicKey = []*keys.RSAPublicKey{} +} + +func (this *ContractsGenerator) createPublicContractWithGoodDefaultValues(key *keys.RSAPublicKey) { + this.publicContract = new(PublicContract) + this.privateContract.AcceptedAsynchronousEncryptionScheme = []string{"rsa_oaep"} + this.privateContract.AcceptedSignatureScheme = []string{"rsa_pss"} + this.privateContract.AcceptedBlockCypherModes = []string{"ofb"} + this.privateContract.AcceptedBlockCyphers = []string{"aes"} + this.privateContract.RSAPublicKey = []*keys.RSAPublicKey{key} +} + +func (this *ContractsGenerator) createContracts(keySize int) error { + if err := this.createRSAKeys(keySize); err != nil { + return err + } + this.createPrivateContractWithGoodDefaultValues(this.privateKey) + this.createPublicContractWithGoodDefaultValues(this.publicKey) + return nil +} + +func (this *ContractsGenerator) CreateContracts(size int) error { + if err := this.createContracts(size); err != nil { + return err + } + return this.saveContracts(shared.GetEcryptoDir()) +} diff --git a/contract/contract_generators_test.go b/contract/contract_generators_test.go new file mode 100644 index 0000000..2fa12db --- /dev/null +++ b/contract/contract_generators_test.go @@ -0,0 +1,73 @@ +package contract + +import ( + "encoding/json" + "io/ioutil" + "os" + "path" + "reflect" + "testing" +) + +func TestCreateRSAKey(t *testing.T) { + kc := new(ContractsGenerator) + if err := kc.createRSAKeys(100); err != nil { + t.Error(err) + } + if kc.privateKey == nil { + t.Fail() + } + if kc.publicKey == nil { + t.Fail() + } +} + +func TestSaveContractAsJSON(t *testing.T) { + cg := new(ContractsGenerator) + if err := cg.createContracts(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 := cg.saveContractAsJSON(cg.privateContract, file.Name()); err != nil { + t.Error(err) + } + data, err := ioutil.ReadFile(file.Name()) + if err != nil { + t.Error(err) + return + } + privC := new(PrivateContract) + if err := json.Unmarshal(data, privC); err != nil { + t.Error(err) + return + } + + if !reflect.DeepEqual(privC, cg.privateContract) { + t.Fail() + } +} + +func TestEnsureDirectoryExists(t *testing.T) { + kc := new(ContractsGenerator) + 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) + } + +} diff --git a/files/encrypt_file.go b/files/encrypt_file.go index 386ddfc..9e8f0de 100644 --- a/files/encrypt_file.go +++ b/files/encrypt_file.go @@ -3,18 +3,38 @@ package files import ( "io" + "github.com/didiercrunch/filou/asymetric" "github.com/didiercrunch/filou/contract" "github.com/didiercrunch/filou/envelop" + "github.com/didiercrunch/filou/helper" "github.com/didiercrunch/filou/payload" ) +func getEncryptorAndSigner(acceptedContract *contract.AcceptedContract) (asymetric.PublicKeyEncryptor, asymetric.Signer, error) { + errs := make([]error, 0, 2) + signer, err := asymetric.GetSigner(acceptedContract) + if err != nil { + errs = append(errs, err) + } + + encryptor, err := asymetric.GetPublicKeyEncryptor(acceptedContract) + if err != nil { + errs = append(errs, err) + } + return encryptor, signer, helper.JoinErrors(errs) +} + func EncryptFile(reader io.Reader, writer io.Writer, acceptedContract *contract.AcceptedContract) error { + encryptor, signer, err := getEncryptorAndSigner(acceptedContract) + if err != nil { + return err + } + payload_, err := payload.GetPayload(reader, acceptedContract) if err != nil { return err } - //signer := - envelop := envelop.NewEnveloper(nil, payload_, nil) + envelop := envelop.NewEnveloper(encryptor, payload_, signer) return envelop.WriteToWriter(writer) } diff --git a/files/encrypt_file_test.go b/files/encrypt_file_test.go new file mode 100644 index 0000000..c21c873 --- /dev/null +++ b/files/encrypt_file_test.go @@ -0,0 +1,3 @@ +package files + + diff --git a/helper/helper.go b/helper/helper.go index 5ef16de..698b96c 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -1,6 +1,7 @@ package helper import ( + "crypto" "errors" "strings" ) @@ -21,3 +22,29 @@ func JoinErrors(errs []error) error { } return JoinAsError(msgs) } + +func GetHashFunctionByLowerCaseName(hashName string) (crypto.Hash, error) { + switch hashName { + case "md4": + return crypto.MD4, nil + case "md5": + return crypto.MD5, nil + case "sha1": + return crypto.SHA1, nil + case "sha224": + return crypto.SHA224, nil + case "sha256": + return crypto.SHA256, nil + case "sha384": + return crypto.SHA384, nil + case "sha512": + return crypto.SHA512, nil + case "md5sha1": + return crypto.MD5SHA1, nil + case "ripemd160": + return crypto.RIPEMD160, nil + default: + return 0, errors.New("unknown lowercase hash " + hashName) + + } +} diff --git a/helper/helper_test.go b/helper/helper_test.go index 6d9085e..1b0c622 100644 --- a/helper/helper_test.go +++ b/helper/helper_test.go @@ -1,6 +1,7 @@ package helper import ( + "crypto" "errors" "testing" ) @@ -36,3 +37,24 @@ func TestJoinErrors(t *testing.T) { t.Error("bad error") } } + +func TestGetHashFunctionByLowerCaseName(t *testing.T) { + m := map[string]crypto.Hash{ + "md4": crypto.MD4, + "md5": crypto.MD5, + "sha1": crypto.SHA1, + "sha224": crypto.SHA224, + "sha256": crypto.SHA256, + "sha384": crypto.SHA384, + "sha512": crypto.SHA512, + "md5sha1": crypto.MD5SHA1, + "ripemd160": crypto.RIPEMD160, + } + for hashName, exptedHash := range m { + if hash, err := GetHashFunctionByLowerCaseName(hashName); err != nil { + t.Error(err) + } else if hash != exptedHash { + t.Error("bad hash found for ", hashName) + } + } +} diff --git a/integration/enveloppayload_test.go b/integration/enveloppayload_test.go index d585822..e28b74c 100644 --- a/integration/enveloppayload_test.go +++ b/integration/enveloppayload_test.go @@ -23,16 +23,23 @@ func generateRSAKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) { } } -func getEncryterAndSigner() *asymetric.RsaOaepPss { +func getEncryter() *asymetric.RsaOaepEncrypter { alicePrivateKey, _ := generateRSAKeyPair() _, bobPubKey := generateRSAKeyPair() - return &asymetric.RsaOaepPss{alicePrivateKey, bobPubKey, crypto.SHA512, random} + return &asymetric.RsaOaepEncrypter{alicePrivateKey, bobPubKey, crypto.SHA512, random} +} + +func getSigner() *asymetric.RsaPssSigner { + alicePrivateKey, _ := generateRSAKeyPair() + _, bobPubKey := generateRSAKeyPair() + return &asymetric.RsaPssSigner{alicePrivateKey, bobPubKey, crypto.SHA512, random} } func TestPayloadCanBeUseInEnvelop(t *testing.T) { - encryterAndSigner := getEncryterAndSigner() + encrypter := getEncryter() + signer := getSigner() payload_ := payload.GetDefaultPayload(bytes.NewBufferString("some data to encrypt")) - envelop := envelop.NewEnveloper(encryterAndSigner, payload_, encryterAndSigner) + envelop := envelop.NewEnveloper(encrypter, payload_, signer) w := helper.NewMockIoWriter() if err := envelop.WriteToWriter(w); err != nil { t.Error(err) diff --git a/keys/keys.go b/keys/keys.go index 659a61f..5de090b 100644 --- a/keys/keys.go +++ b/keys/keys.go @@ -56,11 +56,19 @@ func GetDefaultRSAPublicKey(publicKey *rsa.PublicKey) *PublicKey { return &PublicKey{Type: "RSA", Version: shared.VERSION, Key: key, Accept: accept} } -func GetDefaultRSAPrivateKey(publicKey *rsa.PrivateKey) (*PrivateKey, error) { - if err := publicKey.Validate(); err != nil { +func NewRSAPublicKey(key *rsa.PublicKey) *RSAPublicKey { + return &RSAPublicKey{key.N, key.E} +} + +func NewRSAPrivateKey(key *rsa.PrivateKey) *RSAPrivateKey { + return &RSAPrivateKey{key.N, key.Primes[0], key.Primes[1], key.D, key.E} +} + +func GetDefaultRSAPrivateKey(privateKey *rsa.PrivateKey) (*PrivateKey, error) { + if err := privateKey.Validate(); err != nil { return nil, err } - key := &RSAPrivateKey{publicKey.N, publicKey.Primes[0], publicKey.Primes[1], publicKey.D, publicKey.E} + key := NewRSAPrivateKey(privateKey) accept := &AcceptMethods{ DEFAULT_BLOCK_CYPHER, DEFAULT_BLOCK_CYPHER_MODE,