Skip to content

Commit

Permalink
added kid and alg to cipher and db packages (#55)
Browse files Browse the repository at this point in the history
* added kid and alg to cipher and db packages

* adding basic logger

* Revert "adding basic logger"

This reverts commit 9f175bd.

* passing logger

* merging rsaEncrypter struct and rsaDecrypter struct

* adding algorithm to Ciphers Get()

* adding ParseAlogrithmType

* making Options of Ciphers public for testing
  • Loading branch information
kcajmagic authored Apr 17, 2019
1 parent 2805ecc commit 4f3e41e
Show file tree
Hide file tree
Showing 19 changed files with 496 additions and 213 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
- Added kid and alg to `db` package
- Updated loading cipher options

## [v0.3.3]
- Fix box loader in `cipher` package
Expand Down
38 changes: 38 additions & 0 deletions cipher/algo_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2019 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package cipher

type AlgorithmType string

const (
None AlgorithmType = "none"
Box AlgorithmType = "box"
RSASymmetric AlgorithmType = "rsa-sym"
RSAAsymmetric AlgorithmType = "rsa-asy"
)

func ParseAlogrithmType(algo string) AlgorithmType {
if algo == string(Box) {
return Box
} else if algo == string(RSASymmetric) {
return RSASymmetric
} else if algo == string(RSAAsymmetric) {
return RSAAsymmetric
}
return None
}
5 changes: 3 additions & 2 deletions cipher/boxLoader.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
)

type BoxLoader struct {
KID string
PrivateKey KeyLoader
PublicKey KeyLoader
}
Expand Down Expand Up @@ -65,7 +66,7 @@ func (boxLoader *BoxLoader) LoadEncrypt() (Encrypt, error) {
if err != nil {
return nil, err
}
return NewBoxEncrypter(privateKey, publicKey), nil
return NewBoxEncrypter(privateKey, publicKey, boxLoader.KID), nil
}

func (boxLoader *BoxLoader) LoadDecrypt() (Decrypt, error) {
Expand All @@ -78,5 +79,5 @@ func (boxLoader *BoxLoader) LoadDecrypt() (Decrypt, error) {
if err != nil {
return nil, err
}
return NewBoxDecrypter(privateKey, publicKey), nil
return NewBoxDecrypter(privateKey, publicKey, boxLoader.KID), nil
}
21 changes: 15 additions & 6 deletions cipher/boxRecipient.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
{
"algorithm": {
"type": "box"
},
"recipientPrivateKey": "boxPrivate.pem",
"senderPublicKey": "sendBoxPublic.pem"
}
"cipher": [
{
"type": "box",
"kid": "test",
"keys": {
"senderPublicKey": "sendBoxPublic.pem",
"recipientPrivateKey": "boxPrivate.pem"
}
},
{
"type": "none",
"kid": "none"
}
]
}
17 changes: 11 additions & 6 deletions cipher/boxSender.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"algorithm": {
"type": "box"
},
"senderPrivateKey": "sendBoxPrivate.pem",
"recipientPublicKey": "boxPublic.pem"
}
"cipher": [
{
"type": "box",
"kid": "test",
"keys": {
"senderPrivateKey": "sendBoxPrivate.pem",
"recipientPublicKey": "boxPublic.pem"
}
}
]
}
119 changes: 87 additions & 32 deletions cipher/cipher.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,27 @@ func init() {
})
}

type Identification interface {
// GetAlgorithm will return the algorithm Encrypt and Decrypt uses
GetAlgorithm() AlgorithmType

// GetKID returns the id of the specific keys used
GetKID() string
}

// Encrypt represents the ability to encrypt messages
type Encrypt interface {
Identification

// EncryptMessage attempts to encode the message into an array of bytes.
// and error will be returned if failed to encode the message.
EncryptMessage(message []byte) (crypt []byte, nonce []byte, err error)
}

// Decrypt represents the ability to decrypt messages
type Decrypt interface {
Identification

// DecryptMessage attempts to decode the message into a string.
// and error will be returned if failed to decode the message.
DecryptMessage(cipher []byte, nonce []byte) (message []byte, err error)
Expand Down Expand Up @@ -83,6 +95,14 @@ func DefaultCipherDecrypter() Decrypt {
// NOOP will just return the message
type NOOP struct{}

func (*NOOP) GetAlgorithm() AlgorithmType {
return None
}

func (*NOOP) GetKID() string {
return "none"
}

func (*NOOP) EncryptMessage(message []byte) (crypt []byte, nonce []byte, err error) {
return message, []byte{}, nil
}
Expand All @@ -91,39 +111,48 @@ func (*NOOP) DecryptMessage(cipher []byte, nonce []byte) (message []byte, err er
return cipher, nil
}

type basicEncrypter struct {
hasher crypto.Hash
senderPrivateKey *rsa.PrivateKey
recipientPublicKey *rsa.PublicKey
label []byte
func (c *rsaEncrypterDecrypter) GetAlgorithm() AlgorithmType {
if c.recipientPublicKey == nil || c.senderPublicKey == nil {
return RSASymmetric
}
return RSAAsymmetric
}

type basicDecrypter struct {
func (c *rsaEncrypterDecrypter) GetKID() string {
return c.kid
}

type rsaEncrypterDecrypter struct {
kid string
hasher crypto.Hash
recipientPublicKey *rsa.PublicKey
recipientPrivateKey *rsa.PrivateKey
senderPublicKey *rsa.PublicKey
senderPrivateKey *rsa.PrivateKey
label []byte
}

func NewBasicEncrypter(hash crypto.Hash, senderPrivateKey *rsa.PrivateKey, recipientPublicKey *rsa.PublicKey) Encrypt {
return &basicEncrypter{
func NewRSAEncrypter(hash crypto.Hash, senderPrivateKey *rsa.PrivateKey, recipientPublicKey *rsa.PublicKey, kid string) Encrypt {
return &rsaEncrypterDecrypter{
kid: kid,
hasher: hash,
senderPrivateKey: senderPrivateKey,
recipientPublicKey: recipientPublicKey,
label: []byte("codex-basic-encrypter"),
label: []byte("codex-rsa-cipher"),
}
}

func NewBasicDecrypter(hash crypto.Hash, recipientPrivateKey *rsa.PrivateKey, senderPublicKey *rsa.PublicKey) Decrypt {
return &basicDecrypter{
func NewRSADecrypter(hash crypto.Hash, recipientPrivateKey *rsa.PrivateKey, senderPublicKey *rsa.PublicKey, kid string) Decrypt {
return &rsaEncrypterDecrypter{
kid: kid,
hasher: hash,
recipientPrivateKey: recipientPrivateKey,
senderPublicKey: senderPublicKey,
label: []byte("codex-basic-encrypter"),
label: []byte("codex-rsa-cipher"),
}
}

func (c *basicEncrypter) EncryptMessage(message []byte) ([]byte, []byte, error) {
func (c *rsaEncrypterDecrypter) EncryptMessage(message []byte) ([]byte, []byte, error) {
cipherdata, err := rsa.EncryptOAEP(
c.hasher.New(),
rand.Reader,
Expand All @@ -135,22 +164,26 @@ func (c *basicEncrypter) EncryptMessage(message []byte) ([]byte, []byte, error)
return []byte(""), []byte{}, emperror.Wrap(err, "failed to encrypt message")
}

var opts rsa.PSSOptions
opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example
signature := []byte{}

pssh := c.hasher.New()
pssh.Write(message)
hashed := pssh.Sum(nil)
if c.senderPrivateKey != nil {
var opts rsa.PSSOptions
opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example

signature, err := rsa.SignPSS(rand.Reader, c.senderPrivateKey, c.hasher, hashed, &opts)
if err != nil {
return []byte(""), []byte{}, emperror.Wrap(err, "failed to sign message")
pssh := c.hasher.New()
pssh.Write(message)
hashed := pssh.Sum(nil)

signature, err = rsa.SignPSS(rand.Reader, c.senderPrivateKey, c.hasher, hashed, &opts)
if err != nil {
return []byte(""), []byte{}, emperror.Wrap(err, "failed to sign message")
}
}

return cipherdata, signature, nil
}

func (c *basicDecrypter) DecryptMessage(cipher []byte, nonce []byte) ([]byte, error) {
func (c *rsaEncrypterDecrypter) DecryptMessage(cipher []byte, nonce []byte) ([]byte, error) {
decrypted, err := rsa.DecryptOAEP(
c.hasher.New(),
rand.Reader,
Expand All @@ -162,30 +195,42 @@ func (c *basicDecrypter) DecryptMessage(cipher []byte, nonce []byte) ([]byte, er
return []byte{}, emperror.Wrap(err, "failed to decrypt message")
}

var opts rsa.PSSOptions
opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example
if c.senderPublicKey != nil {
var opts rsa.PSSOptions
opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example

pssh := c.hasher.New()
pssh.Write(decrypted)
hashed := pssh.Sum(nil)
pssh := c.hasher.New()
pssh.Write(decrypted)
hashed := pssh.Sum(nil)

err = rsa.VerifyPSS(c.senderPublicKey, c.hasher, hashed, nonce, &opts)
if err != nil {
return []byte{}, emperror.Wrap(err, "failed to validate signature")
err = rsa.VerifyPSS(c.senderPublicKey, c.hasher, hashed, nonce, &opts)
if err != nil {
return []byte{}, emperror.Wrap(err, "failed to validate signature")
}
}

return decrypted, nil
}

type encryptBox struct {
kid string
senderPrivateKey [32]byte
recipientPublicKey [32]byte
sharedEncryptKey *[32]byte
}

func NewBoxEncrypter(senderPrivateKey [32]byte, recipientPublicKey [32]byte) Encrypt {
func (enBox *encryptBox) GetAlgorithm() AlgorithmType {
return Box
}

func (enBox *encryptBox) GetKID() string {
return enBox.kid
}

func NewBoxEncrypter(senderPrivateKey [32]byte, recipientPublicKey [32]byte, kid string) Encrypt {

encrypter := encryptBox{
kid: kid,
senderPrivateKey: senderPrivateKey,
recipientPublicKey: recipientPublicKey,
sharedEncryptKey: new([32]byte),
Expand All @@ -208,14 +253,24 @@ func (enBox *encryptBox) EncryptMessage(message []byte) ([]byte, []byte, error)
}

type decryptBox struct {
kid string
recipientPrivateKey [32]byte
senderPublicKey [32]byte
sharedDecryptKey *[32]byte
}

func NewBoxDecrypter(recipientPrivateKey [32]byte, senderPublicKey [32]byte) Decrypt {
func (deBox *decryptBox) GetAlgorithm() AlgorithmType {
return Box
}

func (deBox *decryptBox) GetKID() string {
return deBox.kid
}

func NewBoxDecrypter(recipientPrivateKey [32]byte, senderPublicKey [32]byte, kid string) Decrypt {

decrypter := decryptBox{
kid: kid,
recipientPrivateKey: recipientPrivateKey,
senderPublicKey: senderPublicKey,
sharedDecryptKey: new([32]byte),
Expand Down
8 changes: 4 additions & 4 deletions cipher/cipher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ func TestBasicCrypt(t *testing.T) {
recipientPrivateKey := GeneratePrivateKey(tc.size)
require.NotNil(recipientPrivateKey)

encrypter := NewBasicEncrypter(tc.hashAlgo, senderPrivateKey, &recipientPrivateKey.PublicKey)
encrypter := NewRSAEncrypter(tc.hashAlgo, senderPrivateKey, &recipientPrivateKey.PublicKey, "")
require.NotEmpty(encrypter)
decrypter := NewBasicDecrypter(tc.hashAlgo, recipientPrivateKey, &senderPrivateKey.PublicKey)
decrypter := NewRSADecrypter(tc.hashAlgo, recipientPrivateKey, &senderPrivateKey.PublicKey, "")
require.NotEmpty(decrypter)

testCryptoPair(t, encrypter, decrypter, tc.errOnLarge)
Expand Down Expand Up @@ -116,9 +116,9 @@ func TestBoxCipher(t *testing.T) {
require.NoError(err)
require.NotEqual(recipientPublicKey, senderPublicKey)

encrypter := NewBoxEncrypter(*senderPrivateKey, *recipientPublicKey)
encrypter := NewBoxEncrypter(*senderPrivateKey, *recipientPublicKey, "")
require.NotEmpty(encrypter)
decrypter := NewBoxDecrypter(*recipientPrivateKey, *senderPublicKey)
decrypter := NewBoxDecrypter(*recipientPrivateKey, *senderPublicKey, "")
require.NotEmpty(decrypter)

testCryptoPair(t, encrypter, decrypter, false)
Expand Down
18 changes: 12 additions & 6 deletions cipher/example.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
{
"algorithm": {
"type": "basic",
"hash": "SHA512"
},
"senderPrivateKey": "private.pem",
"recipientPublicKey": "public.pem"
"cipher": [
{
"type": "rsa-sym",
"params": {
"hash": "SHA512"
},
"keys": {
"publicKey": "public.pem",
"privateKey": "private.pem"
}
}
]
}
Loading

0 comments on commit 4f3e41e

Please sign in to comment.