#pragma once
#include
#include
/// protocol.h defines the messages that a client may send, and the responses a
/// server will provide.Note that the entire request is a single byte stream,
/// as is the entire response.The entire communication between client and
/// server should consist of just two messages.First, the client sends a
/// message (the request), and then the server sends a reply message (the
/// response).
///
/// Different parts of a message may be encrypted in different ways.We
/// indicate this with the enc() function.The expression enc(x, y)
/// indicates that y should be encrypted using key x.Both RSA and AES
/// encryption are used.A unique AES key (aeskey) should be generated each
/// time the client sends an AES-encrypted message to the server.An RSA key
/// (rsakey) is generated by the server once.
///
/// A request always begins with a fixed-size RSA-encrypted block of bytes
/// (@rblock), followed by a variable-size AES-encrypted block of bytes
/// (@ablock).The only exception to this is the KEY request, which consists of
/// a fixed-size unencrypted block of bytes (@kblock). The @kblock or @rblock
/// will always be LEN_RKBLOCK bytes, regardless of whether it is an
/// RSA-encrypted block or the KEY message.KEY messages are padded with
/// characters. RSA-encrypted blocks are padded with random bytes.In the
/// discussion below, this padding is represented by the function pad0() or
/// padR().
///
/// When there is an AES block, its length will be given as part of the RSA
/// block.Note that this is the length of the *encrypted* @ablock.
///
/// In describing message formats, we use the dot (.) to indicate
/// concatenation.So ABC.DEF will consist of 6 bytes, and will be the
/// characters ABCDEF.When len() appears in a description, this indicates
/// that a 4-byte *binary* value will be provided as a length.You are allowed
/// to assume that only x86 machines will be used (little endian).The
/// expression
///
/// Finally, note that some error messages do not correspond directly to any
/// specific request, but are possible nonetheless (i.e., RES_ERR_INV_CMD).
////////////////////////////////////////////////////////////////
// Below are the definitions needed for Assignment #1
////////////////////////////////////////////////////////////////
//
// Constants
//
/// Maximum length of a user name
const int LEN_UNAME = 64;
/// Maximum length of a users actual password
const int LEN_PASSWORD = 64;
/// Maximum length of a hashed password
const int LEN_PASSHASH = SHA256_DIGEST_LENGTH;
/// Maximum length of a users profile file
const int LEN_PROFILE_FILE = 1048576;
/// Length of an rblock or kblock
const int LEN_RKBLOCK = 256;
/// Length of an RSA public key
///
/// NB: It would be better not to hard-code this, since its not defined by us,
/// but by OpenSSL
const int LEN_RSA_PUBKEY = 426;
/// Length of rblock content before it is encrypted
const int LEN_RBLOCK_CONTENT = 128;
/// Length of salt
const int LEN_SALT = 16;
//
// Request Messages
//
/// Request the servers public key (@pubkey), to use for subsequent interaction
/// with the server by the client
///
/// @kblock pad0(KEY)
/// @response @pubkey.
/// @errors None
const std::string REQ_KEY = KEY;
/// Request the creation of a new user, with null content.The user name must
/// not already exist.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.
///
/// @rblock enc(pubkey, padR(REG.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).@u.@p)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_USER_EXISTS @u already exists as a user
/// ERR_REQUEST_FMT Server unable to extract @u or @p from request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_REG = REG;
/// Force the server to stop.@u and @p represent a valid users username and
/// password.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.
///
/// Note that a real server should never let a client cause it to stop.This is
/// a convenience request to help the professor and TAs grade your assignment.
///
/// @rblock enc(pubkey, padR(BYE.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).@u.@p)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_REQUEST_FMT Server unable to extract @u or @p from request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_BYE = BYE;
/// Force the server to send all its data to disk.@u and @p represent a valid
/// users username and password.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.
///
/// Note that a real server should never let a client cause it to do this.This
/// is a convenience request to help the professor and TAs grade your
/// assignment.
///
/// @rblock enc(pubkey, padR(SAV.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).@u.@p)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_REQUEST_FMT Server unable to extract @u or @p from request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_SAV = SAV;
/// Allow user @u (with password @p) to set her profile content to the byte
/// stream @b.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@b must be no more than LEN_PROFILE_FILE bytes.
///
/// @rblock enc(pubkey, padR(SET.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@b).@u.@p.@b)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @b from
///request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_SET = SET;
/// Allow user @u (with password @p) to fetch the profile content @c associated
/// with user @w.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@w must be no more than LEN_UNAME bytes.
///
/// @rblock enc(pubkey, padR(GET.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@w).@u.@p.@w)
/// @response enc(aeskey, OK.len(@c).@c).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_NO_USER @w is not a valid user
/// ERR_NO_DATA @w has a null profile content
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @w from
///request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_GET = GET;
/// Allow user @u (with password @p) to get a newline-separated list (@l) of the
/// names of all the users.@u will appear in @l, @l will not be sorted, and @l
/// will not have a trailing newline.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.
///
/// @rblock enc(pubkey, padR(ALL.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).@u.@p)
/// @response enc(aeskey, OK.len(@l).@l).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_REQUEST_FMT Server unable to extract @u or @p from request
/// ERR_CRYPTO Server could not decrypt @ablock
const std::string REQ_ALL = ALL;
//
// Response Messages
//
/// Response code to indicate that the command was successful
const std::string RES_OK = OK;
/// Response code to indicate that the registered user already exists
const std::string RES_ERR_USER_EXISTS = ERR_USER_EXISTS;
/// Response code to indicate that the client gave a bad username or password
const std::string RES_ERR_LOGIN = ERR_LOGIN;
/// Response code to indicate that the client request was improperly formatted
const std::string RES_ERR_REQ_FMT = ERR_REQ_FMT;
/// Response code to indicate that there is no data to send back
const std::string RES_ERR_NO_DATA = ERR_NO_DATA;
/// Response code to indicate that the user being looked up is invalid
const std::string RES_ERR_NO_USER = ERR_NO_USER;
/// Response code to indicate that the requested command doesnt exist
const std::string RES_ERR_INV_CMD = ERR_INVALID_COMMAND;
/// Response code to indicate that the client didnt get as much data as
/// expected
const std::string RES_ERR_XMIT = ERR_XMIT;
/// Response code to indicate that the client data cant be decrypted with the
/// provided AES key
const std::string RES_ERR_CRYPTO = ERR_CRYPTO;
/// Response code to indicate that the server had an internal error, such as a
/// bad read from a file, error creating a salt, or failure to fork()
const std::string RES_ERR_SERVER = ERR_SERVER;
/// Response code to indicate that something has not been implemented
const std::string RES_ERR_UNIMPLEMENTED = ERR_UNIMPLEMENTED;
////////////////////////////////////////////////////////////////
// Below are the additions for Assignment #2
////////////////////////////////////////////////////////////////
//
// Constants
//
/// Maximum length of a key in the key-value store
const int LEN_KEY = 1024;
/// Maximum length of a value in the key-value store
const int LEN_VAL = 1048576;
//
// Request Messages
//
/// Allow user @u (with password @p) to set previously-unset string key @k to
/// value @v
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@k and @v must conform to LEN_KEY and LEN_VAL.
///
/// @rblock enc(pubkey, padR(KVI.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@k).len(@v).@u.@p.@k.@v)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_KEY @k already has a value
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @k or @v
///from request
/// ERR_CRYPTO Server could not decrypt @ablock
/// ERR_QUOTA_REQ Client exceeded request quota
/// ERR_QUOTA_UP Client exceeded upload bandwidth quota
const std::string REQ_KVI = KVI;
/// Allow user @u (with password @p) to fetch the value @v associated with key
/// @k
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@k must be no more than LEN_KEY bytes.
///
/// @rblock enc(pubkey, padR(KVG.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@k).@u.@p.@k)
/// @response enc(aeskey, OK.len(@v).@v).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_KEY @k does not have a value mapped to it
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @k from
///request
/// ERR_CRYPTO Server could not decrypt @ablock
/// ERR_QUOTA_REQ Client exceeded request quota
/// ERR_QUOTA_DOWN Client exceeded download bandwidth quota
const std::string REQ_KVG = KVG;
/// Allow user @u (with password @p) to delete the mapping for key @k
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@k myst be no more than LEN_KEY bytes.
///
/// @rblock enc(pubkey, padR(KVD.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@k).@u.@p.@k)
/// @response enc(aeskey, OK).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_KEY @k does not have a value mapped to it
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @k from
///request
/// ERR_CRYPTO Server could not decrypt @ablock
/// ERR_QUOTA_REQ Client exceeded request quota
const std::string REQ_KVD = KVD;
/// Allow user @u (with password @p) to upsert a mapping from key @k to value
/// @v.This will change the mapping if @k is already mapped in the key/value
/// store, and will create a new mapping if @k is not yet mapped to any value.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.@k and @v must conform to LEN_KEY and LEN_VAL.
///
/// @rblock enc(pubkey, padR(KVU.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).len(@k).len(@v).@u.@p.@k.@v)
/// @response enc(aeskey, OKINS).
/// enc(aeskey, OKUPD).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_REQUEST_FMT Server unable to extract @u or @p or @k or @v
///from request
/// ERR_CRYPTO Server could not decrypt @ablock
/// ERR_QUOTA_REQ Client exceeded request quota
/// ERR_QUOTA_UP Client exceeded upload bandwidth quota
const std::string REQ_KVU = KVU;
/// Allow user @u (with password @p) to get a newline-separated list (@l) of the
/// keys in the key/value store.
///
/// The user name (@u) and user password (@p) must conform to LEN_UNAME and
/// LEN_PASSWORD.
///
/// @rblock enc(pubkey, padR(KVA.aeskey.len(@ablock)))
/// @ablock enc(aeskey, len(@u).len(@p).@u.@p)
/// @response enc(aeskey, OK.len(@l).@l).
/// enc(aeskey, error_code).
/// ERR_CRYPTO.
/// @errors ERR_LOGIN @u is not a valid user
/// ERR_LOGIN @p is not @us password
/// ERR_NO_DATA There are no key/value pairs to return
/// ERR_REQUEST_FMT Server unable to extract @u or @p from request
/// ERR_CRYPTO Server could not decrypt @ablock
/// ERR_QUOTA_REQ Client exceeded request quota
/// ERR_QUOTA_DOWN Client exceeded download bandwidth quota
const std::string REQ_KVA = KVA;
//
// Response Messages
//
/// Response code to indicate that the upsert command was successful as an
/// insert
const std::string RES_OKINS = OKINS;
/// Response code to indicate that the upsert command was successful as an
/// update
const std::string RES_OKUPD = OKUPD;
/// Response code to indicate that there was an error when searching for the
/// given key
const std::string RES_ERR_KEY = ERR_KEY;
Reviews
There are no reviews yet.