identity.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright (c)2013-2020 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: 2024-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. // #include "../../native/GoGlue.h"
  15. import "C"
  16. import (
  17. "bytes"
  18. "encoding/hex"
  19. "encoding/json"
  20. "fmt"
  21. "runtime"
  22. "strings"
  23. "unsafe"
  24. )
  25. // Constants from node/Identity.hpp (must be the same)
  26. const (
  27. IdentityTypeC25519 = 0
  28. IdentityTypeP384 = 1
  29. IdentityTypeC25519PublicKeySize = 64
  30. IdentityTypeC25519PrivateKeySize = 64
  31. IdentityTypeP384PublicKeySize = 114
  32. IdentityTypeP384PrivateKeySize = 112
  33. )
  34. // Identity is precisely what it sounds like: the address and associated keys for a ZeroTier node
  35. type Identity struct {
  36. address Address
  37. idtype int
  38. publicKey []byte
  39. privateKey []byte
  40. cid unsafe.Pointer // ZT_Identity
  41. }
  42. func identityFinalizer(obj interface{}) {
  43. id, _ := obj.(*Identity)
  44. if id != nil && uintptr(id.cid) != 0 {
  45. C.ZT_Identity_delete(id.cid)
  46. }
  47. }
  48. func newIdentityFromCIdentity(cid unsafe.Pointer) (*Identity, error) {
  49. if uintptr(cid) == 0 {
  50. return nil, ErrInvalidParameter
  51. }
  52. var idStrBuf [4096]byte
  53. idStr := C.ZT_Identity_toString(cid, (*C.char)(unsafe.Pointer(&idStrBuf[0])), 4096, 1)
  54. if uintptr(unsafe.Pointer(idStr)) == 0 {
  55. return nil, ErrInternal
  56. }
  57. id, err := NewIdentityFromString(C.GoString(idStr))
  58. if err != nil {
  59. return nil, err
  60. }
  61. id.cid = cid
  62. runtime.SetFinalizer(id, identityFinalizer)
  63. return id, nil
  64. }
  65. // initCIdentityPtr returns a pointer to the core ZT_Identity instance or nil/0 on error.
  66. func (id *Identity) initCIdentityPtr() bool {
  67. if uintptr(id.cid) == 0 {
  68. idCStr := C.CString(id.String())
  69. defer C.free(unsafe.Pointer(idCStr))
  70. id.cid = C.ZT_Identity_fromString(idCStr)
  71. if uintptr(id.cid) == 0 {
  72. return false
  73. }
  74. runtime.SetFinalizer(id, identityFinalizer)
  75. }
  76. return true
  77. }
  78. // NewIdentity generates a new identity of the selected type
  79. func NewIdentity(identityType int) (*Identity, error) {
  80. switch identityType {
  81. case C.ZT_IDENTITY_TYPE_C25519:
  82. return newIdentityFromCIdentity(C.ZT_Identity_new(C.ZT_IDENTITY_TYPE_C25519))
  83. case C.ZT_IDENTITY_TYPE_P384:
  84. return newIdentityFromCIdentity(C.ZT_Identity_new(C.ZT_IDENTITY_TYPE_P384))
  85. }
  86. return nil, ErrInvalidParameter
  87. }
  88. // NewIdentityFromString generates a new identity from its string representation.
  89. // The private key is imported as well if it is present.
  90. func NewIdentityFromString(s string) (*Identity, error) {
  91. ss := strings.Split(strings.TrimSpace(s), ":")
  92. if len(ss) < 3 {
  93. return nil, ErrInvalidParameter
  94. }
  95. var err error
  96. id := new(Identity)
  97. id.address, err = NewAddressFromString(ss[0])
  98. if err != nil {
  99. return nil, err
  100. }
  101. if ss[1] == "0" {
  102. id.idtype = 0
  103. } else if ss[1] == "1" {
  104. id.idtype = 1
  105. } else {
  106. return nil, ErrUnrecognizedIdentityType
  107. }
  108. switch id.idtype {
  109. case 0:
  110. id.publicKey, err = hex.DecodeString(ss[2])
  111. if err != nil {
  112. return nil, err
  113. }
  114. if len(ss) >= 4 {
  115. id.privateKey, err = hex.DecodeString(ss[3])
  116. if err != nil {
  117. return nil, err
  118. }
  119. }
  120. case 1:
  121. id.publicKey, err = Base32StdLowerCase.DecodeString(ss[2])
  122. if err != nil {
  123. return nil, err
  124. }
  125. if len(id.publicKey) != IdentityTypeP384PublicKeySize {
  126. return nil, ErrInvalidKey
  127. }
  128. if len(ss) >= 4 {
  129. id.privateKey, err = Base32StdLowerCase.DecodeString(ss[3])
  130. if err != nil {
  131. return nil, err
  132. }
  133. if len(id.privateKey) != IdentityTypeP384PrivateKeySize {
  134. return nil, ErrInvalidKey
  135. }
  136. }
  137. }
  138. return id, nil
  139. }
  140. // Address returns this identity's address
  141. func (id *Identity) Address() Address { return id.address }
  142. // HasPrivate returns true if this identity has its own private portion.
  143. func (id *Identity) HasPrivate() bool { return len(id.privateKey) > 0 }
  144. // Fingerprint gets this identity's address plus hash of public key(s).
  145. func (id *Identity) Fingerprint() *Fingerprint {
  146. id.initCIdentityPtr()
  147. return newFingerprintFromCFingerprint(C.ZT_Identity_fingerprint(id.cid))
  148. }
  149. // PrivateKeyString returns the full identity.secret if the private key is set, or an empty string if no private key is set.
  150. func (id *Identity) PrivateKeyString() string {
  151. switch id.idtype {
  152. case IdentityTypeC25519:
  153. if len(id.publicKey) == IdentityTypeC25519PublicKeySize && len(id.privateKey) == IdentityTypeC25519PrivateKeySize {
  154. return fmt.Sprintf("%.10x:0:%x:%x", uint64(id.address), id.publicKey, id.privateKey)
  155. }
  156. case IdentityTypeP384:
  157. if len(id.publicKey) == IdentityTypeP384PublicKeySize && len(id.privateKey) == IdentityTypeP384PrivateKeySize {
  158. return fmt.Sprintf("%.10x:1:%s:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey), Base32StdLowerCase.EncodeToString(id.privateKey))
  159. }
  160. }
  161. return ""
  162. }
  163. // PublicKeyString returns the address and public key (identity.public contents).
  164. // An empty string is returned if this identity is invalid or not initialized.
  165. func (id *Identity) String() string {
  166. switch id.idtype {
  167. case IdentityTypeC25519:
  168. if len(id.publicKey) == IdentityTypeC25519PublicKeySize {
  169. return fmt.Sprintf("%.10x:0:%x", uint64(id.address), id.publicKey)
  170. }
  171. case IdentityTypeP384:
  172. if len(id.publicKey) == IdentityTypeP384PublicKeySize {
  173. return fmt.Sprintf("%.10x:1:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey))
  174. }
  175. }
  176. return ""
  177. }
  178. // LocallyValidate performs local self-validation of this identity
  179. func (id *Identity) LocallyValidate() bool {
  180. if !id.initCIdentityPtr() {
  181. return false
  182. }
  183. return C.ZT_Identity_validate(id.cid) != 0
  184. }
  185. // Sign signs a message with this identity
  186. func (id *Identity) Sign(msg []byte) ([]byte, error) {
  187. if !id.initCIdentityPtr() {
  188. return nil, ErrInvalidKey
  189. }
  190. var dataP unsafe.Pointer
  191. if len(msg) > 0 {
  192. dataP = unsafe.Pointer(&msg[0])
  193. }
  194. var sig [96]byte
  195. sigLen := C.ZT_Identity_sign(id.cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), 96)
  196. if sigLen <= 0 {
  197. return nil, ErrInvalidKey
  198. }
  199. return sig[0:uint(sigLen)], nil
  200. }
  201. // Verify verifies a signature
  202. func (id *Identity) Verify(msg, sig []byte) bool {
  203. if len(sig) == 0 || !id.initCIdentityPtr() {
  204. return false
  205. }
  206. var dataP unsafe.Pointer
  207. if len(msg) > 0 {
  208. dataP = unsafe.Pointer(&msg[0])
  209. }
  210. return C.ZT_Identity_verify(id.cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), C.uint(len(sig))) != 0
  211. }
  212. // Equals performs a deep equality test between this and another identity
  213. func (id *Identity) Equals(id2 *Identity) bool {
  214. if id2 == nil {
  215. return id == nil
  216. }
  217. if id == nil {
  218. return false
  219. }
  220. return id.address == id2.address && id.idtype == id2.idtype && bytes.Equal(id.publicKey, id2.publicKey) && bytes.Equal(id.privateKey, id2.privateKey)
  221. }
  222. // MarshalJSON marshals this Identity in its string format (private key is never included)
  223. func (id *Identity) MarshalJSON() ([]byte, error) {
  224. return []byte("\"" + id.String() + "\""), nil
  225. }
  226. // UnmarshalJSON unmarshals this Identity from a string
  227. func (id *Identity) UnmarshalJSON(j []byte) error {
  228. var s string
  229. err := json.Unmarshal(j, &s)
  230. if err != nil {
  231. return err
  232. }
  233. nid, err := NewIdentityFromString(s)
  234. if err != nil {
  235. return err
  236. }
  237. *id = *nid
  238. return nil
  239. }