github.com/yimialmonte/fabric@v2.1.1+incompatible/bccsp/utils/keys.go (about)

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