123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /* vim: set expandtab ts=4 sw=4: */
- /*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #ifndef CryptoAuth_H
- #define CryptoAuth_H
- #include "benc/Object.h"
- #include "crypto/random/Random.h"
- #include "crypto/ReplayProtector.h"
- #include "memory/Allocator.h"
- #include "util/Endian.h"
- #include "util/log/Log.h"
- #include "util/events/EventBase.h"
- #include "wire/Message.h"
- #include "util/Linker.h"
- Linker_require("crypto/CryptoAuth.c")
- #include <stdint.h>
- #include <stdbool.h>
- #define CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS 60
- struct CryptoAuth
- {
- uint8_t publicKey[32];
- /**
- * After this number of seconds of inactivity,
- * a connection will be reset to prevent them hanging in a bad state.
- */
- uint32_t resetAfterInactivitySeconds;
- };
- struct CryptoAuth_Session
- {
- uint8_t herPublicKey[32];
- String* userName;
- struct ReplayProtector replayProtector;
- /**
- * Bind this CryptoAuth session to the other node's ip6 address,
- * any packet avertizing a key which doesn't hash to this will be dropped.
- */
- uint8_t herIp6[16];
- };
- /**
- * Associate a password:authtype pair with a user object.
- * Calling CryptoAuth_getUser() on any interface which has established a connection with
- * the same password:authType pair will return the same user object.
- *
- * @param password This should be a key derived from the password using a good key derivation
- * function, using a plaintext password here is NOT recommended.
- * @param authType The method of authenticating the user, only option currently is 1 for sha256
- * based authentication.
- * @param user The thing to associate with this user, will be returned by CryptoAuth_getUser().
- * If this is NULL and requireAuthentication is enabled, authentication will fail.
- * Duplicate user entires are OK.
- * @param ipv6 If not NULL, only allow connections to this CryptoAuth from the key which hashes
- * to the given IPv6 address.
- * @param context The CryptoAuth context.
- * @return 0 if all goes well,
- * CryptoAuth_addUser_INVALID_AUTHTYPE if the authentication method is not supported,
- * CryptoAuth_addUser_OUT_OF_SPACE if there is not enough space to store the entry,
- * CryptoAuth_addUser_DUPLICATE if the same *password* already exists.
- * CryptoAuth_addUser_INVALID_IP if the ipv6 is not valid.
- */
- #define CryptoAuth_addUser_INVALID_AUTHTYPE -1
- #define CryptoAuth_addUser_OUT_OF_SPACE -2
- #define CryptoAuth_addUser_DUPLICATE -3
- #define CryptoAuth_addUser_INVALID_IP -4
- int32_t CryptoAuth_addUser_ipv6(String* password,
- uint8_t authType,
- String* user,
- String* ipv6,
- struct CryptoAuth* context);
- int32_t CryptoAuth_addUser(String* password,
- uint8_t authType,
- String* user,
- struct CryptoAuth* context);
- /**
- * Remove all users registered with this CryptoAuth.
- *
- * @param context the context to remove users for.
- * @param user the identifier which was passed to addUser(), all users with this id will be removed.
- * @return the number of users removed.
- */
- int CryptoAuth_removeUsers(struct CryptoAuth* context, String* user);
- /**
- * Get a list of all the users added via addUser.
- *
- * @param context the context used to call addUser.
- * @param alloc the Allocator to use to create the usersOut array.
- * @returns List* containing the user String's
- */
- List* CryptoAuth_getUsers(struct CryptoAuth* context, struct Allocator* alloc);
- /**
- * Create a new crypto authenticator.
- *
- * @param allocator the means of aquiring memory.
- * @param privateKey the private key to use for this CryptoAuth or null if one should be generated.
- * @param eventBase the libevent context for handling timeouts.
- * @param logger the mechanism for logging output from the CryptoAuth.
- * if NULL then no logging will be done.
- * @param rand random number generator.
- * @return a new CryptoAuth context.
- */
- struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator,
- const uint8_t* privateKey,
- struct EventBase* eventBase,
- struct Log* logger,
- struct Random* rand);
- /**
- * Wrap an interface with crypto authentication.
- *
- * NOTE: Sending empty packets during the handshake is not allowed!
- * Empty packets are used for signaling during the handshake so they can
- * only be used while the session is in state ESTABLISHED.
- *
- * NOTE2: Every received packet is prefixed by the 4 byte *nonce* for that packet
- * in host endian order.
- *
- * @param toWarp the interface to wrap
- * @param herPublicKey the public key of the other party or NULL if unknown.
- * @param herIp6 the ipv6 address of the other party
- * @param requireAuth if the remote end of this interface begins the connection, require
- * them to present valid authentication credentials to connect.
- * If this end begins the connection, this parameter has no effect.
- * @param name a name for this CA which will appear in logs.
- * @param context the CryptoAuth context.
- */
- struct CryptoAuth_Session* CryptoAuth_newSession(struct CryptoAuth* ca,
- struct Allocator* alloc,
- const uint8_t herPublicKey[32],
- const uint8_t herIp6[16],
- const bool requireAuth,
- char* name);
- /** @return 0 on success, -1 otherwise. */
- int CryptoAuth_encrypt(struct CryptoAuth_Session* session, struct Message* msg);
- /** @return 0 on success, -1 otherwise. */
- int CryptoAuth_decrypt(struct CryptoAuth_Session* session, struct Message* msg);
- /**
- * Choose the authentication credentials to use.
- * WARNING: Even if the remote end begins the connection, these credentials will be presented which
- * will cause the connection initiation to fail if the remote end does not know of them.
- *
- * @param password the password to use for authenticating, this must match the password given to
- * CryptoAuth_addUser() at the other end of the connection.
- * @param authType this must match CryptoAuth_addUser() at the other end of the connection.
- * @param wrappedInterface this MUST be the output from CryptoAuth_wrapInterface().
- */
- void CryptoAuth_setAuth(const String* password,
- const uint8_t authType,
- struct CryptoAuth_Session* session);
- /** Reset the session's state to CryptoAuth_NEW, a new connection will be negotiated. */
- //void CryptoAuth_reset(struct CryptoAuth_Session* session);
- void CryptoAuth_resetIfTimeout(struct CryptoAuth_Session* session);
- void CryptoAuth_reset(struct CryptoAuth_Session* caSession);
- /** New CryptoAuth session, has not sent or received anything. */
- #define CryptoAuth_NEW 0
- /** Sent a hello message, waiting for reply. */
- #define CryptoAuth_HANDSHAKE1 1
- /** Received a hello message, sent a key message, waiting for the session to complete. */
- #define CryptoAuth_HANDSHAKE2 2
- /** Sent a hello message and received a key message but have not gotten a data message yet. */
- #define CryptoAuth_HANDSHAKE3 3
- /** The CryptoAuth session has successfully done a handshake and received at least one message. */
- #define CryptoAuth_ESTABLISHED 4
- /** The number of states */
- #define CryptoAuth_STATE_COUNT 5
- static inline char* CryptoAuth_stateString(int state)
- {
- switch (state) {
- case CryptoAuth_NEW: return "CryptoAuth_NEW";
- case CryptoAuth_HANDSHAKE1: return "CryptoAuth_HANDSHAKE1";
- case CryptoAuth_HANDSHAKE2: return "CryptoAuth_HANDSHAKE2";
- case CryptoAuth_HANDSHAKE3: return "CryptoAuth_HANDSHAKE3";
- case CryptoAuth_ESTABLISHED: return "CryptoAuth_ESTABLISHED";
- default: return "INVALID";
- }
- }
- /**
- * Get the state of the CryptoAuth session.
- *
- * @param interface a CryptoAuth wrapper.
- * @return one of CryptoAuth_NEW,
- * CryptoAuth_HANDSHAKE1,
- * CryptoAuth_HANDSHAKE2 or
- * CryptoAuth_ESTABLISHED
- */
- int CryptoAuth_getState(struct CryptoAuth_Session* session);
- #endif
|