strkey.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright 2018-2023 The NATS Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package nkeys
  14. import (
  15. "bytes"
  16. "encoding/base32"
  17. "encoding/binary"
  18. )
  19. // PrefixByte is a lead byte representing the type.
  20. type PrefixByte byte
  21. const (
  22. // PrefixByteSeed is the version byte used for encoded NATS Seeds
  23. PrefixByteSeed PrefixByte = 18 << 3 // Base32-encodes to 'S...'
  24. // PrefixBytePrivate is the version byte used for encoded NATS Private keys
  25. PrefixBytePrivate PrefixByte = 15 << 3 // Base32-encodes to 'P...'
  26. // PrefixByteServer is the version byte used for encoded NATS Servers
  27. PrefixByteServer PrefixByte = 13 << 3 // Base32-encodes to 'N...'
  28. // PrefixByteCluster is the version byte used for encoded NATS Clusters
  29. PrefixByteCluster PrefixByte = 2 << 3 // Base32-encodes to 'C...'
  30. // PrefixByteOperator is the version byte used for encoded NATS Operators
  31. PrefixByteOperator PrefixByte = 14 << 3 // Base32-encodes to 'O...'
  32. // PrefixByteAccount is the version byte used for encoded NATS Accounts
  33. PrefixByteAccount PrefixByte = 0 // Base32-encodes to 'A...'
  34. // PrefixByteUser is the version byte used for encoded NATS Users
  35. PrefixByteUser PrefixByte = 20 << 3 // Base32-encodes to 'U...'
  36. // PrefixByteCurve is the version byte used for encoded CurveKeys (X25519)
  37. PrefixByteCurve PrefixByte = 23 << 3 // Base32-encodes to 'X...'
  38. // PrefixByteUnknown is for unknown prefixes.
  39. PrefixByteUnknown PrefixByte = 25 << 3 // Base32-encodes to 'Z...'
  40. )
  41. // Set our encoding to not include padding '=='
  42. var b32Enc = base32.StdEncoding.WithPadding(base32.NoPadding)
  43. // Encode will encode a raw key or seed with the prefix and crc16 and then base32 encoded.
  44. func Encode(prefix PrefixByte, src []byte) ([]byte, error) {
  45. if err := checkValidPrefixByte(prefix); err != nil {
  46. return nil, err
  47. }
  48. var raw bytes.Buffer
  49. // write prefix byte
  50. if err := raw.WriteByte(byte(prefix)); err != nil {
  51. return nil, err
  52. }
  53. // write payload
  54. if _, err := raw.Write(src); err != nil {
  55. return nil, err
  56. }
  57. // Calculate and write crc16 checksum
  58. err := binary.Write(&raw, binary.LittleEndian, crc16(raw.Bytes()))
  59. if err != nil {
  60. return nil, err
  61. }
  62. data := raw.Bytes()
  63. buf := make([]byte, b32Enc.EncodedLen(len(data)))
  64. b32Enc.Encode(buf, data)
  65. return buf[:], nil
  66. }
  67. // EncodeSeed will encode a raw key with the prefix and then seed prefix and crc16 and then base32 encoded.
  68. // `src` must be 32 bytes long (ed25519.SeedSize).
  69. func EncodeSeed(public PrefixByte, src []byte) ([]byte, error) {
  70. if err := checkValidPublicPrefixByte(public); err != nil {
  71. return nil, err
  72. }
  73. if len(src) != seedLen {
  74. return nil, ErrInvalidSeedLen
  75. }
  76. // In order to make this human printable for both bytes, we need to do a little
  77. // bit manipulation to setup for base32 encoding which takes 5 bits at a time.
  78. b1 := byte(PrefixByteSeed) | (byte(public) >> 5)
  79. b2 := (byte(public) & 31) << 3 // 31 = 00011111
  80. var raw bytes.Buffer
  81. raw.WriteByte(b1)
  82. raw.WriteByte(b2)
  83. // write payload
  84. if _, err := raw.Write(src); err != nil {
  85. return nil, err
  86. }
  87. // Calculate and write crc16 checksum
  88. err := binary.Write(&raw, binary.LittleEndian, crc16(raw.Bytes()))
  89. if err != nil {
  90. return nil, err
  91. }
  92. data := raw.Bytes()
  93. buf := make([]byte, b32Enc.EncodedLen(len(data)))
  94. b32Enc.Encode(buf, data)
  95. return buf, nil
  96. }
  97. // IsValidEncoding will tell you if the encoding is a valid key.
  98. func IsValidEncoding(src []byte) bool {
  99. _, err := decode(src)
  100. return err == nil
  101. }
  102. // decode will decode the base32 and check crc16 and the prefix for validity.
  103. func decode(src []byte) ([]byte, error) {
  104. raw := make([]byte, b32Enc.DecodedLen(len(src)))
  105. n, err := b32Enc.Decode(raw, src)
  106. if err != nil {
  107. return nil, err
  108. }
  109. raw = raw[:n]
  110. if n < 4 {
  111. return nil, ErrInvalidEncoding
  112. }
  113. crc := binary.LittleEndian.Uint16(raw[n-2:])
  114. // ensure checksum is valid
  115. if err := validate(raw[0:n-2], crc); err != nil {
  116. return nil, err
  117. }
  118. return raw[:n-2], nil
  119. }
  120. // Decode will decode the base32 string and check crc16 and enforce the prefix is what is expected.
  121. func Decode(expectedPrefix PrefixByte, src []byte) ([]byte, error) {
  122. if err := checkValidPrefixByte(expectedPrefix); err != nil {
  123. return nil, err
  124. }
  125. raw, err := decode(src)
  126. if err != nil {
  127. return nil, err
  128. }
  129. b1 := raw[0] & 248 // 248 = 11111000
  130. if prefix := PrefixByte(b1); prefix != expectedPrefix {
  131. return nil, ErrInvalidPrefixByte
  132. }
  133. return raw[1:], nil
  134. }
  135. // DecodeSeed will decode the base32 string and check crc16 and enforce the prefix is a seed
  136. // and the subsequent type is a valid type.
  137. func DecodeSeed(src []byte) (PrefixByte, []byte, error) {
  138. raw, err := decode(src)
  139. if err != nil {
  140. return PrefixByteSeed, nil, err
  141. }
  142. // Need to do the reverse here to get back to internal representation.
  143. b1 := raw[0] & 248 // 248 = 11111000
  144. b2 := (raw[0]&7)<<5 | ((raw[1] & 248) >> 3) // 7 = 00000111
  145. if PrefixByte(b1) != PrefixByteSeed {
  146. return PrefixByteSeed, nil, ErrInvalidSeed
  147. }
  148. if checkValidPublicPrefixByte(PrefixByte(b2)) != nil {
  149. return PrefixByteSeed, nil, ErrInvalidSeed
  150. }
  151. return PrefixByte(b2), raw[2:], nil
  152. }
  153. // Prefix returns PrefixBytes of its input
  154. func Prefix(src string) PrefixByte {
  155. b, err := decode([]byte(src))
  156. if err != nil {
  157. return PrefixByteUnknown
  158. }
  159. prefix := PrefixByte(b[0])
  160. err = checkValidPrefixByte(prefix)
  161. if err == nil {
  162. return prefix
  163. }
  164. // Might be a seed.
  165. b1 := b[0] & 248
  166. if PrefixByte(b1) == PrefixByteSeed {
  167. return PrefixByteSeed
  168. }
  169. return PrefixByteUnknown
  170. }
  171. // IsValidPublicKey will decode and verify that the string is a valid encoded public key.
  172. func IsValidPublicKey(src string) bool {
  173. b, err := decode([]byte(src))
  174. if err != nil {
  175. return false
  176. }
  177. if prefix := PrefixByte(b[0]); checkValidPublicPrefixByte(prefix) != nil {
  178. return false
  179. }
  180. return true
  181. }
  182. // IsValidPublicUserKey will decode and verify the string is a valid encoded Public User Key.
  183. func IsValidPublicUserKey(src string) bool {
  184. _, err := Decode(PrefixByteUser, []byte(src))
  185. return err == nil
  186. }
  187. // IsValidPublicAccountKey will decode and verify the string is a valid encoded Public Account Key.
  188. func IsValidPublicAccountKey(src string) bool {
  189. _, err := Decode(PrefixByteAccount, []byte(src))
  190. return err == nil
  191. }
  192. // IsValidPublicServerKey will decode and verify the string is a valid encoded Public Server Key.
  193. func IsValidPublicServerKey(src string) bool {
  194. _, err := Decode(PrefixByteServer, []byte(src))
  195. return err == nil
  196. }
  197. // IsValidPublicClusterKey will decode and verify the string is a valid encoded Public Cluster Key.
  198. func IsValidPublicClusterKey(src string) bool {
  199. _, err := Decode(PrefixByteCluster, []byte(src))
  200. return err == nil
  201. }
  202. // IsValidPublicOperatorKey will decode and verify the string is a valid encoded Public Operator Key.
  203. func IsValidPublicOperatorKey(src string) bool {
  204. _, err := Decode(PrefixByteOperator, []byte(src))
  205. return err == nil
  206. }
  207. // IsValidPublicCurveKey will decode and verify the string is a valid encoded Public Curve Key.
  208. func IsValidPublicCurveKey(src string) bool {
  209. _, err := Decode(PrefixByteCurve, []byte(src))
  210. return err == nil
  211. }
  212. // checkValidPrefixByte returns an error if the provided value
  213. // is not one of the defined valid prefix byte constants.
  214. func checkValidPrefixByte(prefix PrefixByte) error {
  215. switch prefix {
  216. case PrefixByteOperator, PrefixByteServer, PrefixByteCluster,
  217. PrefixByteAccount, PrefixByteUser, PrefixByteSeed, PrefixBytePrivate, PrefixByteCurve:
  218. return nil
  219. }
  220. return ErrInvalidPrefixByte
  221. }
  222. // checkValidPublicPrefixByte returns an error if the provided value
  223. // is not one of the public defined valid prefix byte constants.
  224. func checkValidPublicPrefixByte(prefix PrefixByte) error {
  225. switch prefix {
  226. case PrefixByteOperator, PrefixByteServer, PrefixByteCluster, PrefixByteAccount, PrefixByteUser, PrefixByteCurve:
  227. return nil
  228. }
  229. return ErrInvalidPrefixByte
  230. }
  231. func (p PrefixByte) String() string {
  232. switch p {
  233. case PrefixByteOperator:
  234. return "operator"
  235. case PrefixByteServer:
  236. return "server"
  237. case PrefixByteCluster:
  238. return "cluster"
  239. case PrefixByteAccount:
  240. return "account"
  241. case PrefixByteUser:
  242. return "user"
  243. case PrefixByteSeed:
  244. return "seed"
  245. case PrefixBytePrivate:
  246. return "private"
  247. case PrefixByteCurve:
  248. return "x25519"
  249. }
  250. return "unknown"
  251. }
  252. // CompatibleKeyPair returns an error if the KeyPair doesn't match expected PrefixByte(s)
  253. func CompatibleKeyPair(kp KeyPair, expected ...PrefixByte) error {
  254. pk, err := kp.PublicKey()
  255. if err != nil {
  256. return err
  257. }
  258. pkType := Prefix(pk)
  259. for _, k := range expected {
  260. if pkType == k {
  261. return nil
  262. }
  263. }
  264. return ErrIncompatibleKey
  265. }