github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/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/elliptic"
    22  	"crypto/rand"
    23  	"crypto/rsa"
    24  	"crypto/x509"
    25  	"encoding/asn1"
    26  	"encoding/pem"
    27  	"errors"
    28  	"fmt"
    29  )
    30  
    31  // struct to hold info required for PKCS#8
    32  type pkcs8Info struct {
    33  	Version             int
    34  	PrivateKeyAlgorithm []asn1.ObjectIdentifier
    35  	PrivateKey          []byte
    36  }
    37  
    38  type ecPrivateKey struct {
    39  	Version       int
    40  	PrivateKey    []byte
    41  	NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
    42  	PublicKey     asn1.BitString        `asn1:"optional,explicit,tag:1"`
    43  }
    44  
    45  var (
    46  	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
    47  	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
    48  	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
    49  	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
    50  )
    51  
    52  var oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
    53  
    54  func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
    55  	switch curve {
    56  	case elliptic.P224():
    57  		return oidNamedCurveP224, true
    58  	case elliptic.P256():
    59  		return oidNamedCurveP256, true
    60  	case elliptic.P384():
    61  		return oidNamedCurveP384, true
    62  	case elliptic.P521():
    63  		return oidNamedCurveP521, true
    64  	}
    65  	return nil, false
    66  }
    67  
    68  // PrivateKeyToDER marshals a private key to der
    69  func PrivateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) {
    70  	if privateKey == nil {
    71  		return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
    72  	}
    73  
    74  	return x509.MarshalECPrivateKey(privateKey)
    75  }
    76  
    77  // PrivateKeyToPEM converts the private key to PEM format.
    78  // EC private keys are converted to PKCS#8 format.
    79  // RSA private keys are converted to PKCS#1 format.
    80  func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
    81  	// Validate inputs
    82  	if len(pwd) != 0 {
    83  		return PrivateKeyToEncryptedPEM(privateKey, pwd)
    84  	}
    85  	if privateKey == nil {
    86  		return nil, errors.New("Invalid key. It must be different from nil.")
    87  	}
    88  
    89  	switch k := privateKey.(type) {
    90  	case *ecdsa.PrivateKey:
    91  		if k == nil {
    92  			return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
    93  		}
    94  
    95  		// get the oid for the curve
    96  		oidNamedCurve, ok := oidFromNamedCurve(k.Curve)
    97  		if !ok {
    98  			return nil, errors.New("unknown elliptic curve")
    99  		}
   100  
   101  		// based on https://golang.org/src/crypto/x509/sec1.go
   102  		privateKeyBytes := k.D.Bytes()
   103  		paddedPrivateKey := make([]byte, (k.Curve.Params().N.BitLen()+7)/8)
   104  		copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
   105  		// omit NamedCurveOID for compatibility as it's optional
   106  		asn1Bytes, err := asn1.Marshal(ecPrivateKey{
   107  			Version:    1,
   108  			PrivateKey: paddedPrivateKey,
   109  			PublicKey:  asn1.BitString{Bytes: elliptic.Marshal(k.Curve, k.X, k.Y)},
   110  		})
   111  
   112  		if err != nil {
   113  			return nil, fmt.Errorf("error marshaling EC key to asn1 [%s]", err)
   114  		}
   115  
   116  		var pkcs8Key pkcs8Info
   117  		pkcs8Key.Version = 1
   118  		pkcs8Key.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 2)
   119  		pkcs8Key.PrivateKeyAlgorithm[0] = oidPublicKeyECDSA
   120  		pkcs8Key.PrivateKeyAlgorithm[1] = oidNamedCurve
   121  		pkcs8Key.PrivateKey = asn1Bytes
   122  
   123  		pkcs8Bytes, err := asn1.Marshal(pkcs8Key)
   124  		if err != nil {
   125  			return nil, fmt.Errorf("error marshaling EC key to asn1 [%s]", err)
   126  		}
   127  		return pem.EncodeToMemory(
   128  			&pem.Block{
   129  				Type:  "PRIVATE KEY",
   130  				Bytes: pkcs8Bytes,
   131  			},
   132  		), nil
   133  	case *rsa.PrivateKey:
   134  		if k == nil {
   135  			return nil, errors.New("Invalid rsa private key. It must be different from nil.")
   136  		}
   137  		raw := x509.MarshalPKCS1PrivateKey(k)
   138  
   139  		return pem.EncodeToMemory(
   140  			&pem.Block{
   141  				Type:  "RSA PRIVATE KEY",
   142  				Bytes: raw,
   143  			},
   144  		), nil
   145  	default:
   146  		return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey or *rsa.PrivateKey")
   147  	}
   148  }
   149  
   150  // PrivateKeyToEncryptedPEM converts a private key to an encrypted PEM
   151  func PrivateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
   152  	if privateKey == nil {
   153  		return nil, errors.New("Invalid private key. It must be different from nil.")
   154  	}
   155  
   156  	switch k := privateKey.(type) {
   157  	case *ecdsa.PrivateKey:
   158  		if k == nil {
   159  			return nil, errors.New("Invalid ecdsa private key. It must be different from nil.")
   160  		}
   161  		raw, err := x509.MarshalECPrivateKey(k)
   162  
   163  		if err != nil {
   164  			return nil, err
   165  		}
   166  
   167  		block, err := x509.EncryptPEMBlock(
   168  			rand.Reader,
   169  			"PRIVATE KEY",
   170  			raw,
   171  			pwd,
   172  			x509.PEMCipherAES256)
   173  
   174  		if err != nil {
   175  			return nil, err
   176  		}
   177  
   178  		return pem.EncodeToMemory(block), nil
   179  
   180  	default:
   181  		return nil, errors.New("Invalid key type. It must be *ecdsa.PrivateKey")
   182  	}
   183  }
   184  
   185  // DERToPrivateKey unmarshals a der to private key
   186  func DERToPrivateKey(der []byte) (key interface{}, err error) {
   187  
   188  	if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
   189  		return key, nil
   190  	}
   191  
   192  	if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
   193  		switch key.(type) {
   194  		case *rsa.PrivateKey, *ecdsa.PrivateKey:
   195  			return
   196  		default:
   197  			return nil, errors.New("Found unknown private key type in PKCS#8 wrapping")
   198  		}
   199  	}
   200  
   201  	if key, err = x509.ParseECPrivateKey(der); err == nil {
   202  		return
   203  	}
   204  
   205  	return nil, errors.New("Invalid key type. The DER must contain an rsa.PrivareKey or ecdsa.PrivateKey")
   206  }
   207  
   208  // PEMtoPrivateKey unmarshals a pem to private key
   209  func PEMtoPrivateKey(raw []byte, pwd []byte) (interface{}, error) {
   210  	if len(raw) == 0 {
   211  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   212  	}
   213  	block, _ := pem.Decode(raw)
   214  	if block == nil {
   215  		return nil, fmt.Errorf("Failed decoding PEM. Block must be diffrent from nil. [% x]", raw)
   216  	}
   217  
   218  	// TODO: derive from header the type of the key
   219  
   220  	if x509.IsEncryptedPEMBlock(block) {
   221  		if len(pwd) == 0 {
   222  			return nil, errors.New("Encrypted Key. Need a password")
   223  		}
   224  
   225  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   226  		if err != nil {
   227  			return nil, fmt.Errorf("Failed PEM decryption [%s]", err)
   228  		}
   229  
   230  		key, err := DERToPrivateKey(decrypted)
   231  		if err != nil {
   232  			return nil, err
   233  		}
   234  		return key, err
   235  	}
   236  
   237  	cert, err := DERToPrivateKey(block.Bytes)
   238  	if err != nil {
   239  		return nil, err
   240  	}
   241  	return cert, err
   242  }
   243  
   244  // PEMtoAES extracts from the PEM an AES key
   245  func PEMtoAES(raw []byte, pwd []byte) ([]byte, error) {
   246  	if len(raw) == 0 {
   247  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   248  	}
   249  	block, _ := pem.Decode(raw)
   250  	if block == nil {
   251  		return nil, fmt.Errorf("Failed decoding PEM. Block must be different from nil. [% x]", raw)
   252  	}
   253  
   254  	if x509.IsEncryptedPEMBlock(block) {
   255  		if len(pwd) == 0 {
   256  			return nil, errors.New("Encrypted Key. Password must be different fom nil")
   257  		}
   258  
   259  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   260  		if err != nil {
   261  			return nil, fmt.Errorf("Failed PEM decryption. [%s]", err)
   262  		}
   263  		return decrypted, nil
   264  	}
   265  
   266  	return block.Bytes, nil
   267  }
   268  
   269  // AEStoPEM encapsulates an AES key in the PEM format
   270  func AEStoPEM(raw []byte) []byte {
   271  	return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw})
   272  }
   273  
   274  // AEStoEncryptedPEM encapsulates an AES key in the encrypted PEM format
   275  func AEStoEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) {
   276  	if len(raw) == 0 {
   277  		return nil, errors.New("Invalid aes key. It must be different from nil")
   278  	}
   279  	if len(pwd) == 0 {
   280  		return AEStoPEM(raw), nil
   281  	}
   282  
   283  	block, err := x509.EncryptPEMBlock(
   284  		rand.Reader,
   285  		"AES PRIVATE KEY",
   286  		raw,
   287  		pwd,
   288  		x509.PEMCipherAES256)
   289  
   290  	if err != nil {
   291  		return nil, err
   292  	}
   293  
   294  	return pem.EncodeToMemory(block), nil
   295  }
   296  
   297  // PublicKeyToPEM marshals a public key to the pem format
   298  func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   299  	if len(pwd) != 0 {
   300  		return PublicKeyToEncryptedPEM(publicKey, pwd)
   301  	}
   302  
   303  	if publicKey == nil {
   304  		return nil, errors.New("Invalid public key. It must be different from nil.")
   305  	}
   306  
   307  	switch k := publicKey.(type) {
   308  	case *ecdsa.PublicKey:
   309  		if k == nil {
   310  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   311  		}
   312  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   313  		if err != nil {
   314  			return nil, err
   315  		}
   316  
   317  		return pem.EncodeToMemory(
   318  			&pem.Block{
   319  				Type:  "PUBLIC KEY",
   320  				Bytes: PubASN1,
   321  			},
   322  		), nil
   323  	case *rsa.PublicKey:
   324  		if k == nil {
   325  			return nil, errors.New("Invalid rsa public key. It must be different from nil.")
   326  		}
   327  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   328  		if err != nil {
   329  			return nil, err
   330  		}
   331  
   332  		return pem.EncodeToMemory(
   333  			&pem.Block{
   334  				Type:  "RSA PUBLIC KEY",
   335  				Bytes: PubASN1,
   336  			},
   337  		), nil
   338  
   339  	default:
   340  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey or *rsa.PublicKey")
   341  	}
   342  }
   343  
   344  // PublicKeyToDER marshals a public key to the der format
   345  func PublicKeyToDER(publicKey interface{}) ([]byte, error) {
   346  	if publicKey == nil {
   347  		return nil, errors.New("Invalid public key. It must be different from nil.")
   348  	}
   349  
   350  	switch k := publicKey.(type) {
   351  	case *ecdsa.PublicKey:
   352  		if k == nil {
   353  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   354  		}
   355  		PubASN1, err := x509.MarshalPKIXPublicKey(k)
   356  		if err != nil {
   357  			return nil, err
   358  		}
   359  
   360  		return PubASN1, nil
   361  
   362  	default:
   363  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey")
   364  	}
   365  }
   366  
   367  // PublicKeyToEncryptedPEM converts a public key to encrypted pem
   368  func PublicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
   369  	if publicKey == nil {
   370  		return nil, errors.New("Invalid public key. It must be different from nil.")
   371  	}
   372  	if len(pwd) == 0 {
   373  		return nil, errors.New("Invalid password. It must be different from nil.")
   374  	}
   375  
   376  	switch k := publicKey.(type) {
   377  	case *ecdsa.PublicKey:
   378  		if k == nil {
   379  			return nil, errors.New("Invalid ecdsa public key. It must be different from nil.")
   380  		}
   381  		raw, err := x509.MarshalPKIXPublicKey(k)
   382  		if err != nil {
   383  			return nil, err
   384  		}
   385  
   386  		block, err := x509.EncryptPEMBlock(
   387  			rand.Reader,
   388  			"PUBLIC KEY",
   389  			raw,
   390  			pwd,
   391  			x509.PEMCipherAES256)
   392  
   393  		if err != nil {
   394  			return nil, err
   395  		}
   396  
   397  		return pem.EncodeToMemory(block), nil
   398  
   399  	default:
   400  		return nil, errors.New("Invalid key type. It must be *ecdsa.PublicKey")
   401  	}
   402  }
   403  
   404  // PEMtoPublicKey unmarshals a pem to public key
   405  func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) {
   406  	if len(raw) == 0 {
   407  		return nil, errors.New("Invalid PEM. It must be diffrent from nil.")
   408  	}
   409  	block, _ := pem.Decode(raw)
   410  	if block == nil {
   411  		return nil, fmt.Errorf("Failed decoding. Block must be different from nil. [% x]", raw)
   412  	}
   413  
   414  	// TODO: derive from header the type of the key
   415  	if x509.IsEncryptedPEMBlock(block) {
   416  		if len(pwd) == 0 {
   417  			return nil, errors.New("Encrypted Key. Password must be different from nil")
   418  		}
   419  
   420  		decrypted, err := x509.DecryptPEMBlock(block, pwd)
   421  		if err != nil {
   422  			return nil, fmt.Errorf("Failed PEM decryption. [%s]", err)
   423  		}
   424  
   425  		key, err := DERToPublicKey(decrypted)
   426  		if err != nil {
   427  			return nil, err
   428  		}
   429  		return key, err
   430  	}
   431  
   432  	cert, err := DERToPublicKey(block.Bytes)
   433  	if err != nil {
   434  		return nil, err
   435  	}
   436  	return cert, err
   437  }
   438  
   439  // DERToPublicKey unmarshals a der to public key
   440  func DERToPublicKey(raw []byte) (pub interface{}, err error) {
   441  	if len(raw) == 0 {
   442  		return nil, errors.New("Invalid DER. It must be diffrent from nil.")
   443  	}
   444  
   445  	key, err := x509.ParsePKIXPublicKey(raw)
   446  
   447  	return key, err
   448  }