John starr rocks!
This commit is contained in:
1 parent
d2cd50b2e3
commit
0095eb7159
12 files changed
+343
-9
No files matched your search
@@ -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)
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
Note that any private key are a public key.
|
||||
|
||||
|
||||
+6
-1
@@ -105,7 +105,12 @@ func (this *Enveloper) WriteEncryptedKey(z *zip.Writer) error {
|
||||
func (this *Enveloper) WriteToWriter(w io.Writer) error {
|
||||
z := zip.NewWriter(w)
|
||||
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
|
||||
}
|
||||
if err := this.CreateEnvelopCompletely(); err != nil {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEnvelop(t *testing.T) {
|
||||
|
||||
}
|
||||
@@ -3,8 +3,11 @@ package integration
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"testing"
|
||||
|
||||
"github.com/didiercrunch/filou/asymetric"
|
||||
"github.com/didiercrunch/filou/envelop"
|
||||
"github.com/didiercrunch/filou/helper"
|
||||
"github.com/didiercrunch/filou/payload"
|
||||
@@ -23,6 +26,22 @@ func (this *mockEncryptor) Encrypt(data []byte) ([]byte, error) {
|
||||
|
||||
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) {
|
||||
// a slice with the sum of the data plus a "secret" value
|
||||
var sum byte = 36
|
||||
@@ -33,11 +52,13 @@ func (this *mockSigner) Sign(data []byte) ([]byte, error) {
|
||||
}
|
||||
|
||||
func TestPayloadCanBeUseInEnvelop(t *testing.T) {
|
||||
encryterAndSigner := getEncryterAndSigner()
|
||||
payload_ := payload.GetDefaultPayload(bytes.NewBufferString("some data to encrypt"))
|
||||
envelop := envelop.NewEnveloper(&mockEncryptor{}, payload_, &mockSigner{})
|
||||
envelop := envelop.NewEnveloper(encryterAndSigner, payload_, encryterAndSigner)
|
||||
w := helper.NewMockIoWriter()
|
||||
if err := envelop.WriteToWriter(w); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
r, err := zip.NewReader(w.ReaderAt(), int64(w.Length()))
|
||||
if err != nil {
|
||||
|
||||
+5
-5
@@ -10,11 +10,11 @@ import (
|
||||
// All the method to encode/decode keys to json, yaml...
|
||||
|
||||
type encodingRSAKey struct {
|
||||
N string
|
||||
P string
|
||||
Q string
|
||||
D string
|
||||
E int
|
||||
N string `json:"n,omitempty"`
|
||||
P string `json:"p,omitempty"`
|
||||
Q string `json:"q,omitempty"`
|
||||
D string `json:"d,omitempty"`
|
||||
E int `json:"e,omitempty"`
|
||||
}
|
||||
|
||||
func (this *encodingRSAKey) CreateFromRSAPrivateKey(key *RSAPrivateKey) *encodingRSAKey {
|
||||
|
||||
@@ -41,3 +41,15 @@ func TestRSAPublicKeyJsonification(t *testing.T) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -137,7 +137,6 @@ func (this *Payload) computeHash(reader io.Reader) (io.Reader, error) {
|
||||
}(readerHash)
|
||||
|
||||
return read, nil
|
||||
|
||||
}
|
||||
|
||||
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()
|
||||
}(stream)
|
||||
return this.computeHash(ret)
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user