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 }