strkey.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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. PrefixByteUnknown 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.DecodedLen(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. // Prefix returns PrefixBytes of its input
  155. func Prefix(src string) PrefixByte {
  156. b, err := decode([]byte(src))
  157. if err != nil {
  158. return PrefixByteUnknown
  159. }
  160. prefix := PrefixByte(b[0])
  161. err = checkValidPrefixByte(prefix)
  162. if err == nil {
  163. return prefix
  164. }
  165. // Might be a seed.
  166. b1 := b[0] & 248
  167. if PrefixByte(b1) == PrefixByteSeed {
  168. return PrefixByteSeed
  169. }
  170. return PrefixByteUnknown
  171. }
  172. // IsValidPublicKey will decode and verify that the string is a valid encoded public key.
  173. func IsValidPublicKey(src string) bool {
  174. b, err := decode([]byte(src))
  175. if err != nil {
  176. return false
  177. }
  178. if prefix := PrefixByte(b[0]); checkValidPublicPrefixByte(prefix) != nil {
  179. return false
  180. }
  181. return true
  182. }
  183. // IsValidPublicUserKey will decode and verify the string is a valid encoded Public User Key.
  184. func IsValidPublicUserKey(src string) bool {
  185. _, err := Decode(PrefixByteUser, []byte(src))
  186. return err == nil
  187. }
  188. // IsValidPublicAccountKey will decode and verify the string is a valid encoded Public Account Key.
  189. func IsValidPublicAccountKey(src string) bool {
  190. _, err := Decode(PrefixByteAccount, []byte(src))
  191. return err == nil
  192. }
  193. // IsValidPublicServerKey will decode and verify the string is a valid encoded Public Server Key.
  194. func IsValidPublicServerKey(src string) bool {
  195. _, err := Decode(PrefixByteServer, []byte(src))
  196. return err == nil
  197. }
  198. // IsValidPublicClusterKey will decode and verify the string is a valid encoded Public Cluster Key.
  199. func IsValidPublicClusterKey(src string) bool {
  200. _, err := Decode(PrefixByteCluster, []byte(src))
  201. return err == nil
  202. }
  203. // IsValidPublicOperatorKey will decode and verify the string is a valid encoded Public Operator Key.
  204. func IsValidPublicOperatorKey(src string) bool {
  205. _, err := Decode(PrefixByteOperator, []byte(src))
  206. return err == nil
  207. }
  208. // checkValidPrefixByte returns an error if the provided value
  209. // is not one of the defined valid prefix byte constants.
  210. func checkValidPrefixByte(prefix PrefixByte) error {
  211. switch prefix {
  212. case PrefixByteOperator, PrefixByteServer, PrefixByteCluster,
  213. PrefixByteAccount, PrefixByteUser, PrefixByteSeed, PrefixBytePrivate:
  214. return nil
  215. }
  216. return ErrInvalidPrefixByte
  217. }
  218. // checkValidPublicPrefixByte returns an error if the provided value
  219. // is not one of the public defined valid prefix byte constants.
  220. func checkValidPublicPrefixByte(prefix PrefixByte) error {
  221. switch prefix {
  222. case PrefixByteServer, PrefixByteCluster, PrefixByteOperator, PrefixByteAccount, PrefixByteUser:
  223. return nil
  224. }
  225. return ErrInvalidPrefixByte
  226. }
  227. func (p PrefixByte) String() string {
  228. switch p {
  229. case PrefixByteOperator:
  230. return "operator"
  231. case PrefixByteServer:
  232. return "server"
  233. case PrefixByteCluster:
  234. return "cluster"
  235. case PrefixByteAccount:
  236. return "account"
  237. case PrefixByteUser:
  238. return "user"
  239. case PrefixByteSeed:
  240. return "seed"
  241. case PrefixBytePrivate:
  242. return "private"
  243. }
  244. return "unknown"
  245. }
  246. // CompatibleKeyPair returns an error if the KeyPair doesn't match expected PrefixByte(s)
  247. func CompatibleKeyPair(kp KeyPair, expected ...PrefixByte) error {
  248. pk, err := kp.PublicKey()
  249. if err != nil {
  250. return err
  251. }
  252. pkType := Prefix(pk)
  253. for _, k := range expected {
  254. if pkType == k {
  255. return nil
  256. }
  257. }
  258. return ErrIncompatibleKey
  259. }