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