Skip to content

Commit

Permalink
BCCSP: Removing dependency to crypto/primitives package
Browse files Browse the repository at this point in the history
This change-set removes all the dependencies to the crypto/primitives package.
The bccsp is now self-contained. It does not depend on any other fabric
package.
This change-set comes in the context of:
https://jira.hyperledger.org/browse/FAB-354
Notice that no new methods have been introduced. Only required
methods have been copied from the crypto/primitives package.

Change-Id: I6be03eb4f345592ab1a89e544ec2be278cc7103c
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
  • Loading branch information
adecaro committed Dec 6, 2016
1 parent da16559 commit 51dc761
Show file tree
Hide file tree
Showing 13 changed files with 722 additions and 42 deletions.
4 changes: 2 additions & 2 deletions core/crypto/bccsp/signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"io"

"github.com/hyperledger/fabric/core/crypto/bccsp"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/crypto/bccsp/utils"
)

// CryptoSigner is the BCCSP-based implementation of a crypto.Signer
Expand Down Expand Up @@ -56,7 +56,7 @@ func (s *CryptoSigner) Init(csp bccsp.BCCSP, key bccsp.Key) error {
return fmt.Errorf("Failed marshalling public key [%s]", err)
}

pk, err := primitives.DERToPublicKey(raw)
pk, err := utils.DERToPublicKey(raw)
if err != nil {
return fmt.Errorf("Failed marshalling public key [%s]", err)
}
Expand Down
152 changes: 152 additions & 0 deletions core/crypto/bccsp/sw/aes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
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.
*/
/*
Copyright IBM Corp. 2016 All Rights Reserved.
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 sw

import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"errors"
"fmt"
"io"
)

// GetRandomBytes returns len random looking bytes
func GetRandomBytes(len int) ([]byte, error) {
buffer := make([]byte, len)

n, err := rand.Read(buffer)
if err != nil {
return nil, err
}
if n != len {
return nil, fmt.Errorf("Buffer not filled. Requested [%d], got [%d]", len, n)
}

return buffer, nil
}

func pkcs7Padding(src []byte) []byte {
padding := aes.BlockSize - len(src)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}

func pkcs7UnPadding(src []byte) ([]byte, error) {
length := len(src)
unpadding := int(src[length-1])

if unpadding > aes.BlockSize || unpadding == 0 {
return nil, errors.New("Invalid pkcs7 padding (unpadding > aes.BlockSize || unpadding == 0)")
}

pad := src[len(src)-unpadding:]
for i := 0; i < unpadding; i++ {
if pad[i] != byte(unpadding) {
return nil, errors.New("Invalid pkcs7 padding (pad[i] != unpadding)")
}
}

return src[:(length - unpadding)], nil
}

func aesCBCEncrypt(key, s []byte) ([]byte, error) {
if len(s)%aes.BlockSize != 0 {
return nil, errors.New("Invalid plaintext. It must be a multiple of the block size")
}

block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}

ciphertext := make([]byte, aes.BlockSize+len(s))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}

mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], s)

return ciphertext, nil
}

func aesCBCDecrypt(key, src []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}

if len(src) < aes.BlockSize {
return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size")
}
iv := src[:aes.BlockSize]
src = src[aes.BlockSize:]

if len(src)%aes.BlockSize != 0 {
return nil, errors.New("Invalid ciphertext. It must be a multiple of the block size")
}

mode := cipher.NewCBCDecrypter(block, iv)

mode.CryptBlocks(src, src)

return src, nil
}

// AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding
func AESCBCPKCS7Encrypt(key, src []byte) ([]byte, error) {
// First pad
tmp := pkcs7Padding(src)

// Then encrypt
return aesCBCEncrypt(key, tmp)
}

// AESCBCPKCS7Decrypt combines CBC decryption and PKCS7 unpadding
func AESCBCPKCS7Decrypt(key, src []byte) ([]byte, error) {
// First decrypt
pt, err := aesCBCDecrypt(key, src)
if err != nil {
return nil, err
}

// Then remove padding
original, err := pkcs7UnPadding(pt)
if err != nil {
return nil, err
}

return original, nil
}
23 changes: 23 additions & 0 deletions core/crypto/bccsp/sw/ecdsa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
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 sw

import "math/big"

// ECDSASignature represents an ECDSA signature
type ecdsaSignature struct {
R, S *big.Int
}
6 changes: 3 additions & 3 deletions core/crypto/bccsp/sw/ecdsakey.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"errors"

"github.com/hyperledger/fabric/core/crypto/bccsp"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/crypto/bccsp/utils"
)

type ecdsaPrivateKey struct {
Expand All @@ -40,7 +40,7 @@ func (k *ecdsaPrivateKey) Bytes() (raw []byte, err error) {

// SKI returns the subject key identifier of this key.
func (k *ecdsaPrivateKey) SKI() (ski []byte) {
raw, _ := primitives.PrivateKeyToDER(k.privKey)
raw, _ := utils.PrivateKeyToDER(k.privKey)
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.

hash := sha256.New()
Expand Down Expand Up @@ -82,7 +82,7 @@ func (k *ecdsaPublicKey) Bytes() (raw []byte, err error) {

// SKI returns the subject key identifier of this key.
func (k *ecdsaPublicKey) SKI() (ski []byte) {
raw, _ := primitives.PublicKeyToPEM(k.pubKey, nil)
raw, _ := utils.PublicKeyToPEM(k.pubKey, nil)
// TODO: Error should not be thrown. Anyway, move the marshalling at initialization.

hash := sha256.New()
Expand Down
16 changes: 7 additions & 9 deletions core/crypto/bccsp/sw/fileks.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"os"
"sync"

"github.com/hyperledger/fabric/core/crypto/utils"

"errors"
"strings"

Expand All @@ -32,7 +30,7 @@ import (
"path/filepath"

"github.com/hyperledger/fabric/core/crypto/bccsp"
"github.com/hyperledger/fabric/core/crypto/primitives"
"github.com/hyperledger/fabric/core/crypto/bccsp/utils"
)

// FileBasedKeyStore is a folder-based KeyStore.
Expand Down Expand Up @@ -234,7 +232,7 @@ func (ks *FileBasedKeyStore) getSuffix(alias string) string {
}

func (ks *FileBasedKeyStore) storePrivateKey(alias string, privateKey interface{}) error {
rawKey, err := primitives.PrivateKeyToPEM(privateKey, ks.pwd)
rawKey, err := utils.PrivateKeyToPEM(privateKey, ks.pwd)
if err != nil {
logger.Errorf("Failed converting private key to PEM [%s]: [%s]", alias, err)
return err
Expand All @@ -250,7 +248,7 @@ func (ks *FileBasedKeyStore) storePrivateKey(alias string, privateKey interface{
}

func (ks *FileBasedKeyStore) storePublicKey(alias string, publicKey interface{}) error {
rawKey, err := primitives.PublicKeyToPEM(publicKey, ks.pwd)
rawKey, err := utils.PublicKeyToPEM(publicKey, ks.pwd)
if err != nil {
logger.Errorf("Failed converting public key to PEM [%s]: [%s]", alias, err)
return err
Expand All @@ -266,7 +264,7 @@ func (ks *FileBasedKeyStore) storePublicKey(alias string, publicKey interface{})
}

func (ks *FileBasedKeyStore) storeKey(alias string, key []byte) error {
pem, err := primitives.AEStoEncryptedPEM(key, ks.pwd)
pem, err := utils.AEStoEncryptedPEM(key, ks.pwd)
if err != nil {
logger.Errorf("Failed converting key to PEM [%s]: [%s]", alias, err)
return err
Expand All @@ -292,7 +290,7 @@ func (ks *FileBasedKeyStore) loadPrivateKey(alias string) (interface{}, error) {
return nil, err
}

privateKey, err := primitives.PEMtoPrivateKey(raw, ks.pwd)
privateKey, err := utils.PEMtoPrivateKey(raw, ks.pwd)
if err != nil {
logger.Errorf("Failed parsing private key [%s]: [%s].", alias, err.Error())

Expand All @@ -313,7 +311,7 @@ func (ks *FileBasedKeyStore) loadPublicKey(alias string) (interface{}, error) {
return nil, err
}

privateKey, err := primitives.PEMtoPublicKey(raw, ks.pwd)
privateKey, err := utils.PEMtoPublicKey(raw, ks.pwd)
if err != nil {
logger.Errorf("Failed parsing private key [%s]: [%s].", alias, err.Error())

Expand All @@ -334,7 +332,7 @@ func (ks *FileBasedKeyStore) loadKey(alias string) ([]byte, error) {
return nil, err
}

key, err := primitives.PEMtoAES(pem, ks.pwd)
key, err := utils.PEMtoAES(pem, ks.pwd)
if err != nil {
logger.Errorf("Failed parsing key [%s]: [%s]", alias, err)

Expand Down
Loading

0 comments on commit 51dc761

Please sign in to comment.