identity.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2023-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package zerotier
  14. //#cgo CFLAGS: -O3
  15. //#include "../../native/GoGlue.h"
  16. import "C"
  17. import (
  18. "encoding/hex"
  19. "encoding/json"
  20. "fmt"
  21. "strings"
  22. "unsafe"
  23. )
  24. // IdentityTypeC25519 is a classic Curve25519/Ed25519 identity
  25. const IdentityTypeC25519 = 0
  26. // IdentityTypeP384 is an identity containing both NIST P-384 and Curve25519/Ed25519 key types and leveraging both when possible
  27. const IdentityTypeP384 = 1
  28. // Sizes of components of different identity types
  29. const (
  30. IdentityTypeC25519PublicKeySize = 64 // C25519/Ed25519 keys
  31. IdentityTypeC25519PrivateKeySize = 64 // C25519/Ed25519 private keys
  32. IdentityTypeP384PublicKeySize = 209 // C25519/Ed25519, P-384 point-compressed public, P-384 self-signature
  33. IdentityTypeP384PrivateKeySize = 112 // C25519/Ed25519 and P-384 private keys
  34. )
  35. // Identity is precisely what it sounds like: the address and associated keys for a ZeroTier node
  36. type Identity struct {
  37. address Address
  38. idtype int
  39. publicKey []byte
  40. privateKey []byte
  41. }
  42. // NewIdentity generates a new identity of the selected type
  43. func NewIdentity(identityType int) (*Identity, error) {
  44. cIdStr := C.ZT_GoIdentity_generate(C.int(identityType))
  45. if uintptr(unsafe.Pointer(cIdStr)) == 0 {
  46. return nil, ErrInternal
  47. }
  48. id, err := NewIdentityFromString(C.GoString(cIdStr))
  49. C.free(unsafe.Pointer(cIdStr))
  50. return id, err
  51. }
  52. // NewIdentityFromString generates a new identity from its string representation.
  53. // The private key is imported as well if it is present.
  54. func NewIdentityFromString(s string) (*Identity, error) {
  55. ss := strings.Split(strings.TrimSpace(s), ":")
  56. if len(ss) < 3 {
  57. return nil, ErrInvalidParameter
  58. }
  59. var err error
  60. var id Identity
  61. id.address, err = NewAddressFromString(ss[0])
  62. if err != nil {
  63. return nil, err
  64. }
  65. if ss[1] == "0" {
  66. id.idtype = 0
  67. } else if ss[1] == "1" {
  68. id.idtype = 1
  69. } else {
  70. return nil, ErrUnrecognizedIdentityType
  71. }
  72. switch id.idtype {
  73. case 0:
  74. id.publicKey, err = hex.DecodeString(ss[2])
  75. if err != nil {
  76. return nil, err
  77. }
  78. if len(ss) >= 4 {
  79. id.privateKey, err = hex.DecodeString(ss[3])
  80. if err != nil {
  81. return nil, err
  82. }
  83. }
  84. case 1:
  85. id.publicKey, err = Base32StdLowerCase.DecodeString(ss[2])
  86. if err != nil {
  87. return nil, err
  88. }
  89. if len(id.publicKey) != IdentityTypeP384PublicKeySize {
  90. return nil, ErrInvalidKey
  91. }
  92. if len(ss) >= 4 {
  93. id.privateKey, err = Base32StdLowerCase.DecodeString(ss[3])
  94. if err != nil {
  95. return nil, err
  96. }
  97. if len(id.privateKey) != IdentityTypeP384PrivateKeySize {
  98. return nil, ErrInvalidKey
  99. }
  100. }
  101. }
  102. return &id, nil
  103. }
  104. // Address returns this identity's address
  105. func (id *Identity) Address() Address { return id.address }
  106. // HasPrivate returns true if this identity has its own private portion.
  107. func (id *Identity) HasPrivate() bool { return len(id.privateKey) > 0 }
  108. // PrivateKeyString returns the full identity.secret if the private key is set, or an empty string if no private key is set.
  109. func (id *Identity) PrivateKeyString() string {
  110. switch id.idtype {
  111. case IdentityTypeC25519:
  112. if len(id.publicKey) == IdentityTypeC25519PublicKeySize && len(id.privateKey) == IdentityTypeC25519PrivateKeySize {
  113. return fmt.Sprintf("%.10x:0:%x:%x", uint64(id.address), id.publicKey, id.privateKey)
  114. }
  115. case IdentityTypeP384:
  116. if len(id.publicKey) == IdentityTypeP384PublicKeySize && len(id.privateKey) == IdentityTypeP384PrivateKeySize {
  117. return fmt.Sprintf("%.10x:1:%s:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey), Base32StdLowerCase.EncodeToString(id.privateKey))
  118. }
  119. }
  120. return ""
  121. }
  122. // PublicKeyString returns the address and public key (identity.public contents).
  123. // An empty string is returned if this identity is invalid or not initialized.
  124. func (id *Identity) String() string {
  125. switch id.idtype {
  126. case IdentityTypeC25519:
  127. if len(id.publicKey) == IdentityTypeC25519PublicKeySize {
  128. return fmt.Sprintf("%.10x:0:%x", uint64(id.address), id.publicKey)
  129. }
  130. case IdentityTypeP384:
  131. if len(id.publicKey) == IdentityTypeP384PublicKeySize {
  132. return fmt.Sprintf("%.10x:1:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey))
  133. }
  134. }
  135. return ""
  136. }
  137. // LocallyValidate performs local self-validation of this identity
  138. func (id *Identity) LocallyValidate() bool {
  139. idCStr := C.CString(id.String())
  140. defer C.free(unsafe.Pointer(idCStr))
  141. return C.ZT_GoIdentity_validate(idCStr) != 0
  142. }
  143. // Sign signs a message with this identity
  144. func (id *Identity) Sign(msg []byte) ([]byte, error) {
  145. idCStr := C.CString(id.PrivateKeyString())
  146. var sigbuf [96]byte
  147. var dataP unsafe.Pointer
  148. if len(msg) > 0 {
  149. dataP = unsafe.Pointer(&msg[0])
  150. }
  151. siglen := C.ZT_GoIdentity_sign(idCStr, dataP, C.uint(len(msg)), unsafe.Pointer(&sigbuf[0]), C.uint(len(sigbuf)))
  152. C.free(unsafe.Pointer(idCStr))
  153. if siglen <= 0 {
  154. return nil, ErrInvalidKey
  155. }
  156. return sigbuf[0:int(siglen)], nil
  157. }
  158. // Verify verifies a signature
  159. func (id *Identity) Verify(msg, sig []byte) bool {
  160. if len(sig) == 0 {
  161. return false
  162. }
  163. idCStr := C.CString(id.String())
  164. defer C.free(unsafe.Pointer(idCStr))
  165. var dataP unsafe.Pointer
  166. if len(msg) > 0 {
  167. dataP = unsafe.Pointer(&msg[0])
  168. }
  169. return C.ZT_GoIdentity_verify(idCStr, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), C.uint(len(sig))) != 0
  170. }
  171. // MarshalJSON marshals this Identity in its string format (private key is never included)
  172. func (id *Identity) MarshalJSON() ([]byte, error) {
  173. return []byte("\"" + id.String() + "\""), nil
  174. }
  175. // UnmarshalJSON unmarshals this Identity from a string
  176. func (id *Identity) UnmarshalJSON(j []byte) error {
  177. var s string
  178. err := json.Unmarshal(j, &s)
  179. if err != nil {
  180. return err
  181. }
  182. nid, err := NewIdentityFromString(s)
  183. if err != nil {
  184. return err
  185. }
  186. *id = *nid
  187. return nil
  188. }