asn1.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  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. package ecies
  30. import (
  31. "bytes"
  32. "crypto"
  33. "crypto/elliptic"
  34. "crypto/sha1"
  35. "crypto/sha256"
  36. "crypto/sha512"
  37. "encoding/asn1"
  38. "encoding/pem"
  39. "fmt"
  40. "hash"
  41. "math/big"
  42. ethcrypto "github.com/ethereum/go-ethereum/crypto"
  43. )
  44. var (
  45. secgScheme = []int{1, 3, 132, 1}
  46. shaScheme = []int{2, 16, 840, 1, 101, 3, 4, 2}
  47. ansiX962Scheme = []int{1, 2, 840, 10045}
  48. x963Scheme = []int{1, 2, 840, 63, 0}
  49. )
  50. var ErrInvalidPrivateKey = fmt.Errorf("ecies: invalid private key")
  51. func doScheme(base, v []int) asn1.ObjectIdentifier {
  52. var oidInts asn1.ObjectIdentifier
  53. oidInts = append(oidInts, base...)
  54. return append(oidInts, v...)
  55. }
  56. // curve OID code taken from crypto/x509, including
  57. // - oidNameCurve*
  58. // - namedCurveFromOID
  59. // - oidFromNamedCurve
  60. // RFC 5480, 2.1.1.1. Named Curve
  61. //
  62. // secp224r1 OBJECT IDENTIFIER ::= {
  63. // iso(1) identified-organization(3) certicom(132) curve(0) 33 }
  64. //
  65. // secp256r1 OBJECT IDENTIFIER ::= {
  66. // iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
  67. // prime(1) 7 }
  68. //
  69. // secp384r1 OBJECT IDENTIFIER ::= {
  70. // iso(1) identified-organization(3) certicom(132) curve(0) 34 }
  71. //
  72. // secp521r1 OBJECT IDENTIFIER ::= {
  73. // iso(1) identified-organization(3) certicom(132) curve(0) 35 }
  74. //
  75. // NB: secp256r1 is equivalent to prime256v1
  76. type secgNamedCurve asn1.ObjectIdentifier
  77. var (
  78. secgNamedCurveS256 = secgNamedCurve{1, 3, 132, 0, 10}
  79. secgNamedCurveP256 = secgNamedCurve{1, 2, 840, 10045, 3, 1, 7}
  80. secgNamedCurveP384 = secgNamedCurve{1, 3, 132, 0, 34}
  81. secgNamedCurveP521 = secgNamedCurve{1, 3, 132, 0, 35}
  82. rawCurveP256 = []byte{6, 8, 4, 2, 1, 3, 4, 7, 2, 2, 0, 6, 6, 1, 3, 1, 7}
  83. rawCurveP384 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 4}
  84. rawCurveP521 = []byte{6, 5, 4, 3, 1, 2, 9, 4, 0, 3, 5}
  85. )
  86. func rawCurve(curve elliptic.Curve) []byte {
  87. switch curve {
  88. case elliptic.P256():
  89. return rawCurveP256
  90. case elliptic.P384():
  91. return rawCurveP384
  92. case elliptic.P521():
  93. return rawCurveP521
  94. default:
  95. return nil
  96. }
  97. }
  98. func (curve secgNamedCurve) Equal(curve2 secgNamedCurve) bool {
  99. if len(curve) != len(curve2) {
  100. return false
  101. }
  102. for i := range curve {
  103. if curve[i] != curve2[i] {
  104. return false
  105. }
  106. }
  107. return true
  108. }
  109. func namedCurveFromOID(curve secgNamedCurve) elliptic.Curve {
  110. switch {
  111. case curve.Equal(secgNamedCurveS256):
  112. return ethcrypto.S256()
  113. case curve.Equal(secgNamedCurveP256):
  114. return elliptic.P256()
  115. case curve.Equal(secgNamedCurveP384):
  116. return elliptic.P384()
  117. case curve.Equal(secgNamedCurveP521):
  118. return elliptic.P521()
  119. }
  120. return nil
  121. }
  122. func oidFromNamedCurve(curve elliptic.Curve) (secgNamedCurve, bool) {
  123. switch curve {
  124. case elliptic.P256():
  125. return secgNamedCurveP256, true
  126. case elliptic.P384():
  127. return secgNamedCurveP384, true
  128. case elliptic.P521():
  129. return secgNamedCurveP521, true
  130. case ethcrypto.S256():
  131. return secgNamedCurveS256, true
  132. }
  133. return nil, false
  134. }
  135. // asnAlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
  136. // 5280, section 4.1.1.2.
  137. type asnAlgorithmIdentifier struct {
  138. Algorithm asn1.ObjectIdentifier
  139. Parameters asn1.RawValue `asn1:"optional"`
  140. }
  141. func (a asnAlgorithmIdentifier) Cmp(b asnAlgorithmIdentifier) bool {
  142. if len(a.Algorithm) != len(b.Algorithm) {
  143. return false
  144. }
  145. for i := range a.Algorithm {
  146. if a.Algorithm[i] != b.Algorithm[i] {
  147. return false
  148. }
  149. }
  150. return true
  151. }
  152. type asnHashFunction asnAlgorithmIdentifier
  153. var (
  154. oidSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
  155. oidSHA224 = doScheme(shaScheme, []int{4})
  156. oidSHA256 = doScheme(shaScheme, []int{1})
  157. oidSHA384 = doScheme(shaScheme, []int{2})
  158. oidSHA512 = doScheme(shaScheme, []int{3})
  159. )
  160. func hashFromOID(oid asn1.ObjectIdentifier) func() hash.Hash {
  161. switch {
  162. case oid.Equal(oidSHA1):
  163. return sha1.New
  164. case oid.Equal(oidSHA224):
  165. return sha256.New224
  166. case oid.Equal(oidSHA256):
  167. return sha256.New
  168. case oid.Equal(oidSHA384):
  169. return sha512.New384
  170. case oid.Equal(oidSHA512):
  171. return sha512.New
  172. }
  173. return nil
  174. }
  175. func oidFromHash(hash crypto.Hash) (asn1.ObjectIdentifier, bool) {
  176. switch hash {
  177. case crypto.SHA1:
  178. return oidSHA1, true
  179. case crypto.SHA224:
  180. return oidSHA224, true
  181. case crypto.SHA256:
  182. return oidSHA256, true
  183. case crypto.SHA384:
  184. return oidSHA384, true
  185. case crypto.SHA512:
  186. return oidSHA512, true
  187. default:
  188. return nil, false
  189. }
  190. }
  191. var (
  192. asnAlgoSHA1 = asnHashFunction{
  193. Algorithm: oidSHA1,
  194. }
  195. asnAlgoSHA224 = asnHashFunction{
  196. Algorithm: oidSHA224,
  197. }
  198. asnAlgoSHA256 = asnHashFunction{
  199. Algorithm: oidSHA256,
  200. }
  201. asnAlgoSHA384 = asnHashFunction{
  202. Algorithm: oidSHA384,
  203. }
  204. asnAlgoSHA512 = asnHashFunction{
  205. Algorithm: oidSHA512,
  206. }
  207. )
  208. // type ASNasnSubjectPublicKeyInfo struct {
  209. //
  210. // }
  211. //
  212. type asnSubjectPublicKeyInfo struct {
  213. Algorithm asn1.ObjectIdentifier
  214. PublicKey asn1.BitString
  215. Supplements ecpksSupplements `asn1:"optional"`
  216. }
  217. type asnECPKAlgorithms struct {
  218. Type asn1.ObjectIdentifier
  219. }
  220. var idPublicKeyType = doScheme(ansiX962Scheme, []int{2})
  221. var idEcPublicKey = doScheme(idPublicKeyType, []int{1})
  222. var idEcPublicKeySupplemented = doScheme(idPublicKeyType, []int{0})
  223. func curveToRaw(curve elliptic.Curve) (rv asn1.RawValue, ok bool) {
  224. switch curve {
  225. case elliptic.P256(), elliptic.P384(), elliptic.P521():
  226. raw := rawCurve(curve)
  227. return asn1.RawValue{
  228. Tag: 30,
  229. Bytes: raw[2:],
  230. FullBytes: raw,
  231. }, true
  232. default:
  233. return rv, false
  234. }
  235. }
  236. func asnECPublicKeyType(curve elliptic.Curve) (algo asnAlgorithmIdentifier, ok bool) {
  237. raw, ok := curveToRaw(curve)
  238. if !ok {
  239. return
  240. } else {
  241. return asnAlgorithmIdentifier{Algorithm: idEcPublicKey,
  242. Parameters: raw}, true
  243. }
  244. }
  245. type asnECPrivKeyVer int
  246. var asnECPrivKeyVer1 asnECPrivKeyVer = 1
  247. type asnPrivateKey struct {
  248. Version asnECPrivKeyVer
  249. Private []byte
  250. Curve secgNamedCurve `asn1:"optional"`
  251. Public asn1.BitString
  252. }
  253. var asnECDH = doScheme(secgScheme, []int{12})
  254. type asnECDHAlgorithm asnAlgorithmIdentifier
  255. var (
  256. dhSinglePass_stdDH_sha1kdf = asnECDHAlgorithm{
  257. Algorithm: doScheme(x963Scheme, []int{2}),
  258. }
  259. dhSinglePass_stdDH_sha256kdf = asnECDHAlgorithm{
  260. Algorithm: doScheme(secgScheme, []int{11, 1}),
  261. }
  262. dhSinglePass_stdDH_sha384kdf = asnECDHAlgorithm{
  263. Algorithm: doScheme(secgScheme, []int{11, 2}),
  264. }
  265. dhSinglePass_stdDH_sha224kdf = asnECDHAlgorithm{
  266. Algorithm: doScheme(secgScheme, []int{11, 0}),
  267. }
  268. dhSinglePass_stdDH_sha512kdf = asnECDHAlgorithm{
  269. Algorithm: doScheme(secgScheme, []int{11, 3}),
  270. }
  271. )
  272. func (a asnECDHAlgorithm) Cmp(b asnECDHAlgorithm) bool {
  273. if len(a.Algorithm) != len(b.Algorithm) {
  274. return false
  275. }
  276. for i := range a.Algorithm {
  277. if a.Algorithm[i] != b.Algorithm[i] {
  278. return false
  279. }
  280. }
  281. return true
  282. }
  283. // asnNISTConcatenation is the only supported KDF at this time.
  284. type asnKeyDerivationFunction asnAlgorithmIdentifier
  285. var asnNISTConcatenationKDF = asnKeyDerivationFunction{
  286. Algorithm: doScheme(secgScheme, []int{17, 1}),
  287. }
  288. func (a asnKeyDerivationFunction) Cmp(b asnKeyDerivationFunction) bool {
  289. if len(a.Algorithm) != len(b.Algorithm) {
  290. return false
  291. }
  292. for i := range a.Algorithm {
  293. if a.Algorithm[i] != b.Algorithm[i] {
  294. return false
  295. }
  296. }
  297. return true
  298. }
  299. var eciesRecommendedParameters = doScheme(secgScheme, []int{7})
  300. var eciesSpecifiedParameters = doScheme(secgScheme, []int{8})
  301. type asnECIESParameters struct {
  302. KDF asnKeyDerivationFunction `asn1:"optional"`
  303. Sym asnSymmetricEncryption `asn1:"optional"`
  304. MAC asnMessageAuthenticationCode `asn1:"optional"`
  305. }
  306. type asnSymmetricEncryption asnAlgorithmIdentifier
  307. var (
  308. aes128CTRinECIES = asnSymmetricEncryption{
  309. Algorithm: doScheme(secgScheme, []int{21, 0}),
  310. }
  311. aes192CTRinECIES = asnSymmetricEncryption{
  312. Algorithm: doScheme(secgScheme, []int{21, 1}),
  313. }
  314. aes256CTRinECIES = asnSymmetricEncryption{
  315. Algorithm: doScheme(secgScheme, []int{21, 2}),
  316. }
  317. )
  318. func (a asnSymmetricEncryption) Cmp(b asnSymmetricEncryption) bool {
  319. if len(a.Algorithm) != len(b.Algorithm) {
  320. return false
  321. }
  322. for i := range a.Algorithm {
  323. if a.Algorithm[i] != b.Algorithm[i] {
  324. return false
  325. }
  326. }
  327. return true
  328. }
  329. type asnMessageAuthenticationCode asnAlgorithmIdentifier
  330. var (
  331. hmacFull = asnMessageAuthenticationCode{
  332. Algorithm: doScheme(secgScheme, []int{22}),
  333. }
  334. )
  335. func (a asnMessageAuthenticationCode) Cmp(b asnMessageAuthenticationCode) bool {
  336. if len(a.Algorithm) != len(b.Algorithm) {
  337. return false
  338. }
  339. for i := range a.Algorithm {
  340. if a.Algorithm[i] != b.Algorithm[i] {
  341. return false
  342. }
  343. }
  344. return true
  345. }
  346. type ecpksSupplements struct {
  347. ECDomain secgNamedCurve
  348. ECCAlgorithms eccAlgorithmSet
  349. }
  350. type eccAlgorithmSet struct {
  351. ECDH asnECDHAlgorithm `asn1:"optional"`
  352. ECIES asnECIESParameters `asn1:"optional"`
  353. }
  354. func marshalSubjectPublicKeyInfo(pub *PublicKey) (subj asnSubjectPublicKeyInfo, err error) {
  355. subj.Algorithm = idEcPublicKeySupplemented
  356. curve, ok := oidFromNamedCurve(pub.Curve)
  357. if !ok {
  358. err = ErrInvalidPublicKey
  359. return
  360. }
  361. subj.Supplements.ECDomain = curve
  362. if pub.Params != nil {
  363. subj.Supplements.ECCAlgorithms.ECDH = paramsToASNECDH(pub.Params)
  364. subj.Supplements.ECCAlgorithms.ECIES = paramsToASNECIES(pub.Params)
  365. }
  366. pubkey := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
  367. subj.PublicKey = asn1.BitString{
  368. BitLength: len(pubkey) * 8,
  369. Bytes: pubkey,
  370. }
  371. return
  372. }
  373. // Encode a public key to DER format.
  374. func MarshalPublic(pub *PublicKey) ([]byte, error) {
  375. subj, err := marshalSubjectPublicKeyInfo(pub)
  376. if err != nil {
  377. return nil, err
  378. }
  379. return asn1.Marshal(subj)
  380. }
  381. // Decode a DER-encoded public key.
  382. func UnmarshalPublic(in []byte) (pub *PublicKey, err error) {
  383. var subj asnSubjectPublicKeyInfo
  384. if _, err = asn1.Unmarshal(in, &subj); err != nil {
  385. return
  386. }
  387. if !subj.Algorithm.Equal(idEcPublicKeySupplemented) {
  388. err = ErrInvalidPublicKey
  389. return
  390. }
  391. pub = new(PublicKey)
  392. pub.Curve = namedCurveFromOID(subj.Supplements.ECDomain)
  393. x, y := elliptic.Unmarshal(pub.Curve, subj.PublicKey.Bytes)
  394. if x == nil {
  395. err = ErrInvalidPublicKey
  396. return
  397. }
  398. pub.X = x
  399. pub.Y = y
  400. pub.Params = new(ECIESParams)
  401. asnECIEStoParams(subj.Supplements.ECCAlgorithms.ECIES, pub.Params)
  402. asnECDHtoParams(subj.Supplements.ECCAlgorithms.ECDH, pub.Params)
  403. if pub.Params == nil {
  404. if pub.Params = ParamsFromCurve(pub.Curve); pub.Params == nil {
  405. err = ErrInvalidPublicKey
  406. }
  407. }
  408. return
  409. }
  410. func marshalPrivateKey(prv *PrivateKey) (ecprv asnPrivateKey, err error) {
  411. ecprv.Version = asnECPrivKeyVer1
  412. ecprv.Private = prv.D.Bytes()
  413. var ok bool
  414. ecprv.Curve, ok = oidFromNamedCurve(prv.PublicKey.Curve)
  415. if !ok {
  416. err = ErrInvalidPrivateKey
  417. return
  418. }
  419. var pub []byte
  420. if pub, err = MarshalPublic(&prv.PublicKey); err != nil {
  421. return
  422. } else {
  423. ecprv.Public = asn1.BitString{
  424. BitLength: len(pub) * 8,
  425. Bytes: pub,
  426. }
  427. }
  428. return
  429. }
  430. // Encode a private key to DER format.
  431. func MarshalPrivate(prv *PrivateKey) ([]byte, error) {
  432. ecprv, err := marshalPrivateKey(prv)
  433. if err != nil {
  434. return nil, err
  435. }
  436. return asn1.Marshal(ecprv)
  437. }
  438. // Decode a private key from a DER-encoded format.
  439. func UnmarshalPrivate(in []byte) (prv *PrivateKey, err error) {
  440. var ecprv asnPrivateKey
  441. if _, err = asn1.Unmarshal(in, &ecprv); err != nil {
  442. return
  443. } else if ecprv.Version != asnECPrivKeyVer1 {
  444. err = ErrInvalidPrivateKey
  445. return
  446. }
  447. privateCurve := namedCurveFromOID(ecprv.Curve)
  448. if privateCurve == nil {
  449. err = ErrInvalidPrivateKey
  450. return
  451. }
  452. prv = new(PrivateKey)
  453. prv.D = new(big.Int).SetBytes(ecprv.Private)
  454. if pub, err := UnmarshalPublic(ecprv.Public.Bytes); err != nil {
  455. return nil, err
  456. } else {
  457. prv.PublicKey = *pub
  458. }
  459. return
  460. }
  461. // Export a public key to PEM format.
  462. func ExportPublicPEM(pub *PublicKey) (out []byte, err error) {
  463. der, err := MarshalPublic(pub)
  464. if err != nil {
  465. return
  466. }
  467. var block pem.Block
  468. block.Type = "ELLIPTIC CURVE PUBLIC KEY"
  469. block.Bytes = der
  470. buf := new(bytes.Buffer)
  471. err = pem.Encode(buf, &block)
  472. if err != nil {
  473. return
  474. } else {
  475. out = buf.Bytes()
  476. }
  477. return
  478. }
  479. // Export a private key to PEM format.
  480. func ExportPrivatePEM(prv *PrivateKey) (out []byte, err error) {
  481. der, err := MarshalPrivate(prv)
  482. if err != nil {
  483. return
  484. }
  485. var block pem.Block
  486. block.Type = "ELLIPTIC CURVE PRIVATE KEY"
  487. block.Bytes = der
  488. buf := new(bytes.Buffer)
  489. err = pem.Encode(buf, &block)
  490. if err != nil {
  491. return
  492. } else {
  493. out = buf.Bytes()
  494. }
  495. return
  496. }
  497. // Import a PEM-encoded public key.
  498. func ImportPublicPEM(in []byte) (pub *PublicKey, err error) {
  499. p, _ := pem.Decode(in)
  500. if p == nil || p.Type != "ELLIPTIC CURVE PUBLIC KEY" {
  501. return nil, ErrInvalidPublicKey
  502. }
  503. pub, err = UnmarshalPublic(p.Bytes)
  504. return
  505. }
  506. // Import a PEM-encoded private key.
  507. func ImportPrivatePEM(in []byte) (prv *PrivateKey, err error) {
  508. p, _ := pem.Decode(in)
  509. if p == nil || p.Type != "ELLIPTIC CURVE PRIVATE KEY" {
  510. return nil, ErrInvalidPrivateKey
  511. }
  512. prv, err = UnmarshalPrivate(p.Bytes)
  513. return
  514. }