github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/bccsp/utils/keys.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package utils
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"crypto/rand"
    22  	"crypto/rsa"
    23  	"crypto/x509"
    24  	"encoding/pem"
    25  	"errors"
    26  	"fmt"
    27  )
    28  
    29  // PrivateKeyToDER marshals a private key to der
    30  func PrivateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) {
    31  	if privateKey == nil {
    32  		return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
    33  	}
    34  
    35  	return x509.MarshalECPrivateKey(privateKey)
    36  }
    37  
    38  // PrivateKeyToPEM converts a private key to PEM
    39  func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
    40  	// Validate inputs
    41  	if len(pwd) != 0 {
    42  		return PrivateKeyToEncryptedPEM(privateKey, pwd)
    43  	}
    44  
    45  	switch k := privateKey.(type) {
    46  	case *ecdsa.PrivateKey:
    47  		if k == nil {
    48  			return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
    49  		}
    50  
    51  		raw, err := x509.MarshalECPrivateKey(k)
    52  
    53  		if err != nil {
    54  			return nil, err
    55  		}
    56  
    57  		return pem.EncodeToMemory(
    58  			&pem.Block{
    59  				Type:  "ECDSA PRIVATE KEY",
    60  				Bytes: raw,
    61  			},
    62  		), nil
    63  	case *rsa.PrivateKey:
    64  		if k == nil {
    65  			return nil, errors.New("Invalid rsa private key. It must be different from nil.")
    66  		}
    67  
    68  		raw := x509.MarshalPKCS1PrivateKey(k)
    69  
    70  		return pem.EncodeToMemory(
    71  			&pem.Block{
    72  				Type:  "RSA PRIVATE KEY",
    73  				Bytes: raw,
    74  			},
    75  		), nil
    76  	default:
    77  		return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey")
    78  	}
    79  }
    80  
    81  // PrivateKeyToEncryptedPEM converts a private key to an encrypted PEM
    82  func PrivateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
    83  	switch k := privateKey.(type) {
    84  	case *ecdsa.PrivateKey:
    85  		if k == nil {
    86  			return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
    87  		}
    88  
    89  		raw, err := x509.MarshalECPrivateKey(k)
    90  
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  
    95  		block, err := x509.EncryptPEMBlock(
    96  			rand.Reader,
    97  			"ECDSA PRIVATE KEY",
    98  			raw,
    99  			pwd,
   100  			x509.PEMCipherAES256)
   101  
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  
   106  		return pem.EncodeToMemory(block), nil
   107  
   108  	default:
   109  		return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey")
   110  	}
   111  }
   112  
   113  // DERToPrivateKey unmarshals a der to private key
   114  func DERToPrivateKey(der []byte) (key interface{}, err error) {
   115  
   116  	if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
   117  		return key, nil
   118  	}
   119  
   120  	if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
   121  		switch key.(type) {
   122  		case *rsa.PrivateKey, *ecdsa.PrivateKey:
   123  			return
   124  		default:
   125  			return nil, errors.New("Found unknown private key type in PKCS#8 wrapping")
   126  		}
   127  	}
   128  
   129  	if key, err = x509.ParseECPrivateKey(der); err == nil {
   130  		return
   131  	}
   132  
   133  	return nil, errors.New("Invalid key type. The DER must contain an rsa.PrivareKey or ecdsa.PrivateKey")
   134  }
   135  
   136  // PEMtoPrivateKey unmarshals a pem to private key
   137  func PEMtoPrivateKey(raw []byte, pwd []byte) (interface{}, error) {
   138  	if len(raw) == 0 {
   139  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   140  	}
   141  	block, _ := pem.Decode(raw)
   142  	if block == nil {
   143  		return nil, fmt.Errorf("Failed decoding PEM. Block must be diffrent from nil. [% x]", raw)
   144  	}
   145  
   146  	// TODO: derive from header the type of the key
   147  
   148  	if x509.IsEncryptedPEMBlock(block) {
   149  		if len(pwd) == 0 {
   150  			return nil, errors.New("Encrypted Key. Need a password")
   151  		}
   152  
   153  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   154  		if err != nil {
   155  			return nil, fmt.Errorf("Failed PEM decryption [%s]", err)
   156  		}
   157  
   158  		key, err := DERToPrivateKey(decrypted)
   159  		if err != nil {
   160  			return nil, err
   161  		}
   162  		return key, err
   163  	}
   164  
   165  	cert, err := DERToPrivateKey(block.Bytes)
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  	return cert, err
   170  }
   171  
   172  // PEMtoAES extracts from the PEM an AES key
   173  func PEMtoAES(raw []byte, pwd []byte) ([]byte, error) {
   174  	if len(raw) == 0 {
   175  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   176  	}
   177  	block, _ := pem.Decode(raw)
   178  	if block == nil {
   179  		return nil, fmt.Errorf("Failed decoding PEM. Block must be different from nil. [% x]", raw)
   180  	}
   181  
   182  	if x509.IsEncryptedPEMBlock(block) {
   183  		if len(pwd) == 0 {
   184  			return nil, errors.New("Encrypted Key. Password must be different fom nil")
   185  		}
   186  
   187  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   188  		if err != nil {
   189  			return nil, fmt.Errorf("Failed PEM decryption. [%s]", err)
   190  		}
   191  		return decrypted, nil
   192  	}
   193  
   194  	return block.Bytes, nil
   195  }
   196  
   197  // AEStoPEM encapsulates an AES key in the PEM format
   198  func AEStoPEM(raw []byte) []byte {
   199  	return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw})
   200  }
   201  
   202  // AEStoEncryptedPEM encapsulates an AES key in the encrypted PEM format
   203  func AEStoEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) {
   204  	if len(raw) == 0 {
   205  		return nil, errors.New("Invalid aes key. It must be different from nil")
   206  	}
   207  	if len(pwd) == 0 {
   208  		return AEStoPEM(raw), nil
   209  	}
   210  
   211  	block, err := x509.EncryptPEMBlock(
   212  		rand.Reader,
   213  		"AES PRIVATE KEY",
   214  		raw,
   215  		pwd,
   216  		x509.PEMCipherAES256)
   217  
   218  	if err != nil {
   219  		return nil, err
   220  	}
   221  
   222  	return pem.EncodeToMemory(block), nil
   223  }
   224  
   225  // PublicKeyToPEM marshals a public key to the pem format
   226  func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   227  	if len(pwd) != 0 {
   228  		return PublicKeyToEncryptedPEM(publicKey, pwd)
   229  	}
   230  
   231  	switch k := publicKey.(type) {
   232  	case *ecdsa.PublicKey:
   233  		if k == nil {
   234  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   235  		}
   236  
   237  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   238  		if err != nil {
   239  			return nil, err
   240  		}
   241  
   242  		return pem.EncodeToMemory(
   243  			&pem.Block{
   244  				Type:  "ECDSA PUBLIC KEY",
   245  				Bytes: PubASN1,
   246  			},
   247  		), nil
   248  	case *rsa.PublicKey:
   249  		if k == nil {
   250  			return nil, errors.New("Invalid rsa public key. It must be different from nil.")
   251  		}
   252  
   253  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   254  		if err != nil {
   255  			return nil, err
   256  		}
   257  
   258  		return pem.EncodeToMemory(
   259  			&pem.Block{
   260  				Type:  "RSA PUBLIC KEY",
   261  				Bytes: PubASN1,
   262  			},
   263  		), nil
   264  
   265  	default:
   266  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey or *rsa.PublicKey")
   267  	}
   268  }
   269  
   270  // PublicKeyToDER marshals a public key to the der format
   271  func PublicKeyToDER(publicKey interface{}) ([]byte, error) {
   272  	switch k := publicKey.(type) {
   273  	case *ecdsa.PublicKey:
   274  		if k == nil {
   275  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   276  		}
   277  
   278  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   279  		if err != nil {
   280  			return nil, err
   281  		}
   282  
   283  		return PubASN1, nil
   284  
   285  	default:
   286  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey")
   287  	}
   288  }
   289  
   290  // PublicKeyToEncryptedPEM converts a public key to encrypted pem
   291  func PublicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   292  	switch k := publicKey.(type) {
   293  	case *ecdsa.PublicKey:
   294  		if k == nil {
   295  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   296  		}
   297  		raw, err := x509.MarshalPKIXPublicKey(k)
   298  
   299  		if err != nil {
   300  			return nil, err
   301  		}
   302  
   303  		block, err := x509.EncryptPEMBlock(
   304  			rand.Reader,
   305  			"ECDSA PUBLIC KEY",
   306  			raw,
   307  			pwd,
   308  			x509.PEMCipherAES256)
   309  
   310  		if err != nil {
   311  			return nil, err
   312  		}
   313  
   314  		return pem.EncodeToMemory(block), nil
   315  
   316  	default:
   317  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey")
   318  	}
   319  }
   320  
   321  // PEMtoPublicKey unmarshals a pem to public key
   322  func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) {
   323  	if len(raw) == 0 {
   324  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   325  	}
   326  	block, _ := pem.Decode(raw)
   327  	if block == nil {
   328  		return nil, fmt.Errorf("Failed decoding. Block must be different from nil. [% x]", raw)
   329  	}
   330  
   331  	// TODO: derive from header the type of the key
   332  	if x509.IsEncryptedPEMBlock(block) {
   333  		if len(pwd) == 0 {
   334  			return nil, errors.New("Encrypted Key. Password must be different from nil")
   335  		}
   336  
   337  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   338  		if err != nil {
   339  			return nil, fmt.Errorf("Failed PEM decryption. [%s]", err)
   340  		}
   341  
   342  		key, err := DERToPublicKey(decrypted)
   343  		if err != nil {
   344  			return nil, err
   345  		}
   346  		return key, err
   347  	}
   348  
   349  	cert, err := DERToPublicKey(block.Bytes)
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  	return cert, err
   354  }
   355  
   356  // DERToPublicKey unmarshals a der to public key
   357  func DERToPublicKey(raw []byte) (pub interface{}, err error) {
   358  	if len(raw) == 0 {
   359  		return nil, errors.New("Invalid DER. It must be diffrent from nil.")
   360  	}
   361  
   362  	key, err := x509.ParsePKIXPublicKey(raw)
   363  
   364  	return key, err
   365  }