identity.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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,
  150. // or an empty string if no private key is set.
  151. func (id *Identity) PrivateKeyString() string {
  152. switch id.idtype {
  153. case IdentityTypeC25519:
  154. if len(id.publicKey) == IdentityTypeC25519PublicKeySize && len(id.privateKey) == IdentityTypeC25519PrivateKeySize {
  155. return fmt.Sprintf("%.10x:0:%x:%x", uint64(id.address), id.publicKey, id.privateKey)
  156. }
  157. case IdentityTypeP384:
  158. if len(id.publicKey) == IdentityTypeP384PublicKeySize && len(id.privateKey) == IdentityTypeP384PrivateKeySize {
  159. return fmt.Sprintf("%.10x:1:%s:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey), Base32StdLowerCase.EncodeToString(id.privateKey))
  160. }
  161. }
  162. return ""
  163. }
  164. // PublicKeyString returns the address and public key (identity.public contents).
  165. // An empty string is returned if this identity is invalid or not initialized.
  166. func (id *Identity) String() string {
  167. switch id.idtype {
  168. case IdentityTypeC25519:
  169. if len(id.publicKey) == IdentityTypeC25519PublicKeySize {
  170. return fmt.Sprintf("%.10x:0:%x", uint64(id.address), id.publicKey)
  171. }
  172. case IdentityTypeP384:
  173. if len(id.publicKey) == IdentityTypeP384PublicKeySize {
  174. return fmt.Sprintf("%.10x:1:%s", uint64(id.address), Base32StdLowerCase.EncodeToString(id.publicKey))
  175. }
  176. }
  177. return ""
  178. }
  179. // LocallyValidate performs local self-validation of this identity
  180. func (id *Identity) LocallyValidate() bool {
  181. if !id.initCIdentityPtr() {
  182. return false
  183. }
  184. return C.ZT_Identity_validate(id.cid) != 0
  185. }
  186. // Sign signs a message with this identity
  187. func (id *Identity) Sign(msg []byte) ([]byte, error) {
  188. if !id.initCIdentityPtr() {
  189. return nil, ErrInvalidKey
  190. }
  191. var dataP unsafe.Pointer
  192. if len(msg) > 0 {
  193. dataP = unsafe.Pointer(&msg[0])
  194. }
  195. var sig [96]byte
  196. sigLen := C.ZT_Identity_sign(id.cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), 96)
  197. if sigLen <= 0 {
  198. return nil, ErrInvalidKey
  199. }
  200. return sig[0:uint(sigLen)], nil
  201. }
  202. // Verify verifies a signature
  203. func (id *Identity) Verify(msg, sig []byte) bool {
  204. if len(sig) == 0 || !id.initCIdentityPtr() {
  205. return false
  206. }
  207. var dataP unsafe.Pointer
  208. if len(msg) > 0 {
  209. dataP = unsafe.Pointer(&msg[0])
  210. }
  211. return C.ZT_Identity_verify(id.cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), C.uint(len(sig))) != 0
  212. }
  213. // Equals performs a deep equality test between this and another identity
  214. func (id *Identity) Equals(id2 *Identity) bool {
  215. if id2 == nil {
  216. return id == nil
  217. }
  218. if id == nil {
  219. return false
  220. }
  221. return id.address == id2.address && id.idtype == id2.idtype && bytes.Equal(id.publicKey, id2.publicKey) && bytes.Equal(id.privateKey, id2.privateKey)
  222. }
  223. func (id *Identity) MarshalJSON() ([]byte, error) {
  224. return []byte("\"" + id.String() + "\""), nil
  225. }
  226. func (id *Identity) UnmarshalJSON(j []byte) error {
  227. var s string
  228. err := json.Unmarshal(j, &s)
  229. if err != nil {
  230. return err
  231. }
  232. nid, err := NewIdentityFromString(s)
  233. if err != nil {
  234. return err
  235. }
  236. *id = *nid
  237. return nil
  238. }