github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/crypto/ecies/asn1.go (about)

     1  // Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
     2  // Copyright (c) 2012 The Go Authors. All rights reserved.
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are
     6  // met:
     7  //
     8  //    * Redistributions of source code must retain the above copyright
     9  // notice, this list of conditions and the following disclaimer.
    10  //    * Redistributions in binary form must reproduce the above
    11  // copyright notice, this list of conditions and the following disclaimer
    12  // in the documentation and/or other materials provided with the
    13  // distribution.
    14  //    * Neither the name of Google Inc. nor the names of its
    15  // contributors may be used to endorse or promote products derived from
    16  // this software without specific prior written permission.
    17  //
    18  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29  
    30  package ecies
    31  
    32  import (
    33  	"bytes"
    34  	"crypto"
    35  	"crypto/elliptic"
    36  	"crypto/sha1"
    37  	"crypto/sha256"
    38  	"crypto/sha512"
    39  	"encoding/asn1"
    40  	"encoding/pem"
    41  	"fmt"
    42  	"hash"
    43  	"math/big"
    44  
    45  	"github.com/atheioschain/go-atheios/crypto/secp256k1"
    46  )
    47  
    48  var (
    49  	secgScheme     = []int{1, 3, 132, 1}
    50  	shaScheme      = []int{2, 16, 840, 1, 101, 3, 4, 2}
    51  	ansiX962Scheme = []int{1, 2, 840, 10045}
    52  	x963Scheme     = []int{1, 2, 840, 63, 0}
    53  )
    54  
    55  var ErrInvalidPrivateKey = fmt.Errorf("ecies: invalid private key")
    56  
    57  func doScheme(base, v []int) asn1.ObjectIdentifier {
    58  	var oidInts asn1.ObjectIdentifier
    59  	oidInts = append(oidInts, base...)
    60  	return append(oidInts, v...)
    61  }
    62  
    63  // curve OID code taken from crypto/x509, including
    64  //	- oidNameCurve*
    65  //	- namedCurveFromOID
    66  //	- oidFromNamedCurve
    67  // RFC 5480, 2.1.1.1. Named Curve
    68  //
    69  // secp224r1 OBJECT IDENTIFIER ::= {
    70  //   iso(1) identified-organization(3) certicom(132) curve(0) 33 }
    71  //
    72  // secp256r1 OBJECT IDENTIFIER ::= {
    73  //   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
    74  //   prime(1) 7 }
    75  //
    76  // secp384r1 OBJECT IDENTIFIER ::= {
    77  //   iso(1) identified-organization(3) certicom(132) curve(0) 34 }
    78  //
    79  // secp521r1 OBJECT IDENTIFIER ::= {
    80  //   iso(1) identified-organization(3) certicom(132) curve(0) 35 }
    81  //
    82  // NB: secp256r1 is equivalent to prime256v1
    83  type secgNamedCurve asn1.ObjectIdentifier
    84  
    85  var (
    86  	secgNamedCurveS256 = secgNamedCurve{1, 3, 132, 0, 10}
    87  	secgNamedCurveP256 = secgNamedCurve{1, 2, 840, 10045, 3, 1, 7}
    88  	secgNamedCurveP384 = secgNamedCurve{1, 3, 132, 0, 34}
    89  	secgNamedCurveP521 = secgNamedCurve{1, 3, 132, 0, 35}
    90  	rawCurveP256       = []byte{6, 8, 4, 2, 1, 3, 4, 7, 2, 2, 0, 6, 6, 1, 3, 1, 7}
    91  	rawCurveP384       = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 4}
    92  	rawCurveP521       = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 5}
    93  )
    94  
    95  func rawCurve(curve elliptic.Curve) []byte {
    96  	switch curve {
    97  	case elliptic.P256():
    98  		return rawCurveP256
    99  	case elliptic.P384():
   100  		return rawCurveP384
   101  	case elliptic.P521():
   102  		return rawCurveP521
   103  	default:
   104  		return nil
   105  	}
   106  }
   107  
   108  func (curve secgNamedCurve) Equal(curve2 secgNamedCurve) bool {
   109  	if len(curve) != len(curve2) {
   110  		return false
   111  	}
   112  	for i := range curve {
   113  		if curve[i] != curve2[i] {
   114  			return false
   115  		}
   116  	}
   117  	return true
   118  }
   119  
   120  func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve {
   121  	switch {
   122  	case curve.Equal(secgNamedCurveS256):
   123  		return secp256k1.S256()
   124  	case curve.Equal(secgNamedCurveP256):
   125  		return elliptic.P256()
   126  	case curve.Equal(secgNamedCurveP384):
   127  		return elliptic.P384()
   128  	case curve.Equal(secgNamedCurveP521):
   129  		return elliptic.P521()
   130  	}
   131  	return nil
   132  }
   133  
   134  func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) {
   135  	switch curve {
   136  	case elliptic.P256():
   137  		return secgNamedCurveP256, true
   138  	case elliptic.P384():
   139  		return secgNamedCurveP384, true
   140  	case elliptic.P521():
   141  		return secgNamedCurveP521, true
   142  	case secp256k1.S256():
   143  		return secgNamedCurveS256, true
   144  	}
   145  
   146  	return nil, false
   147  }
   148  
   149  // asnAlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
   150  // 5280, section 4.1.1.2.
   151  type asnAlgorithmIdentifier struct {
   152  	Algorithm  asn1.ObjectIdentifier
   153  	Parameters asn1.RawValue `asn1:"optional"`
   154  }
   155  
   156  func (a asnAlgorithmIdentifier) Cmp(b asnAlgorithmIdentifier) bool {
   157  	if len(a.Algorithm) != len(b.Algorithm) {
   158  		return false
   159  	}
   160  	for i := range a.Algorithm {
   161  		if a.Algorithm[i] != b.Algorithm[i] {
   162  			return false
   163  		}
   164  	}
   165  	return true
   166  }
   167  
   168  type asnHashFunction asnAlgorithmIdentifier
   169  
   170  var (
   171  	oidSHA1   = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
   172  	oidSHA224 = doScheme(shaScheme, []int{4})
   173  	oidSHA256 = doScheme(shaScheme, []int{1})
   174  	oidSHA384 = doScheme(shaScheme, []int{2})
   175  	oidSHA512 = doScheme(shaScheme, []int{3})
   176  )
   177  
   178  func hashFromOID(oid asn1.ObjectIdentifier) func() hash.Hash {
   179  	switch {
   180  	case oid.Equal(oidSHA1):
   181  		return sha1.New
   182  	case oid.Equal(oidSHA224):
   183  		return sha256.New224
   184  	case oid.Equal(oidSHA256):
   185  		return sha256.New
   186  	case oid.Equal(oidSHA384):
   187  		return sha512.New384
   188  	case oid.Equal(oidSHA512):
   189  		return sha512.New
   190  	}
   191  	return nil
   192  }
   193  
   194  func oidFromHash(hash crypto.Hash) (asn1.ObjectIdentifier, bool) {
   195  	switch hash {
   196  	case crypto.SHA1:
   197  		return oidSHA1, true
   198  	case crypto.SHA224:
   199  		return oidSHA224, true
   200  	case crypto.SHA256:
   201  		return oidSHA256, true
   202  	case crypto.SHA384:
   203  		return oidSHA384, true
   204  	case crypto.SHA512:
   205  		return oidSHA512, true
   206  	default:
   207  		return nil, false
   208  	}
   209  }
   210  
   211  var (
   212  	asnAlgoSHA1 = asnHashFunction{
   213  		Algorithm: oidSHA1,
   214  	}
   215  	asnAlgoSHA224 = asnHashFunction{
   216  		Algorithm: oidSHA224,
   217  	}
   218  	asnAlgoSHA256 = asnHashFunction{
   219  		Algorithm: oidSHA256,
   220  	}
   221  	asnAlgoSHA384 = asnHashFunction{
   222  		Algorithm: oidSHA384,
   223  	}
   224  	asnAlgoSHA512 = asnHashFunction{
   225  		Algorithm: oidSHA512,
   226  	}
   227  )
   228  
   229  // type ASNasnSubjectPublicKeyInfo struct {
   230  //
   231  // }
   232  //
   233  
   234  type asnSubjectPublicKeyInfo struct {
   235  	Algorithm   asn1.ObjectIdentifier
   236  	PublicKey   asn1.BitString
   237  	Supplements ecpksSupplements `asn1:"optional"`
   238  }
   239  
   240  type asnECPKAlgorithms struct {
   241  	Type asn1.ObjectIdentifier
   242  }
   243  
   244  var idPublicKeyType = doScheme(ansiX962Scheme, []int{2})
   245  var idEcPublicKey = doScheme(idPublicKeyType, []int{1})
   246  var idEcPublicKeySupplemented = doScheme(idPublicKeyType, []int{0})
   247  
   248  func curveToRaw(curve elliptic.Curve) (rv asn1.RawValue, ok bool) {
   249  	switch curve {
   250  	case elliptic.P256(), elliptic.P384(), elliptic.P521():
   251  		raw := rawCurve(curve)
   252  		return asn1.RawValue{
   253  			Tag:       30,
   254  			Bytes:     raw[2:],
   255  			FullBytes: raw,
   256  		}, true
   257  	default:
   258  		return rv, false
   259  	}
   260  }
   261  
   262  func asnECPublicKeyType(curve elliptic.Curve) (algo asnAlgorithmIdentifier, ok bool) {
   263  	raw, ok := curveToRaw(curve)
   264  	if !ok {
   265  		return
   266  	} else {
   267  		return asnAlgorithmIdentifier{Algorithm: idEcPublicKey,
   268  			Parameters: raw}, true
   269  	}
   270  }
   271  
   272  type asnECPrivKeyVer int
   273  
   274  var asnECPrivKeyVer1 asnECPrivKeyVer = 1
   275  
   276  type asnPrivateKey struct {
   277  	Version asnECPrivKeyVer
   278  	Private []byte
   279  	Curve   secgNamedCurve `asn1:"optional"`
   280  	Public  asn1.BitString
   281  }
   282  
   283  var asnECDH = doScheme(secgScheme, []int{12})
   284  
   285  type asnECDHAlgorithm asnAlgorithmIdentifier
   286  
   287  var (
   288  	dhSinglePass_stdDH_sha1kdf = asnECDHAlgorithm{
   289  		Algorithm: doScheme(x963Scheme, []int{2}),
   290  	}
   291  	dhSinglePass_stdDH_sha256kdf = asnECDHAlgorithm{
   292  		Algorithm: doScheme(secgScheme, []int{11, 1}),
   293  	}
   294  	dhSinglePass_stdDH_sha384kdf = asnECDHAlgorithm{
   295  		Algorithm: doScheme(secgScheme, []int{11, 2}),
   296  	}
   297  	dhSinglePass_stdDH_sha224kdf = asnECDHAlgorithm{
   298  		Algorithm: doScheme(secgScheme, []int{11, 0}),
   299  	}
   300  	dhSinglePass_stdDH_sha512kdf = asnECDHAlgorithm{
   301  		Algorithm: doScheme(secgScheme, []int{11, 3}),
   302  	}
   303  )
   304  
   305  func (a asnECDHAlgorithm) Cmp(b asnECDHAlgorithm) bool {
   306  	if len(a.Algorithm) != len(b.Algorithm) {
   307  		return false
   308  	}
   309  	for i := range a.Algorithm {
   310  		if a.Algorithm[i] != b.Algorithm[i] {
   311  			return false
   312  		}
   313  	}
   314  	return true
   315  }
   316  
   317  // asnNISTConcatenation is the only supported KDF at this time.
   318  type asnKeyDerivationFunction asnAlgorithmIdentifier
   319  
   320  var asnNISTConcatenationKDF = asnKeyDerivationFunction{
   321  	Algorithm: doScheme(secgScheme, []int{17, 1}),
   322  }
   323  
   324  func (a asnKeyDerivationFunction) Cmp(b asnKeyDerivationFunction) bool {
   325  	if len(a.Algorithm) != len(b.Algorithm) {
   326  		return false
   327  	}
   328  	for i := range a.Algorithm {
   329  		if a.Algorithm[i] != b.Algorithm[i] {
   330  			return false
   331  		}
   332  	}
   333  	return true
   334  }
   335  
   336  var eciesRecommendedParameters = doScheme(secgScheme, []int{7})
   337  var eciesSpecifiedParameters = doScheme(secgScheme, []int{8})
   338  
   339  type asnECIESParameters struct {
   340  	KDF asnKeyDerivationFunction     `asn1:"optional"`
   341  	Sym asnSymmetricEncryption       `asn1:"optional"`
   342  	MAC asnMessageAuthenticationCode `asn1:"optional"`
   343  }
   344  
   345  type asnSymmetricEncryption asnAlgorithmIdentifier
   346  
   347  var (
   348  	aes128CTRinECIES = asnSymmetricEncryption{
   349  		Algorithm: doScheme(secgScheme, []int{21, 0}),
   350  	}
   351  	aes192CTRinECIES = asnSymmetricEncryption{
   352  		Algorithm: doScheme(secgScheme, []int{21, 1}),
   353  	}
   354  	aes256CTRinECIES = asnSymmetricEncryption{
   355  		Algorithm: doScheme(secgScheme, []int{21, 2}),
   356  	}
   357  )
   358  
   359  func (a asnSymmetricEncryption) Cmp(b asnSymmetricEncryption) bool {
   360  	if len(a.Algorithm) != len(b.Algorithm) {
   361  		return false
   362  	}
   363  	for i := range a.Algorithm {
   364  		if a.Algorithm[i] != b.Algorithm[i] {
   365  			return false
   366  		}
   367  	}
   368  	return true
   369  }
   370  
   371  type asnMessageAuthenticationCode asnAlgorithmIdentifier
   372  
   373  var (
   374  	hmacFull = asnMessageAuthenticationCode{
   375  		Algorithm: doScheme(secgScheme, []int{22}),
   376  	}
   377  )
   378  
   379  func (a asnMessageAuthenticationCode) Cmp(b asnMessageAuthenticationCode) bool {
   380  	if len(a.Algorithm) != len(b.Algorithm) {
   381  		return false
   382  	}
   383  	for i := range a.Algorithm {
   384  		if a.Algorithm[i] != b.Algorithm[i] {
   385  			return false
   386  		}
   387  	}
   388  	return true
   389  }
   390  
   391  type ecpksSupplements struct {
   392  	ECDomain      secgNamedCurve
   393  	ECCAlgorithms eccAlgorithmSet
   394  }
   395  
   396  type eccAlgorithmSet struct {
   397  	ECDH  asnECDHAlgorithm   `asn1:"optional"`
   398  	ECIES asnECIESParameters `asn1:"optional"`
   399  }
   400  
   401  func marshalSubjectPublicKeyInfo(pub *PublicKey) (subj asnSubjectPublicKeyInfo, err error) {
   402  	subj.Algorithm = idEcPublicKeySupplemented
   403  	curve, ok := oidFromNamedCurve(pub.Curve)
   404  	if !ok {
   405  		err = ErrInvalidPublicKey
   406  		return
   407  	}
   408  	subj.Supplements.ECDomain = curve
   409  	if pub.Params != nil {
   410  		subj.Supplements.ECCAlgorithms.ECDH = paramsToASNECDH(pub.Params)
   411  		subj.Supplements.ECCAlgorithms.ECIES = paramsToASNECIES(pub.Params)
   412  	}
   413  	pubkey := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
   414  	subj.PublicKey = asn1.BitString{
   415  		BitLength: len(pubkey) * 8,
   416  		Bytes:     pubkey,
   417  	}
   418  	return
   419  }
   420  
   421  // Encode a public key to DER format.
   422  func MarshalPublic(pub *PublicKey) ([]byte, error) {
   423  	subj, err := marshalSubjectPublicKeyInfo(pub)
   424  	if err != nil {
   425  		return nil, err
   426  	}
   427  	return asn1.Marshal(subj)
   428  }
   429  
   430  // Decode a DER-encoded public key.
   431  func UnmarshalPublic(in []byte) (pub *PublicKey, err error) {
   432  	var subj asnSubjectPublicKeyInfo
   433  
   434  	if _, err = asn1.Unmarshal(in, &subj); err != nil {
   435  		return
   436  	}
   437  	if !subj.Algorithm.Equal(idEcPublicKeySupplemented) {
   438  		err = ErrInvalidPublicKey
   439  		return
   440  	}
   441  	pub = new(PublicKey)
   442  	pub.Curve = namedCurveFromOID(subj.Supplements.ECDomain)
   443  	x, y := elliptic.Unmarshal(pub.Curve, subj.PublicKey.Bytes)
   444  	if x == nil {
   445  		err = ErrInvalidPublicKey
   446  		return
   447  	}
   448  	pub.X = x
   449  	pub.Y = y
   450  	pub.Params = new(ECIESParams)
   451  	asnECIEStoParams(subj.Supplements.ECCAlgorithms.ECIES, pub.Params)
   452  	asnECDHtoParams(subj.Supplements.ECCAlgorithms.ECDH, pub.Params)
   453  	if pub.Params == nil {
   454  		if pub.Params = ParamsFromCurve(pub.Curve); pub.Params == nil {
   455  			err = ErrInvalidPublicKey
   456  		}
   457  	}
   458  	return
   459  }
   460  
   461  func marshalPrivateKey(prv *PrivateKey) (ecprv asnPrivateKey, err error) {
   462  	ecprv.Version = asnECPrivKeyVer1
   463  	ecprv.Private = prv.D.Bytes()
   464  
   465  	var ok bool
   466  	ecprv.Curve, ok = oidFromNamedCurve(prv.PublicKey.Curve)
   467  	if !ok {
   468  		err = ErrInvalidPrivateKey
   469  		return
   470  	}
   471  
   472  	var pub []byte
   473  	if pub, err = MarshalPublic(&prv.PublicKey); err != nil {
   474  		return
   475  	} else {
   476  		ecprv.Public = asn1.BitString{
   477  			BitLength: len(pub) * 8,
   478  			Bytes:     pub,
   479  		}
   480  	}
   481  	return
   482  }
   483  
   484  // Encode a private key to DER format.
   485  func MarshalPrivate(prv *PrivateKey) ([]byte, error) {
   486  	ecprv, err := marshalPrivateKey(prv)
   487  	if err != nil {
   488  		return nil, err
   489  	}
   490  	return asn1.Marshal(ecprv)
   491  }
   492  
   493  // Decode a private key from a DER-encoded format.
   494  func UnmarshalPrivate(in []byte) (prv *PrivateKey, err error) {
   495  	var ecprv asnPrivateKey
   496  
   497  	if _, err = asn1.Unmarshal(in, &ecprv); err != nil {
   498  		return
   499  	} else if ecprv.Version != asnECPrivKeyVer1 {
   500  		err = ErrInvalidPrivateKey
   501  		return
   502  	}
   503  
   504  	privateCurve := namedCurveFromOID(ecprv.Curve)
   505  	if privateCurve == nil {
   506  		err = ErrInvalidPrivateKey
   507  		return
   508  	}
   509  
   510  	prv = new(PrivateKey)
   511  	prv.D = new(big.Int).SetBytes(ecprv.Private)
   512  
   513  	if pub, err := UnmarshalPublic(ecprv.Public.Bytes); err != nil {
   514  		return nil, err
   515  	} else {
   516  		prv.PublicKey = *pub
   517  	}
   518  
   519  	return
   520  }
   521  
   522  // Export a public key to PEM format.
   523  func ExportPublicPEM(pub *PublicKey) (out []byte, err error) {
   524  	der, err := MarshalPublic(pub)
   525  	if err != nil {
   526  		return
   527  	}
   528  
   529  	var block pem.Block
   530  	block.Type = "ELLIPTIC CURVE PUBLIC KEY"
   531  	block.Bytes = der
   532  
   533  	buf := new(bytes.Buffer)
   534  	err = pem.Encode(buf, &block)
   535  	if err != nil {
   536  		return
   537  	} else {
   538  		out = buf.Bytes()
   539  	}
   540  	return
   541  }
   542  
   543  // Export a private key to PEM format.
   544  func ExportPrivatePEM(prv *PrivateKey) (out []byte, err error) {
   545  	der, err := MarshalPrivate(prv)
   546  	if err != nil {
   547  		return
   548  	}
   549  
   550  	var block pem.Block
   551  	block.Type = "ELLIPTIC CURVE PRIVATE KEY"
   552  	block.Bytes = der
   553  
   554  	buf := new(bytes.Buffer)
   555  	err = pem.Encode(buf, &block)
   556  	if err != nil {
   557  		return
   558  	} else {
   559  		out = buf.Bytes()
   560  	}
   561  	return
   562  }
   563  
   564  // Import a PEM-encoded public key.
   565  func ImportPublicPEM(in []byte) (pub *PublicKey, err error) {
   566  	p, _ := pem.Decode(in)
   567  	if p == nil || p.Type != "ELLIPTIC CURVE PUBLIC KEY" {
   568  		return nil, ErrInvalidPublicKey
   569  	}
   570  
   571  	pub, err = UnmarshalPublic(p.Bytes)
   572  	return
   573  }
   574  
   575  // Import a PEM-encoded private key.
   576  func ImportPrivatePEM(in []byte) (prv *PrivateKey, err error) {
   577  	p, _ := pem.Decode(in)
   578  	if p == nil || p.Type != "ELLIPTIC CURVE PRIVATE KEY" {
   579  		return nil, ErrInvalidPrivateKey
   580  	}
   581  
   582  	prv, err = UnmarshalPrivate(p.Bytes)
   583  	return
   584  }