CryptoAuth.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef CryptoAuth_H
  16. #define CryptoAuth_H
  17. #include "benc/Object.h"
  18. #include "crypto/random/Random.h"
  19. #include "interface/Interface.h"
  20. #include "memory/Allocator.h"
  21. #include "util/Endian.h"
  22. #include "util/log/Log.h"
  23. #include "util/events/EventBase.h"
  24. #include "util/Linker.h"
  25. Linker_require("crypto/CryptoAuth.c")
  26. #include <stdint.h>
  27. #include <stdbool.h>
  28. #define CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS 60
  29. struct CryptoAuth
  30. {
  31. uint8_t publicKey[32];
  32. /**
  33. * After this number of seconds of inactivity,
  34. * a connection will be reset to prevent them hanging in a bad state.
  35. */
  36. uint32_t resetAfterInactivitySeconds;
  37. };
  38. /** The internal interface wrapper struct. */
  39. struct CryptoAuth_Wrapper;
  40. /**
  41. * Associate a password:authtype pair with a user object.
  42. * Calling CryptoAuth_getUser() on any interface which has established a connection with
  43. * the same password:authType pair will return the same user object.
  44. *
  45. * @param password This should be a key derived from the password using a good key derivation
  46. * function, using a plaintext password here is NOT recommended.
  47. * @param authType The method of authenticating the user, only option currently is 1 for sha256
  48. * based authentication.
  49. * @param user The thing to associate with this user, will be returned by CryptoAuth_getUser().
  50. * If this is NULL and requireAuthentication is enabled, authentication will fail.
  51. * Duplicate user entires are OK.
  52. * @param context The CryptoAuth context.
  53. * @return 0 if all goes well,
  54. * CryptoAuth_addUser_INVALID_AUTHTYPE if the authentication method is not supported,
  55. * CryptoAuth_addUser_OUT_OF_SPACE if there is not enough space to store the entry,
  56. * CryptoAuth_addUser_DUPLICATE if the same *password* already exists.
  57. */
  58. #define CryptoAuth_addUser_INVALID_AUTHTYPE -1
  59. #define CryptoAuth_addUser_OUT_OF_SPACE -2
  60. #define CryptoAuth_addUser_DUPLICATE -3
  61. int32_t CryptoAuth_addUser(String* password,
  62. uint8_t authType,
  63. String* user,
  64. struct CryptoAuth* context);
  65. /**
  66. * Remove all users registered with this CryptoAuth.
  67. *
  68. * @param context the context to remove users for.
  69. * @param user the identifier which was passed to addUser(), all users with this id will be removed.
  70. * @return the number of users removed.
  71. */
  72. int CryptoAuth_removeUsers(struct CryptoAuth* context, String* user);
  73. /**
  74. * Get a list of all the users added via addUser.
  75. *
  76. * @param context the context used to call addUser.
  77. * @param alloc the Allocator to use to create the usersOut array.
  78. * @returns List* containing the user String's
  79. */
  80. List* CryptoAuth_getUsers(struct CryptoAuth* context, struct Allocator* alloc);
  81. /**
  82. * Get the user object associated with the authenticated session or NULL if there is none.
  83. * Please make sure to only call this on interfaces which were actually returned by
  84. * CryptoAuth_wrapInterface() as strange and interesting bugs will result otherwise.
  85. *
  86. * @param interface an interface as returned by CryptoAuth_wrapInterface().
  87. * @return the user object added by calling CryptoAuth_addUser() or NULL if this session is not
  88. * authenticated.
  89. */
  90. String* CryptoAuth_getUser(struct Interface* iface);
  91. /**
  92. * Create a new crypto authenticator.
  93. *
  94. * @param allocator the means of aquiring memory.
  95. * @param privateKey the private key to use for this CryptoAuth or null if one should be generated.
  96. * @param eventBase the libevent context for handling timeouts.
  97. * @param logger the mechanism for logging output from the CryptoAuth.
  98. * if NULL then no logging will be done.
  99. * @param rand random number generator.
  100. * @return a new CryptoAuth context.
  101. */
  102. struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator,
  103. const uint8_t* privateKey,
  104. struct EventBase* eventBase,
  105. struct Log* logger,
  106. struct Random* rand);
  107. /**
  108. * Wrap an interface with crypto authentication.
  109. *
  110. * NOTE: Sending empty packets during the handshake is not allowed!
  111. * Empty packets are used for signaling during the handshake so they can
  112. * only be used while the session is in state ESTABLISHED.
  113. *
  114. * @param toWarp the interface to wrap
  115. * @param herPublicKey the public key of the other party or NULL if unknown.
  116. * @param herIp6 the ipv6 address of the other party
  117. * @param requireAuth if the remote end of this interface begins the connection, require
  118. * them to present valid authentication credentials to connect.
  119. * If this end begins the connection, this parameter has no effect.
  120. * @param name a name for this CA which will appear in logs.
  121. * @param context the CryptoAuth context.
  122. */
  123. struct Interface* CryptoAuth_wrapInterface(struct Interface* toWrap,
  124. const uint8_t herPublicKey[32],
  125. const uint8_t herIp6[16],
  126. const bool requireAuth,
  127. char* name,
  128. struct CryptoAuth* ca);
  129. /**
  130. * Choose the authentication credentials to use.
  131. * WARNING: Even if the remote end begins the connection, these credentials will be presented which
  132. * will cause the connection initiation to fail if the remote end does not know of them.
  133. *
  134. * @param password the password to use for authenticating, this must match the password given to
  135. * CryptoAuth_addUser() at the other end of the connection.
  136. * @param authType this must match CryptoAuth_addUser() at the other end of the connection.
  137. * @param wrappedInterface this MUST be the output from CryptoAuth_wrapInterface().
  138. */
  139. void CryptoAuth_setAuth(const String* password,
  140. const uint8_t authType,
  141. struct Interface* wrappedInterface);
  142. /** @return a pointer to the other party's public key. */
  143. uint8_t* CryptoAuth_getHerPublicKey(struct Interface* iface);
  144. /** Reset the session's state to CryptoAuth_NEW, a new connection will be negotiated. */
  145. void CryptoAuth_reset(struct Interface* iface);
  146. /** New CryptoAuth session, has not sent or received anything. */
  147. #define CryptoAuth_NEW 0
  148. /** Sent a hello message, waiting for reply. */
  149. #define CryptoAuth_HANDSHAKE1 1
  150. /** Received a hello message, sent a key message, waiting for the session to complete. */
  151. #define CryptoAuth_HANDSHAKE2 2
  152. /** Sent a hello message and received a key message but have not gotten a data message yet. */
  153. #define CryptoAuth_HANDSHAKE3 3
  154. /** The CryptoAuth session has successfully done a handshake and received at least one message. */
  155. #define CryptoAuth_ESTABLISHED 4
  156. static inline char* CryptoAuth_stateString(int state)
  157. {
  158. switch (state) {
  159. case CryptoAuth_NEW: return "CryptoAuth_NEW";
  160. case CryptoAuth_HANDSHAKE1: return "CryptoAuth_HANDSHAKE1";
  161. case CryptoAuth_HANDSHAKE2: return "CryptoAuth_HANDSHAKE2";
  162. case CryptoAuth_HANDSHAKE3: return "CryptoAuth_HANDSHAKE3";
  163. case CryptoAuth_ESTABLISHED: return "CryptoAuth_ESTABLISHED";
  164. default: return "INVALID";
  165. }
  166. }
  167. /**
  168. * Get the state of the CryptoAuth session.
  169. *
  170. * @param interface a CryptoAuth wrapper.
  171. * @return one of CryptoAuth_NEW,
  172. * CryptoAuth_HANDSHAKE1,
  173. * CryptoAuth_HANDSHAKE2 or
  174. * CryptoAuth_ESTABLISHED
  175. */
  176. int CryptoAuth_getState(struct Interface* iface);
  177. /**
  178. * Get the interface on the other side of this CryptoAuth session.
  179. *
  180. * Given a wrapped interface, get the wrapping interface.
  181. * given a wrapping interface, get the one which is wrapped.
  182. *
  183. * @param iface the wrapped or wrapper iface.
  184. * @return the opposite.
  185. */
  186. struct Interface* CryptoAuth_getConnectedInterface(struct Interface* iface);
  187. /**
  188. * Get the structure which is used to protect against packet replay attacks.
  189. */
  190. struct ReplayProtector* CryptoAuth_getReplayProtector(struct Interface* iface);
  191. #endif