A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

70 lines
1.5 KiB

  1. /*
  2. * Copyright © 2019, 2021 Musing Studio LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. // Package key holds application keys and utilities around generating them.
  11. package key
  12. import (
  13. "crypto/rand"
  14. )
  15. const (
  16. EncKeysBytes = 32
  17. )
  18. type Keychain struct {
  19. EmailKey, CookieAuthKey, CookieKey, CSRFKey []byte
  20. }
  21. // GenerateKeys generates necessary keys for the app on the given Keychain,
  22. // skipping any that already exist.
  23. func (keys *Keychain) GenerateKeys() error {
  24. // Generate keys only if they don't already exist
  25. // TODO: use something like https://github.com/hashicorp/go-multierror to return errors
  26. var err, keyErrs error
  27. if len(keys.EmailKey) == 0 {
  28. keys.EmailKey, err = GenerateBytes(EncKeysBytes)
  29. if err != nil {
  30. keyErrs = err
  31. }
  32. }
  33. if len(keys.CookieAuthKey) == 0 {
  34. keys.CookieAuthKey, err = GenerateBytes(EncKeysBytes)
  35. if err != nil {
  36. keyErrs = err
  37. }
  38. }
  39. if len(keys.CookieKey) == 0 {
  40. keys.CookieKey, err = GenerateBytes(EncKeysBytes)
  41. if err != nil {
  42. keyErrs = err
  43. }
  44. }
  45. if len(keys.CSRFKey) == 0 {
  46. keys.CSRFKey, err = GenerateBytes(EncKeysBytes)
  47. if err != nil {
  48. keyErrs = err
  49. }
  50. }
  51. return keyErrs
  52. }
  53. // GenerateBytes returns securely generated random bytes.
  54. func GenerateBytes(n int) ([]byte, error) {
  55. b := make([]byte, n)
  56. _, err := rand.Read(b)
  57. if err != nil {
  58. return nil, err
  59. }
  60. return b, nil
  61. }