nonce.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Public Domain Software
  3. *
  4. * I (Matthias Ladkau) am the author of the source code in this file.
  5. * I have placed the source code in this file in the public domain.
  6. *
  7. * For further information see: http://creativecommons.org/publicdomain/zero/1.0/
  8. */
  9. package datautil
  10. import (
  11. "crypto/sha256"
  12. "errors"
  13. "fmt"
  14. "devt.de/krotik/common/cryptutil"
  15. "devt.de/krotik/common/timeutil"
  16. )
  17. /*
  18. MaxNonceLifetime is the maximum lifetime for nonces in seconds.
  19. */
  20. var MaxNonceLifetime int64 = 3600 // One hour
  21. /*
  22. Default nonce related errors
  23. */
  24. var (
  25. ErrInvlaidNonce = errors.New("Invalid nonce value")
  26. )
  27. /*
  28. nonces is an internal map which holds all valid nonces
  29. */
  30. var nonces *MapCache
  31. /*
  32. NewNonce generates a new nonce value. The nonce is invalidated either
  33. after it was consumed or automatically after MaxNonceLifetime seconds.
  34. */
  35. func NewNonce() string {
  36. if nonces == nil {
  37. // Create nonce cache if it doesn't exist yet
  38. nonces = NewMapCache(0, MaxNonceLifetime)
  39. }
  40. // Get a timestamp
  41. ts := timeutil.MakeTimestamp()
  42. // Calculate a hash based on a UUID
  43. uuid := cryptutil.GenerateUUID()
  44. secPart := sha256.Sum256(uuid[:])
  45. // Construct the actual nonce and save it
  46. ret := fmt.Sprintf("%x-%s", secPart, ts)
  47. nonces.Put(ret, nil)
  48. return ret
  49. }
  50. /*
  51. CheckNonce checks if a given nonce is valid. The nonce is still valid
  52. after this operation.
  53. */
  54. func CheckNonce(nonce string) error {
  55. // Check length
  56. if len(nonce) == 78 && nonces != nil {
  57. // Check if the nonce is still valid
  58. if _, ok := nonces.Get(nonce); ok {
  59. return nil
  60. }
  61. }
  62. return ErrInvlaidNonce
  63. }
  64. /*
  65. ConsumeNonce consumes a given nonce. The nonce will no longer be valid
  66. after this operation.
  67. */
  68. func ConsumeNonce(nonce string) error {
  69. err := CheckNonce(nonce)
  70. if err == nil {
  71. nonces.Remove(nonce)
  72. }
  73. return nil
  74. }