account.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package libcobalt
  2. import (
  3. "encoding/base64"
  4. "errors"
  5. "strings"
  6. "notabug.org/apiote/gott"
  7. )
  8. const (
  9. KEY_SIGN int = 1 << iota
  10. KEY_ENCRYPT int = 1 << iota
  11. )
  12. func selectKey(keys []KeyPair, kind int) (KeyPair, error) {
  13. // todo some priority
  14. for _, key := range keys {
  15. if key.kind&kind > 0 {
  16. return key, nil
  17. }
  18. }
  19. return KeyPair{}, errors.New("No such error found")
  20. }
  21. type KeyPair struct {
  22. id string
  23. private string
  24. public string
  25. fingerprint string
  26. kind int
  27. password string
  28. }
  29. type Address struct {
  30. id string
  31. domainID string
  32. email string
  33. send bool
  34. receive bool
  35. order int
  36. displayName string
  37. signature string
  38. keys []KeyPair
  39. }
  40. func (a *Account) SelectAddress(email string) {
  41. for _, addr := range a.addresses {
  42. if strings.ToLower(addr.email) == strings.ToLower(email) {
  43. a.selectedAddress = &addr
  44. }
  45. }
  46. }
  47. // Account is a structure that holds data about ProtonMail account
  48. type Account struct {
  49. username string
  50. password string
  51. twoFactor string
  52. authToken string
  53. refreshToken string
  54. authInfo authInfo
  55. uid string
  56. keyPassword string
  57. addresses []Address
  58. selectedAddress *Address
  59. seccondPasswordEnabled bool
  60. }
  61. func moveSalts(values ...interface{}) interface{} {
  62. values[2] = values[0].(saltsResponse).KeySalts
  63. return gott.Tuple(values)
  64. }
  65. func convertAddresses(values ...interface{}) interface{} {
  66. rawAddresses := values[0].(addressesResponse).Addresses
  67. addresses := []Address{}
  68. for _, addr := range rawAddresses {
  69. address := Address{
  70. id: addr.ID,
  71. domainID: addr.DomainID,
  72. email: addr.Email,
  73. send: addr.Send == 1,
  74. receive: addr.Receive == 1,
  75. order: addr.Order,
  76. displayName: addr.DisplayName,
  77. signature: addr.Signature,
  78. }
  79. keys := []KeyPair{}
  80. for _, k := range addr.Keys {
  81. key := KeyPair{
  82. id: k.ID,
  83. private: k.PrivateKey,
  84. public: k.PublicKey,
  85. fingerprint: k.Fingerprint,
  86. kind: k.Flags,
  87. }
  88. keys = append(keys, key)
  89. }
  90. address.keys = keys
  91. addresses = append(addresses, address)
  92. }
  93. values[0] = addresses
  94. return gott.Tuple(values)
  95. }
  96. func decodeKeySalt(values ...interface{}) (interface{}, error) {
  97. hash, err := base64.StdEncoding.DecodeString(values[1].(string))
  98. values[1] = hash
  99. return gott.Tuple(values), err
  100. }
  101. func computePrivateKeyPassword(password, salt string, keyPair KeyPair) (interface{}, error) {
  102. r, err := gott.NewResult(gott.Tuple{password, salt, nil, nil}).
  103. Bind(decodeKeySalt).
  104. Bind(bcrypt).
  105. Map(replaceBcryptVersion).
  106. Finish()
  107. if err == nil {
  108. keyPair.password = string(r.(gott.Tuple)[3].([]byte)[29:])
  109. }
  110. return keyPair, err
  111. }
  112. func computeKeysPasswords(values ...interface{}) (interface{}, error) {
  113. addresses := values[0].([]Address)
  114. account := values[1].(Account)
  115. salts := values[2].([]keySalt)
  116. for i, addr := range addresses {
  117. for j, pair := range addr.keys {
  118. var selectedSalt string
  119. for _, salt := range salts {
  120. if salt.ID == pair.id {
  121. selectedSalt = salt.KeySalt
  122. }
  123. }
  124. keyPair, err := computePrivateKeyPassword(account.keyPassword, selectedSalt, pair)
  125. if err != nil {
  126. return gott.Tuple(values), err
  127. }
  128. addresses[i].keys[j] = keyPair.(KeyPair)
  129. }
  130. }
  131. return addresses, nil
  132. }
  133. func (a *Account) GetAddresses() error {
  134. t := gott.Tuple{nil, *a, nil}
  135. r, err := gott.NewResult(t).
  136. Bind(prepareSaltsRequest).
  137. Map(setHeadersAuthed).
  138. Bind(doRequest).
  139. Bind(checkResponse).
  140. Bind(readResponse).
  141. Bind(unmarshalSaltsResponse).
  142. Map(moveSalts).
  143. Bind(prepareAddressesRequest).
  144. Map(setHeadersAuthed).
  145. Bind(doRequest).
  146. Bind(checkResponse).
  147. Bind(readResponse).
  148. Bind(unmarshalAddressesResponse).
  149. Map(convertAddresses).
  150. Bind(computeKeysPasswords).
  151. Finish()
  152. if err == nil {
  153. a.addresses = r.([]Address)
  154. }
  155. return err
  156. }