1 #ifndef BLOCK_TX_UTILS_H 2 #define BLOCK_TX_UTILS_H 3 4 #include <event2/buffer.h> 5 #include <event2/util.h> 6 #include <openssl/evp.h> 7 8 /* Common structures and contants shared by the client and server. */ 9 10 /* We use AES 256 */ 11 #define ENC_KEY_SIZE 32 12 #define ENC_BLOCK_SIZE 16 13 14 #define BLOCK_PROTOCOL_VERSION 2 15 16 enum { 17 STATUS_OK = 0, 18 STATUS_VERSION_MISMATCH, 19 STATUS_BAD_REQUEST, 20 STATUS_ACCESS_DENIED, 21 STATUS_INTERNAL_SERVER_ERROR, 22 STATUS_NOT_FOUND, 23 }; 24 25 struct _HandshakeRequest { 26 gint32 version; 27 gint32 key_len; 28 char enc_session_key[0]; 29 } __attribute__((__packed__)); 30 31 typedef struct _HandshakeRequest HandshakeRequest; 32 33 struct _HandshakeResponse { 34 gint32 status; 35 gint32 version; 36 } __attribute__((__packed__)); 37 38 typedef struct _HandshakeResponse HandshakeResponse; 39 40 struct _AuthResponse { 41 gint32 status; 42 } __attribute__((__packed__)); 43 44 typedef struct _AuthResponse AuthResponse; 45 46 enum { 47 REQUEST_COMMAND_GET = 0, 48 REQUEST_COMMAND_PUT, 49 }; 50 51 struct _RequestHeader { 52 gint32 command; 53 char block_id[40]; 54 } __attribute__((__packed__)); 55 56 typedef struct _RequestHeader RequestHeader; 57 58 struct _ResponseHeader { 59 gint32 status; 60 } __attribute__((__packed__)); 61 62 typedef struct _ResponseHeader ResponseHeader; 63 64 /* Utility functions for encryption. */ 65 66 void 67 blocktx_generate_encrypt_key (unsigned char *session_key, int sk_len, 68 unsigned char *key, unsigned char *iv); 69 70 int 71 blocktx_encrypt_init (EVP_CIPHER_CTX **ctx, 72 const unsigned char *key, 73 const unsigned char *iv); 74 75 int 76 blocktx_decrypt_init (EVP_CIPHER_CTX **ctx, 77 const unsigned char *key, 78 const unsigned char *iv); 79 80 /* 81 * Encrypted data is sent in "frames". 82 * Format of a frame: 83 * 84 * length of data in the frame after encryption + encrypted data. 85 * 86 * Each frame can contain three types of contents: 87 * 1. Auth request or response; 88 * 2. Block request or response header; 89 * 3. Block content. 90 */ 91 92 int 93 send_encrypted_data_frame_begin (evutil_socket_t data_fd, 94 int frame_len); 95 96 int 97 send_encrypted_data (EVP_CIPHER_CTX *ctx, 98 evutil_socket_t data_fd, 99 const void *buf, int len); 100 101 int 102 send_encrypted_data_frame_end (EVP_CIPHER_CTX *ctx, 103 evutil_socket_t data_fd); 104 105 typedef int (*FrameContentCB) (char *, int, void *); 106 107 typedef int (*FrameFragmentCB) (char *, int, int, void *); 108 109 typedef struct _FrameParser { 110 int enc_frame_len; 111 112 unsigned char key[ENC_KEY_SIZE]; 113 unsigned char iv[ENC_BLOCK_SIZE]; 114 gboolean enc_init; 115 EVP_CIPHER_CTX *ctx; 116 117 unsigned char key_v2[ENC_KEY_SIZE]; 118 unsigned char iv_v2[ENC_BLOCK_SIZE]; 119 120 int version; 121 122 /* Used when parsing fragments */ 123 int remain; 124 125 FrameContentCB content_cb; 126 FrameFragmentCB fragment_cb; 127 void *cbarg; 128 } FrameParser; 129 130 /* Handle entire frame all at once. 131 * parser->content_cb() will be called after the entire frame is read. 132 */ 133 int 134 handle_one_frame (struct evbuffer *buf, FrameParser *parser); 135 136 /* Handle a frame fragment by fragment. 137 * parser->fragment_cb() will be called when any amount data is read. 138 */ 139 int 140 handle_frame_fragments (struct evbuffer *buf, FrameParser *parser); 141 142 #endif 143