John starr rocks!

This commit is contained in:
didier.amyot committed 2014-10-31 16:51:49 -07:00
1 parent d2cd50b2e3
commit 0095eb7159
12 files changed
+343 -9

No files matched your search

+59
View File
@@ -0,0 +1,59 @@
package asymetric
import (
_ "crypto/sha256"
_ "crypto/sha512"
"crypto"
"crypto/rsa"
"errors"
"fmt"
"io"
)
type RsaOaepPss struct {
PrivateKey *rsa.PrivateKey
PublicKey *rsa.PublicKey
Hash crypto.Hash
Random io.Reader
}
func (this *RsaOaepPss) 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 *RsaOaepPss) Encrypt(data []byte) ([]byte, error) {
label := make([]byte, 0)
if hash, err := this.getHash(); err != nil {
return nil, err
} else {
return rsa.EncryptOAEP(hash.New(), this.Random, this.PublicKey, data, label)
}
}
func (this *RsaOaepPss) Decrypt(ciphertext []byte) ([]byte, error) {
label := make([]byte, 0)
if hash, err := this.getHash(); err != nil {
return nil, err
} else {
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)
if err != nil {
fmt.Println(">>> ", len(hashedData))
}
return ret, err
}
func (this *RsaOaepPss) VerifySignature(hashedData []byte, signature []byte) error {
return rsa.VerifyPSS(this.PublicKey, this.Hash, hashedData, signature, nil)
}
+104
View File
@@ -0,0 +1,104 @@
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")
}
}
}
+10
View File
@@ -0,0 +1,10 @@
package contract
import (
"github.com/didiercrunch/filou/keys"
)
type PrivateContract struct {
PublicContract
RSAPrivateKey []*keys.RSAPrivateKey `yaml:"rsa_private_key,omitempty" json:"rsa_private_key,omitempty"`
}
+11
View File
@@ -0,0 +1,11 @@
package contract
import (
"github.com/didiercrunch/filou/keys"
)
type PublicContract struct {
AcceptedHashes []string `yaml:"accepted_hashes" json:"accepted_hashes"`
AcceptedBlockCypher []string `yaml:"accepted_block_cypher" json:"accepted_block_cypher"`
RSAPublicKey []*keys.RSAPublicKey `yaml:"rsa_public_key, omitempty" json:"rsa_public_key,omitempty"`
}
+63
View File
@@ -0,0 +1,63 @@
package contract
import (
"encoding/json"
"errors"
"fmt"
"reflect"
"testing"
"github.com/didiercrunch/filou/helper"
"github.com/didiercrunch/filou/keys"
)
func assertJSONMarshalling(c *PublicContract) error {
ret := new(PublicContract)
if data, err := json.Marshal(c); err != nil {
return err
} else if err = json.Unmarshal(data, ret); err != nil {
return err
} else if !reflect.DeepEqual(ret, c) {
fmt.Println(string(data))
return errors.New("bad serisalization")
}
return nil
}
func expectJson(c *PublicContract, jsonData string) error {
ret := new(PublicContract)
if err := json.Unmarshal([]byte(jsonData), ret); err != nil {
return err
} else if !reflect.DeepEqual(ret.RSAPublicKey, c.RSAPublicKey) {
return errors.New("bad serisalization")
}
return nil
}
func TestSimpleJsonification(t *testing.T) {
c := &PublicContract{
AcceptedHashes: []string{"sha246"},
AcceptedBlockCypher: []string{"aes"},
RSAPublicKey: []*keys.RSAPublicKey{&keys.RSAPublicKey{helper.B(12), 3}},
}
if err := assertJSONMarshalling(c); err != nil {
t.Error(err)
}
}
func TestEmptyRSAPublicKey(t *testing.T) {
c := &PublicContract{
AcceptedHashes: []string{"sha246"},
AcceptedBlockCypher: []string{"aes"},
RSAPublicKey: []*keys.RSAPublicKey{&keys.RSAPublicKey{helper.B(12), 3}},
}
jsonData := `{
"accepted_hashes": ["sha246"],
"accepted_block_cypher": ["aes"],
"rsa_public_key": [{"n": "c", "e": 3}]
}`
if err := expectJson(c, jsonData); err != nil {
t.Error(err)
}
}
+42
View File
@@ -1,4 +1,46 @@
### public contract
A public contract is the information a user publish to allow anybody to send
him encrypted files. Of course the public contract contains the user
public key but it contains much more.
The contract itself does not need to be sign. The signature is level of
complexity above the public contract
~~~
---
# example of a contract
name: john dear
organizarion: JohnDeer corporation
email: johndear@johndeer.co
url: "the url where to fiofbnd an exact copy of the contract"
root_url: "the url where to find the most up to date version of the contract"
accepted_hashs:
- sha512
accepted_block_cypher:
- aes
accepted_modes:
- ofb
signatures_required: yes
rsa_public_keys:
-
n: "hexadecimal n"
e: 3424
~~~
### public key ### public key
Note that any private key are a public key. Note that any private key are a public key.
+6 -1
View File
@@ -105,7 +105,12 @@ func (this *Enveloper) WriteEncryptedKey(z *zip.Writer) error {
func (this *Enveloper) WriteToWriter(w io.Writer) error { func (this *Enveloper) WriteToWriter(w io.Writer) error {
z := zip.NewWriter(w) z := zip.NewWriter(w)
defer z.Close() defer z.Close()
if err := this.WritePayload(z); err != nil { errc := make(chan error)
go func() {
errc <- this.WritePayload(z)
}()
if err := <-errc; err != nil {
return err return err
} }
if err := this.CreateEnvelopCompletely(); err != nil { if err := this.CreateEnvelopCompletely(); err != nil {
+9
View File
@@ -0,0 +1,9 @@
package integration
import (
"testing"
)
func TestEnvelop(t *testing.T) {
}
+22 -1
View File
@@ -3,8 +3,11 @@ package integration
import ( import (
"archive/zip" "archive/zip"
"bytes" "bytes"
"crypto"
"crypto/rsa"
"testing" "testing"
"github.com/didiercrunch/filou/asymetric"
"github.com/didiercrunch/filou/envelop" "github.com/didiercrunch/filou/envelop"
"github.com/didiercrunch/filou/helper" "github.com/didiercrunch/filou/helper"
"github.com/didiercrunch/filou/payload" "github.com/didiercrunch/filou/payload"
@@ -23,6 +26,22 @@ func (this *mockEncryptor) Encrypt(data []byte) ([]byte, error) {
type mockSigner struct{} type mockSigner struct{}
var random = helper.NewMockRandomReader()
func generateRSAKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) {
if key, err := rsa.GenerateKey(random, 2048); err != nil {
panic(err)
} else {
return key, &key.PublicKey
}
}
func getEncryterAndSigner() *asymetric.RsaOaepPss {
alicePrivateKey, _ := generateRSAKeyPair()
_, bobPubKey := generateRSAKeyPair()
return &asymetric.RsaOaepPss{alicePrivateKey, bobPubKey, crypto.SHA512, random}
}
func (this *mockSigner) Sign(data []byte) ([]byte, error) { func (this *mockSigner) Sign(data []byte) ([]byte, error) {
// a slice with the sum of the data plus a "secret" value // a slice with the sum of the data plus a "secret" value
var sum byte = 36 var sum byte = 36
@@ -33,11 +52,13 @@ func (this *mockSigner) Sign(data []byte) ([]byte, error) {
} }
func TestPayloadCanBeUseInEnvelop(t *testing.T) { func TestPayloadCanBeUseInEnvelop(t *testing.T) {
encryterAndSigner := getEncryterAndSigner()
payload_ := payload.GetDefaultPayload(bytes.NewBufferString("some data to encrypt")) payload_ := payload.GetDefaultPayload(bytes.NewBufferString("some data to encrypt"))
envelop := envelop.NewEnveloper(&mockEncryptor{}, payload_, &mockSigner{}) envelop := envelop.NewEnveloper(encryterAndSigner, payload_, encryterAndSigner)
w := helper.NewMockIoWriter() w := helper.NewMockIoWriter()
if err := envelop.WriteToWriter(w); err != nil { if err := envelop.WriteToWriter(w); err != nil {
t.Error(err) t.Error(err)
return
} }
r, err := zip.NewReader(w.ReaderAt(), int64(w.Length())) r, err := zip.NewReader(w.ReaderAt(), int64(w.Length()))
if err != nil { if err != nil {
+5 -5
View File
@@ -10,11 +10,11 @@ import (
// All the method to encode/decode keys to json, yaml... // All the method to encode/decode keys to json, yaml...
type encodingRSAKey struct { type encodingRSAKey struct {
N string N string `json:"n,omitempty"`
P string P string `json:"p,omitempty"`
Q string Q string `json:"q,omitempty"`
D string D string `json:"d,omitempty"`
E int E int `json:"e,omitempty"`
} }
func (this *encodingRSAKey) CreateFromRSAPrivateKey(key *RSAPrivateKey) *encodingRSAKey { func (this *encodingRSAKey) CreateFromRSAPrivateKey(key *RSAPrivateKey) *encodingRSAKey {
+12
View File
@@ -41,3 +41,15 @@ func TestRSAPublicKeyJsonification(t *testing.T) {
t.Fail() t.Fail()
} }
} }
func TestRSAPublicKeyJsonificationFromString(t *testing.T) {
data := []byte(`{"N":"3ff","E":89}`)
key := new(RSAPublicKey)
if err := json.Unmarshal(data, key); err != nil {
t.Error(err)
return
}
if !reflect.DeepEqual(key, &RSAPublicKey{B(1023), 89}) {
t.Fail()
}
}
-2
View File
@@ -137,7 +137,6 @@ func (this *Payload) computeHash(reader io.Reader) (io.Reader, error) {
}(readerHash) }(readerHash)
return read, nil return read, nil
} }
func (this *Payload) encrypt(reader io.Reader, stream cipher.Stream) (io.Reader, error) { func (this *Payload) encrypt(reader io.Reader, stream cipher.Stream) (io.Reader, error) {
@@ -148,5 +147,4 @@ func (this *Payload) encrypt(reader io.Reader, stream cipher.Stream) (io.Reader,
cipherWriter.Close() cipherWriter.Close()
}(stream) }(stream)
return this.computeHash(ret) return this.computeHash(ret)
} }