strkey.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Copyright 2018 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. "golang.org/x/crypto/ed25519"
  19. )
  20. // PrefixByte is a lead byte representing the type.
  21. type PrefixByte byte
  22. const (
  23. // PrefixByteSeed is the version byte used for encoded NATS Seeds
  24. PrefixByteSeed PrefixByte = 18 << 3 // Base32-encodes to 'S...'
  25. // PrefixBytePrivate is the version byte used for encoded NATS Private keys
  26. PrefixBytePrivate PrefixByte = 15 << 3 // Base32-encodes to 'P...'
  27. // PrefixByteServer is the version byte used for encoded NATS Servers
  28. PrefixByteServer PrefixByte = 13 << 3 // Base32-encodes to 'N...'
  29. // PrefixByteCluster is the version byte used for encoded NATS Clusters
  30. PrefixByteCluster PrefixByte = 2 << 3 // Base32-encodes to 'C...'
  31. // PrefixByteOperator is the version byte used for encoded NATS Operators
  32. PrefixByteOperator PrefixByte = 14 << 3 // Base32-encodes to 'O...'
  33. // PrefixByteAccount is the version byte used for encoded NATS Accounts
  34. PrefixByteAccount PrefixByte = 0 // Base32-encodes to 'A...'
  35. // PrefixByteUser is the version byte used for encoded NATS Users
  36. PrefixByteUser PrefixByte = 20 << 3 // Base32-encodes to 'U...'
  37. // PrefixByteUnknown is for unknown prefixes.
  38. PrefixByteUknown PrefixByte = 23 << 3 // Base32-encodes to 'X...'
  39. )
  40. // Set our encoding to not include padding '=='
  41. var b32Enc = base32.StdEncoding.WithPadding(base32.NoPadding)
  42. // Encode will encode a raw key or seed with the prefix and crc16 and then base32 encoded.
  43. func Encode(prefix PrefixByte, src []byte) ([]byte, error) {
  44. if err := checkValidPrefixByte(prefix); err != nil {
  45. return nil, err
  46. }
  47. var raw bytes.Buffer
  48. // write prefix byte
  49. if err := raw.WriteByte(byte(prefix)); err != nil {
  50. return nil, err
  51. }
  52. // write payload
  53. if _, err := raw.Write(src); err != nil {
  54. return nil, err
  55. }
  56. // Calculate and write crc16 checksum
  57. err := binary.Write(&raw, binary.LittleEndian, crc16(raw.Bytes()))
  58. if err != nil {
  59. return nil, err
  60. }
  61. data := raw.Bytes()
  62. buf := make([]byte, b32Enc.EncodedLen(len(data)))
  63. b32Enc.Encode(buf, data)
  64. return buf[:], nil
  65. }
  66. // EncodeSeed will encode a raw key with the prefix and then seed prefix and crc16 and then base32 encoded.
  67. func EncodeSeed(public PrefixByte, src []byte) ([]byte, error) {
  68. if err := checkValidPublicPrefixByte(public); err != nil {
  69. return nil, err
  70. }
  71. if len(src) != ed25519.SeedSize {
  72. return nil, ErrInvalidSeedLen
  73. }
  74. // In order to make this human printable for both bytes, we need to do a little
  75. // bit manipulation to setup for base32 encoding which takes 5 bits at a time.
  76. b1 := byte(PrefixByteSeed) | (byte(public) >> 5)
  77. b2 := (byte(public) & 31) << 3 // 31 = 00011111
  78. var raw bytes.Buffer
  79. raw.WriteByte(b1)
  80. raw.WriteByte(b2)
  81. // write payload
  82. if _, err := raw.Write(src); err != nil {
  83. return nil, err
  84. }
  85. // Calculate and write crc16 checksum
  86. err := binary.Write(&raw, binary.LittleEndian, crc16(raw.Bytes()))
  87. if err != nil {
  88. return nil, err
  89. }
  90. data := raw.Bytes()
  91. buf := make([]byte, b32Enc.EncodedLen(len(data)))
  92. b32Enc.Encode(buf, data)
  93. return buf, nil
  94. }
  95. // IsValidEncoding will tell you if the encoding is a valid key.
  96. func IsValidEncoding(src []byte) bool {
  97. _, err := decode(src)
  98. return err == nil
  99. }
  100. // decode will decode the base32 and check crc16 and the prefix for validity.
  101. func decode(src []byte) ([]byte, error) {
  102. raw := make([]byte, b32Enc.EncodedLen(len(src)))
  103. n, err := b32Enc.Decode(raw, src)
  104. if err != nil {
  105. return nil, err
  106. }
  107. raw = raw[:n]
  108. if len(raw) < 4 {
  109. return nil, ErrInvalidEncoding
  110. }
  111. var crc uint16
  112. checksum := bytes.NewReader(raw[len(raw)-2:])
  113. if err := binary.Read(checksum, binary.LittleEndian, &crc); err != nil {
  114. return nil, err
  115. }
  116. // ensure checksum is valid
  117. if err := validate(raw[0:len(raw)-2], crc); err != nil {
  118. return nil, err
  119. }
  120. return raw[:len(raw)-2], nil
  121. }
  122. // Decode will decode the base32 string and check crc16 and enforce the prefix is what is expected.
  123. func Decode(expectedPrefix PrefixByte, src []byte) ([]byte, error) {
  124. if err := checkValidPrefixByte(expectedPrefix); err != nil {
  125. return nil, err
  126. }
  127. raw, err := decode(src)
  128. if err != nil {
  129. return nil, err
  130. }
  131. if prefix := PrefixByte(raw[0]); prefix != expectedPrefix {
  132. return nil, ErrInvalidPrefixByte
  133. }
  134. return raw[1:], nil
  135. }
  136. // DecodeSeed will decode the base32 string and check crc16 and enforce the prefix is a seed
  137. // and the subsequent type is a valid type.
  138. func DecodeSeed(src []byte) (PrefixByte, []byte, error) {
  139. raw, err := decode(src)
  140. if err != nil {
  141. return PrefixByteSeed, nil, err
  142. }
  143. // Need to do the reverse here to get back to internal representation.
  144. b1 := raw[0] & 248 // 248 = 11111000
  145. b2 := (raw[0]&7)<<5 | ((raw[1] & 248) >> 3) // 7 = 00000111
  146. if PrefixByte(b1) != PrefixByteSeed {
  147. return PrefixByteSeed, nil, ErrInvalidSeed
  148. }
  149. if checkValidPublicPrefixByte(PrefixByte(b2)) != nil {
  150. return PrefixByteSeed, nil, ErrInvalidSeed
  151. }
  152. return PrefixByte(b2), raw[2:], nil
  153. }
  154. func Prefix(src string) PrefixByte {
  155. b, err := decode([]byte(src))
  156. if err != nil {
  157. return PrefixByteUknown
  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 PrefixByteUknown
  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. // checkValidPrefixByte returns an error if the provided value
  208. // is not one of the defined valid prefix byte constants.
  209. func checkValidPrefixByte(prefix PrefixByte) error {
  210. switch prefix {
  211. case PrefixByteOperator, PrefixByteServer, PrefixByteCluster,
  212. PrefixByteAccount, PrefixByteUser, PrefixByteSeed, PrefixBytePrivate:
  213. return nil
  214. }
  215. return ErrInvalidPrefixByte
  216. }
  217. // checkValidPublicPrefixByte returns an error if the provided value
  218. // is not one of the public defined valid prefix byte constants.
  219. func checkValidPublicPrefixByte(prefix PrefixByte) error {
  220. switch prefix {
  221. case PrefixByteServer, PrefixByteCluster, PrefixByteOperator, PrefixByteAccount, PrefixByteUser:
  222. return nil
  223. }
  224. return ErrInvalidPrefixByte
  225. }
  226. func (p PrefixByte) String() string {
  227. switch p {
  228. case PrefixByteOperator:
  229. return "operator"
  230. case PrefixByteServer:
  231. return "server"
  232. case PrefixByteCluster:
  233. return "cluster"
  234. case PrefixByteAccount:
  235. return "account"
  236. case PrefixByteUser:
  237. return "user"
  238. case PrefixByteSeed:
  239. return "seed"
  240. case PrefixBytePrivate:
  241. return "private"
  242. }
  243. return "unknown"
  244. }