add all
This commit is contained in:
1 parent
4897e8d307
commit
4aca3324c9
10 files changed
+401
-17
No files matched your search
+16
-17
@@ -18,35 +18,34 @@ else than a zip file containing the following shit.
|
|||||||
* mode
|
* mode
|
||||||
* encrypted symetric key
|
* encrypted symetric key
|
||||||
* hash of the encrypted data (always use full for validation)
|
* hash of the encrypted data (always use full for validation)
|
||||||
3. a 'signature' file with the signature of the `meta_data.yml` filefunc (this *RsaSha512) encrypt() ([]byte, error) {
|
3. a 'signature' file with the signature of the `meta_data.yml` file
|
||||||
|
func (this *RsaSha512) encrypt() ([]byte, error) {}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
_____________________________________________________________________
|
_____________________________________________________________________________
|
||||||
|
|
|
|
||||||
| Envelop: zip file, no compression, no encryption
|
| Envelop: zip file, no compression, no encryption
|
||||||
| _________________________________________________________________
|
|
||||||
| |
|
|
||||||
| | Paiload key: cyphered by target pulic key
|
|
||||||
| |______________________________________________________________
|
|
||||||
|
|
|
||||||
| _____________________________________________________________________
|
|
||||||
| |
|
|
||||||
| | Envelop meta data: encryption type, mode, Paiload signature (yaml)
|
|
||||||
| |________________________________________________________________________
|
|
||||||
|
|
|
||||||
| ________________________________________________________________________
|
| ________________________________________________________________________
|
||||||
| |
|
| |
|
||||||
|
| | Paiload key: cyphered by target pulic key
|
||||||
|
| |________________________________________________________________________
|
||||||
|
|
|
||||||
|
| _________________________________________________________________________
|
||||||
|
| |
|
||||||
|
| | Envelop meta data: encryption type, mode, Paiload signature (yaml)
|
||||||
|
| |__________________________________________________________________________
|
||||||
|
|
|
||||||
|
| __________________________________________________________________________
|
||||||
|
| |
|
||||||
| | Paiload: Zip file, no compression, symetrcally encrypted
|
| | Paiload: Zip file, no compression, symetrcally encrypted
|
||||||
| | _________________________________________________________________
|
| | _____________________________________________________________________
|
||||||
| | |
|
| | |
|
||||||
| | | paiload intern metadata: Data signature, sender, message,...
|
| | | paiload intern metadata: Data signature, sender, message,...
|
||||||
| | |_________________________________________________________________
|
| | |______________________________________________________________________
|
||||||
| |
|
| |
|
||||||
| | _________________________________________________________________
|
| | _______________________________________________________________________
|
||||||
| | |
|
| | |
|
||||||
| | | Data: Zip file, high compression
|
| | | Data: Zip file, high compression
|
||||||
| | |
|
| | |
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package envelop
|
||||||
|
|
||||||
|
/*
|
||||||
|
This package containes everything to create an envelop around a payload
|
||||||
|
*/
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package envelop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Payload interface {
|
||||||
|
GetHash() []byte
|
||||||
|
GetKey() []byte
|
||||||
|
GetAlgorithm() string
|
||||||
|
GetMode() string
|
||||||
|
GetHashMethod() string
|
||||||
|
GetPayloadData() io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
type Encryptor interface {
|
||||||
|
Encrypt(data []byte) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Signer interface {
|
||||||
|
Sign(data []byte) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Enveloper struct {
|
||||||
|
encryptor Encryptor
|
||||||
|
payload Payload
|
||||||
|
signer Signer
|
||||||
|
EncryptedKey []byte
|
||||||
|
Signature []byte
|
||||||
|
Metadata *Metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) EncryptKey() ([]byte, error) {
|
||||||
|
return this.encryptor.Encrypt(this.payload.GetKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) SignPayload() ([]byte, error) {
|
||||||
|
return this.signer.Sign(this.payload.GetHash())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) CreateMetadata() *Metadata {
|
||||||
|
md := new(Metadata)
|
||||||
|
md.BlockAlgorithm = this.payload.GetAlgorithm()
|
||||||
|
md.BlockMode = this.payload.GetMode()
|
||||||
|
md.SignatureAlgorithm = "RSAPSS"
|
||||||
|
md.HashMethod = this.payload.GetHashMethod()
|
||||||
|
return md
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) CreateEnvelopCompletely() error {
|
||||||
|
var err error
|
||||||
|
if this.EncryptedKey, err = this.EncryptKey(); err != nil {
|
||||||
|
return err
|
||||||
|
} else if this.Signature, err = this.SignPayload(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
this.Metadata = this.CreateMetadata()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) WritePayload(z *zip.Writer) error {
|
||||||
|
dataWriter, err := z.Create("data")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(dataWriter, this.payload.GetPayloadData())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) WriteMetadata(z *zip.Writer) error {
|
||||||
|
dataWriter, err := z.Create("metadata.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
encoder := json.NewEncoder(dataWriter)
|
||||||
|
return encoder.Encode(this.Metadata)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) WriteEncryptedKey(z *zip.Writer) error {
|
||||||
|
dataWriter, err := z.Create("key.json")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
encoder := json.NewEncoder(dataWriter)
|
||||||
|
return encoder.Encode(&struct {
|
||||||
|
Key string
|
||||||
|
}{fmt.Sprintf("%s", this.EncryptedKey)})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Enveloper) WriteToWriter(w io.Writer) error {
|
||||||
|
z := zip.NewWriter(w)
|
||||||
|
defer z.Close()
|
||||||
|
if err := this.WritePayload(z); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := this.WriteMetadata(z); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := this.WriteEncryptedKey(z); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package envelop
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"bytes"
|
||||||
|
"github.com/didiercrunch/ecrypto/helper"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockPayload struct{}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetKey() []byte {
|
||||||
|
return []byte{1, 2, 3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetHash() []byte {
|
||||||
|
return []byte{10, 9, 8}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetAlgorithm() string {
|
||||||
|
symetricEncryptionAlgorithm := "DES"
|
||||||
|
return symetricEncryptionAlgorithm
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetMode() string {
|
||||||
|
symetricEncryptionMode := "OFB"
|
||||||
|
return symetricEncryptionMode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetHashMethod() string {
|
||||||
|
theHashMethodUsedInThePayLoad := "SHA1"
|
||||||
|
return theHashMethodUsedInThePayLoad
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *mockPayload) GetPayloadData() io.Reader {
|
||||||
|
someData := `some data must be here. In reality, the data
|
||||||
|
would be the encrypted payload. This will be
|
||||||
|
the big chunk of the data.
|
||||||
|
`
|
||||||
|
return bytes.NewReader([]byte(someData))
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockEncryptor struct{}
|
||||||
|
|
||||||
|
func (this *mockEncryptor) Encrypt(data []byte) ([]byte, error) {
|
||||||
|
// cesar encryption!
|
||||||
|
ret := make([]byte, len(data))
|
||||||
|
for i, d := range data {
|
||||||
|
ret[i] = d + 3 // modulo is implicit
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockSigner struct{}
|
||||||
|
|
||||||
|
func (this *mockSigner) Sign(data []byte) ([]byte, error) {
|
||||||
|
// a slice with the sum of the data plus a "secret" value
|
||||||
|
var sum byte = 36
|
||||||
|
for _, d := range data {
|
||||||
|
sum += d
|
||||||
|
}
|
||||||
|
return []byte{sum}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEncryptKey(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
encryptor: &mockEncryptor{},
|
||||||
|
payload: &mockPayload{},
|
||||||
|
}
|
||||||
|
if enc, err := env.EncryptKey(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if !reflect.DeepEqual(enc, []byte{1 + 3, 2 + 3, 3 + 3}) {
|
||||||
|
t.Error("bad signature")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateEnvelopCompletelyEncryptKey(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
encryptor: &mockEncryptor{},
|
||||||
|
payload: &mockPayload{},
|
||||||
|
signer: &mockSigner{},
|
||||||
|
}
|
||||||
|
if err := env.CreateEnvelopCompletely(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(env.EncryptedKey, []byte{1 + 3, 2 + 3, 3 + 3}) {
|
||||||
|
t.Error("CreateEnvelopCompletely has not encrypted the key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignPayload(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
signer: &mockSigner{},
|
||||||
|
payload: &mockPayload{},
|
||||||
|
}
|
||||||
|
if sign, err := env.SignPayload(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if !reflect.DeepEqual([]byte{10 + 9 + 8 + 36}, sign) {
|
||||||
|
t.Error("bad signature")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateEnvelopCompletelySignHash(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
payload: &mockPayload{},
|
||||||
|
encryptor: &mockEncryptor{},
|
||||||
|
signer: &mockSigner{},
|
||||||
|
}
|
||||||
|
if err := env.CreateEnvelopCompletely(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(env.Signature, []byte{10 + 9 + 8 + 36}) {
|
||||||
|
t.Error("CreateEnvelopCompletely has not signature")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateMetadata(t *testing.T) {
|
||||||
|
env := &Enveloper{payload: &mockPayload{}}
|
||||||
|
exptectedMetaData := &Metadata{
|
||||||
|
BlockAlgorithm: "DES",
|
||||||
|
BlockMode: "OFB",
|
||||||
|
SignatureAlgorithm: "RSAPSS",
|
||||||
|
HashMethod: "SHA1",
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := env.CreateMetadata(); !reflect.DeepEqual(m, exptectedMetaData) {
|
||||||
|
t.Error("bad meta data")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreateEnvelopCompletelyMetadata(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
encryptor: &mockEncryptor{},
|
||||||
|
payload: &mockPayload{},
|
||||||
|
signer: &mockSigner{},
|
||||||
|
}
|
||||||
|
if err := env.CreateEnvelopCompletely(); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if env.Metadata == nil || env.Metadata.HashMethod != "SHA1" {
|
||||||
|
t.Error("CreateEnvelopCompletely has not created metadata")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteToWriter(t *testing.T) {
|
||||||
|
env := &Enveloper{
|
||||||
|
payload: &mockPayload{},
|
||||||
|
}
|
||||||
|
w := helper.NewMockIoWriter()
|
||||||
|
if err := env.WriteToWriter(w); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
r, err := zip.NewReader(w.ReaderAt(), int64(w.Length()))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(r.File) != 3 {
|
||||||
|
t.Error("wrong file number")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package envelop
|
||||||
|
|
||||||
|
type Metadata struct {
|
||||||
|
BlockMode string
|
||||||
|
BlockAlgorithm string
|
||||||
|
SignatureAlgorithm string
|
||||||
|
HashMethod string
|
||||||
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
)
|
)
|
||||||
@@ -64,6 +66,14 @@ func (this *MockIoWriter) Bytes() []byte {
|
|||||||
return this.state
|
return this.state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) Reader() io.Reader {
|
||||||
|
return bytes.NewReader(this.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *MockIoWriter) ReaderAt() io.ReaderAt {
|
||||||
|
return bytes.NewReader(this.state)
|
||||||
|
}
|
||||||
|
|
||||||
func Range(length int) []byte {
|
func Range(length int) []byte {
|
||||||
ret := make([]byte, length)
|
ret := make([]byte, length)
|
||||||
for i, _ := range ret {
|
for i, _ := range ret {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package helper
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -35,6 +36,10 @@ func TestMockIoWriter(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
} else if w.Length() != len("something to write") {
|
} else if w.Length() != len("something to write") {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
|
} else if readerOutput, err := ioutil.ReadAll(w.Reader()); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
} else if "something to write" != string(readerOutput) {
|
||||||
|
t.Error("bad reader")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package payload
|
||||||
|
|
||||||
|
/*
|
||||||
|
This package is contains everything to create the payload.
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package payload
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/cipher"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
type Payload interface {
|
||||||
|
GetHash() []byte
|
||||||
|
GetKey() []byte
|
||||||
|
GetAlgorithm() string
|
||||||
|
GetMode() string
|
||||||
|
GetHashMethod() string
|
||||||
|
GetPayloadData() io.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Payload struct {
|
||||||
|
DataSource io.Reader
|
||||||
|
Hash crypto.Hash
|
||||||
|
Block cipher.Block
|
||||||
|
BlockMode cipher.BlockMode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Payload) GetHashMethod() string {
|
||||||
|
switch this.Hash {
|
||||||
|
case crypto.MD5:
|
||||||
|
return "md5"
|
||||||
|
case crypto.MD4:
|
||||||
|
return "md4"
|
||||||
|
case crypto.SHA1:
|
||||||
|
return "sha1"
|
||||||
|
case crypto.MD5SHA1:
|
||||||
|
return "md5sha1"
|
||||||
|
case crypto.RIPEMD160:
|
||||||
|
return "ripemd160"
|
||||||
|
case crypto.SHA224:
|
||||||
|
return "sha224"
|
||||||
|
case crypto.SHA256:
|
||||||
|
return "sha256"
|
||||||
|
case crypto.SHA384:
|
||||||
|
return "sha384"
|
||||||
|
case crypto.SHA512:
|
||||||
|
return "sha512"
|
||||||
|
default:
|
||||||
|
panic("unknown hash method")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *Payload) GetPayloadData() io.Reader {
|
||||||
|
// this.BlockMode.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package payload
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPayloadGetHashMethod(t *testing.T) {
|
||||||
|
p := new(Payload)
|
||||||
|
testCases := make(map[string]crypto.Hash)
|
||||||
|
testCases["md4"] = crypto.MD4
|
||||||
|
testCases["md5"] = crypto.MD5
|
||||||
|
testCases["sha1"] = crypto.SHA1
|
||||||
|
testCases["sha224"] = crypto.SHA224
|
||||||
|
testCases["sha256"] = crypto.SHA256
|
||||||
|
testCases["sha384"] = crypto.SHA384
|
||||||
|
testCases["sha512"] = crypto.SHA512
|
||||||
|
testCases["md5sha1"] = crypto.MD5SHA1
|
||||||
|
testCases["ripemd160"] = crypto.RIPEMD160
|
||||||
|
for name, hashfunc := range testCases {
|
||||||
|
p.Hash = hashfunc
|
||||||
|
if returnedName := p.GetHashMethod(); returnedName != name {
|
||||||
|
t.Error("bad hash name. supposed to be ", name, " but received", returnedName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in new issue
Block a user