Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

parse.go 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright 2018 by David A. Golden. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. package scram
  7. import (
  8. "encoding/base64"
  9. "errors"
  10. "fmt"
  11. "strconv"
  12. "strings"
  13. )
  14. type c1Msg struct {
  15. gs2Header string
  16. authzID string
  17. username string
  18. nonce string
  19. c1b string
  20. }
  21. type c2Msg struct {
  22. cbind []byte
  23. nonce string
  24. proof []byte
  25. c2wop string
  26. }
  27. type s1Msg struct {
  28. nonce string
  29. salt []byte
  30. iters int
  31. }
  32. type s2Msg struct {
  33. verifier []byte
  34. err string
  35. }
  36. func parseField(s, k string) (string, error) {
  37. t := strings.TrimPrefix(s, k+"=")
  38. if t == s {
  39. return "", fmt.Errorf("error parsing '%s' for field '%s'", s, k)
  40. }
  41. return t, nil
  42. }
  43. func parseGS2Flag(s string) (string, error) {
  44. if s[0] == 'p' {
  45. return "", fmt.Errorf("channel binding requested but not supported")
  46. }
  47. if s == "n" || s == "y" {
  48. return s, nil
  49. }
  50. return "", fmt.Errorf("error parsing '%s' for gs2 flag", s)
  51. }
  52. func parseFieldBase64(s, k string) ([]byte, error) {
  53. raw, err := parseField(s, k)
  54. if err != nil {
  55. return nil, err
  56. }
  57. dec, err := base64.StdEncoding.DecodeString(raw)
  58. if err != nil {
  59. return nil, err
  60. }
  61. return dec, nil
  62. }
  63. func parseFieldInt(s, k string) (int, error) {
  64. raw, err := parseField(s, k)
  65. if err != nil {
  66. return 0, err
  67. }
  68. num, err := strconv.Atoi(raw)
  69. if err != nil {
  70. return 0, fmt.Errorf("error parsing field '%s': %v", k, err)
  71. }
  72. return num, nil
  73. }
  74. func parseClientFirst(c1 string) (msg c1Msg, err error) {
  75. fields := strings.Split(c1, ",")
  76. if len(fields) < 4 {
  77. err = errors.New("not enough fields in first server message")
  78. return
  79. }
  80. gs2flag, err := parseGS2Flag(fields[0])
  81. if err != nil {
  82. return
  83. }
  84. // 'a' field is optional
  85. if len(fields[1]) > 0 {
  86. msg.authzID, err = parseField(fields[1], "a")
  87. if err != nil {
  88. return
  89. }
  90. }
  91. // Recombine and save the gs2 header
  92. msg.gs2Header = gs2flag + "," + msg.authzID + ","
  93. // Check for unsupported extensions field "m".
  94. if strings.HasPrefix(fields[2], "m=") {
  95. err = errors.New("SCRAM message extensions are not supported")
  96. return
  97. }
  98. msg.username, err = parseField(fields[2], "n")
  99. if err != nil {
  100. return
  101. }
  102. msg.nonce, err = parseField(fields[3], "r")
  103. if err != nil {
  104. return
  105. }
  106. msg.c1b = strings.Join(fields[2:], ",")
  107. return
  108. }
  109. func parseClientFinal(c2 string) (msg c2Msg, err error) {
  110. fields := strings.Split(c2, ",")
  111. if len(fields) < 3 {
  112. err = errors.New("not enough fields in first server message")
  113. return
  114. }
  115. msg.cbind, err = parseFieldBase64(fields[0], "c")
  116. if err != nil {
  117. return
  118. }
  119. msg.nonce, err = parseField(fields[1], "r")
  120. if err != nil {
  121. return
  122. }
  123. // Extension fields may come between nonce and proof, so we
  124. // grab the *last* fields as proof.
  125. msg.proof, err = parseFieldBase64(fields[len(fields)-1], "p")
  126. if err != nil {
  127. return
  128. }
  129. msg.c2wop = c2[:strings.LastIndex(c2, ",")]
  130. return
  131. }
  132. func parseServerFirst(s1 string) (msg s1Msg, err error) {
  133. // Check for unsupported extensions field "m".
  134. if strings.HasPrefix(s1, "m=") {
  135. err = errors.New("SCRAM message extensions are not supported")
  136. return
  137. }
  138. fields := strings.Split(s1, ",")
  139. if len(fields) < 3 {
  140. err = errors.New("not enough fields in first server message")
  141. return
  142. }
  143. msg.nonce, err = parseField(fields[0], "r")
  144. if err != nil {
  145. return
  146. }
  147. msg.salt, err = parseFieldBase64(fields[1], "s")
  148. if err != nil {
  149. return
  150. }
  151. msg.iters, err = parseFieldInt(fields[2], "i")
  152. return
  153. }
  154. func parseServerFinal(s2 string) (msg s2Msg, err error) {
  155. fields := strings.Split(s2, ",")
  156. msg.verifier, err = parseFieldBase64(fields[0], "v")
  157. if err == nil {
  158. return
  159. }
  160. msg.err, err = parseField(fields[0], "e")
  161. return
  162. }