CryptoAuth.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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 <https://www.gnu.org/licenses/>.
  14. */
  15. #ifndef CryptoAuth_H
  16. #define CryptoAuth_H
  17. #include "benc/StringList.h"
  18. #include "crypto/random/Random.h"
  19. #include "crypto/ReplayProtector.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 "wire/Message.h"
  25. #include "util/Linker.h"
  26. Linker_require("crypto/CryptoAuth.c")
  27. #include <stdint.h>
  28. #include <stdbool.h>
  29. #define CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS 60
  30. #define CryptoAuth_DEFAULT_SETUP_RESET_AFTER_INACTIVITY_SECONDS 10
  31. struct CryptoAuth
  32. {
  33. uint8_t publicKey[32];
  34. };
  35. struct CryptoAuth_Session
  36. {
  37. uint8_t herPublicKey[32];
  38. String* displayName;
  39. struct ReplayProtector replayProtector;
  40. /**
  41. * Bind this CryptoAuth session to the other node's ip6 address,
  42. * any packet avertizing a key which doesn't hash to this will be dropped.
  43. */
  44. uint8_t herIp6[16];
  45. /**
  46. * After this number of seconds of inactivity,
  47. * a connection will be reset to prevent them hanging in a bad state.
  48. */
  49. uint32_t resetAfterInactivitySeconds;
  50. /** If a session is not completely setup, reset it after this many seconds of inactivity. */
  51. uint32_t setupResetAfterInactivitySeconds;
  52. };
  53. /**
  54. * Associate a password:authtype pair with a user object.
  55. * Calling CryptoAuth_getUser() on any interface which has established a connection with
  56. * the same password:authType pair will return the same user object.
  57. *
  58. * @param password This should be a key derived from the password using a good key derivation
  59. * function, using a plaintext password here is NOT recommended.
  60. * @param authType The method of authenticating the user, only option currently is 1 for sha256
  61. * based authentication.
  62. * @param user The thing to associate with this user, will be returned by CryptoAuth_getUser().
  63. * If this is NULL and requireAuthentication is enabled, authentication will fail.
  64. * Duplicate user entires are OK.
  65. * @param ipv6 If not NULL, only allow connections to this CryptoAuth from the key which hashes
  66. * to the given IPv6 address.
  67. * @param context The CryptoAuth context.
  68. * @return 0 if all goes well,
  69. * CryptoAuth_addUser_DUPLICATE if the same *password* already exists.
  70. */
  71. #define CryptoAuth_addUser_DUPLICATE -3
  72. int CryptoAuth_addUser_ipv6(String* password,
  73. String* login,
  74. uint8_t ipv6[16],
  75. struct CryptoAuth* ca);
  76. static inline int CryptoAuth_addUser(String* password, String* login, struct CryptoAuth* ca)
  77. {
  78. return CryptoAuth_addUser_ipv6(password, login, NULL, ca);
  79. }
  80. /**
  81. * Remove all users registered with this CryptoAuth.
  82. *
  83. * @param context the context to remove users for.
  84. * @param user the identifier which was passed to addUser(), all users with this id will be removed.
  85. * @return the number of users removed.
  86. */
  87. int CryptoAuth_removeUsers(struct CryptoAuth* context, String* user);
  88. /**
  89. * Get a list of all the users added via addUser.
  90. *
  91. * @param context the context used to call addUser.
  92. * @param alloc the Allocator to use to create the usersOut array.
  93. * @returns List* containing the user String's
  94. */
  95. struct StringList* CryptoAuth_getUsers(struct CryptoAuth* context, struct Allocator* alloc);
  96. /**
  97. * Create a new crypto authenticator.
  98. *
  99. * @param allocator the means of aquiring memory.
  100. * @param privateKey the private key to use for this CryptoAuth or null if one should be generated.
  101. * @param eventBase the libevent context for handling timeouts.
  102. * @param logger the mechanism for logging output from the CryptoAuth.
  103. * if NULL then no logging will be done.
  104. * @param rand random number generator.
  105. * @return a new CryptoAuth context.
  106. */
  107. struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator,
  108. const uint8_t* privateKey,
  109. struct EventBase* eventBase,
  110. struct Log* logger,
  111. struct Random* rand);
  112. /**
  113. * Wrap an interface with crypto authentication.
  114. *
  115. * NOTE2: Every received packet is prefixed by the 4 byte *nonce* for that packet
  116. * in host endian order.
  117. *
  118. * @param toWarp the interface to wrap
  119. * @param herPublicKey the public key of the other party or NULL if unknown.
  120. * @param requireAuth if the remote end of this interface begins the connection, require
  121. * them to present valid authentication credentials to connect.
  122. * If this end begins the connection, this parameter has no effect.
  123. * @param name a name for this CA which will appear in logs.
  124. * @param context the CryptoAuth context.
  125. */
  126. struct CryptoAuth_Session* CryptoAuth_newSession(struct CryptoAuth* ca,
  127. struct Allocator* alloc,
  128. const uint8_t herPublicKey[32],
  129. const bool requireAuth,
  130. char* name);
  131. /** @return 0 on success, -1 otherwise. */
  132. int CryptoAuth_encrypt(struct CryptoAuth_Session* session, struct Message* msg);
  133. enum CryptoAuth_DecryptErr {
  134. CryptoAuth_DecryptErr_NONE = 0,
  135. // Packet too short
  136. CryptoAuth_DecryptErr_RUNT = 1,
  137. // Received a run message to an un-setup session
  138. CryptoAuth_DecryptErr_NO_SESSION = 2,
  139. CryptoAuth_DecryptErr_FINAL_SHAKE_FAIL = 3,
  140. CryptoAuth_DecryptErr_FAILED_DECRYPT_RUN_MSG = 4,
  141. CryptoAuth_DecryptErr_KEY_PKT_ESTABLISHED_SESSION = 5,
  142. CryptoAuth_DecryptErr_WRONG_PERM_PUBKEY = 6,
  143. // Only specific IPv6 can connect to this CA session and the request has the wrong one.
  144. CryptoAuth_DecryptErr_IP_RESTRICTED = 7,
  145. // Authentication is required and is missing.
  146. CryptoAuth_DecryptErr_AUTH_REQUIRED = 8,
  147. // Basically this means the login name doesn't exist, beware of giving this information up.
  148. CryptoAuth_DecryptErr_UNRECOGNIZED_AUTH = 9,
  149. // Key packet and we are not in a state to accept a key packet
  150. CryptoAuth_DecryptErr_STRAY_KEY = 10,
  151. CryptoAuth_DecryptErr_HANDSHAKE_DECRYPT_FAILED = 11,
  152. // Set zero as the temporary public key
  153. CryptoAuth_DecryptErr_WISEGUY = 12,
  154. // Duplicate hello or key packet (same temp key and not a repeat-packet type)
  155. // Or repeat key packet with different key than what is known
  156. // Or a repeat hello packet for which we already know the temp key (meaning it is associated
  157. // with an existing session) when we are not in a state to accept a repeat hello.
  158. CryptoAuth_DecryptErr_INVALID_PACKET = 13,
  159. // Replay checker could not validate this packet
  160. CryptoAuth_DecryptErr_REPLAY = 14,
  161. // Authenticated decryption failed
  162. CryptoAuth_DecryptErr_DECRYPT = 15
  163. };
  164. // returns 0 if everything if ok, otherwise an encryption error.
  165. // If there is an error, the content of the message MIGHT already be decrypted !
  166. enum CryptoAuth_DecryptErr CryptoAuth_decrypt(struct CryptoAuth_Session* sess, struct Message* msg);
  167. /**
  168. * Choose the authentication credentials to use.
  169. * WARNING: Even if the remote end begins the connection, these credentials will be presented which
  170. * will cause the connection initiation to fail if the remote end does not know of them.
  171. *
  172. * @param password the password to use for authenticating, this must match the password given to
  173. * CryptoAuth_addUser() at the other end of the connection.
  174. * @param login the username to use for logging in with the other node.
  175. * if null then the authtype will be type 1 (password only).
  176. * @param wrappedInterface this MUST be the output from CryptoAuth_wrapInterface().
  177. */
  178. void CryptoAuth_setAuth(const String* password,
  179. const String* login,
  180. struct CryptoAuth_Session* caSession);
  181. /** Reset the session's state to CryptoAuth_NEW, a new connection will be negotiated. */
  182. //void CryptoAuth_reset(struct CryptoAuth_Session* session);
  183. void CryptoAuth_resetIfTimeout(struct CryptoAuth_Session* session);
  184. void CryptoAuth_reset(struct CryptoAuth_Session* caSession);
  185. enum CryptoAuth_State {
  186. // New CryptoAuth session, has not sent or received anything
  187. CryptoAuth_State_INIT = 0,
  188. // Sent a hello message, waiting for reply
  189. CryptoAuth_State_SENT_HELLO = 1,
  190. // Received a hello message, have not yet sent a reply
  191. CryptoAuth_State_RECEIVED_HELLO = 2,
  192. // Received a hello message, sent a key message, waiting for the session to complete
  193. CryptoAuth_State_SENT_KEY = 3,
  194. // Sent a hello message, received a key message, may or may not have sent some data traffic
  195. // but no data traffic has yet been received
  196. CryptoAuth_State_RECEIVED_KEY = 4,
  197. // Received data traffic, session is in run state
  198. CryptoAuth_State_ESTABLISHED = 100
  199. };
  200. static inline char* CryptoAuth_stateString(int state)
  201. {
  202. switch (state) {
  203. case CryptoAuth_State_INIT: return "INIT";
  204. case CryptoAuth_State_SENT_HELLO: return "SENT_HELLO";
  205. case CryptoAuth_State_RECEIVED_HELLO: return "RECEIVED_HELLO";
  206. case CryptoAuth_State_SENT_KEY: return "SENT_KEY";
  207. case CryptoAuth_State_RECEIVED_KEY: return "RECEIVED_KEY";
  208. case CryptoAuth_State_ESTABLISHED: return "ESTABLISHED";
  209. default: return "INVALID";
  210. }
  211. }
  212. enum CryptoAuth_State CryptoAuth_getState(struct CryptoAuth_Session* session);
  213. #endif