コード例 #1
0
ファイル: generichash.c プロジェクト: GraxRabble/libsodium
int main(void)
{
#define MAXLEN 64
    unsigned char in[MAXLEN], out[crypto_generichash_BYTES_MAX],
        k[crypto_generichash_KEYBYTES_MAX];
    size_t h, i, j;

    for (h = 0; h < crypto_generichash_KEYBYTES_MAX; ++h)
        k[h] = h;

    for (i = 0; i < MAXLEN; ++i) {
        in[i] = i;
        crypto_generichash(out, 1 + i % crypto_generichash_BYTES_MAX, in, i, k,
                           1 + i % crypto_generichash_KEYBYTES_MAX);
        for (j = 0; j < 1 + i % crypto_generichash_BYTES_MAX; ++j) {
            printf("%02x", (unsigned int)out[j]);
        }
        printf("\n");
    }

    assert(crypto_generichash(out, 0U, in, sizeof in, k, sizeof k) == -1);
    assert(crypto_generichash(out, crypto_generichash_BYTES_MAX + 1U, in, sizeof in,
                              k, sizeof k) == -1);
    assert(crypto_generichash(out, sizeof out, in, sizeof in,
                              k, crypto_generichash_KEYBYTES_MAX + 1U) == -1);

    assert(crypto_generichash_bytes_min() > 0U);
    assert(crypto_generichash_bytes_max() > 0U);
    assert(crypto_generichash_bytes() > 0U);
    assert(crypto_generichash_bytes() >= crypto_generichash_bytes_min());
    assert(crypto_generichash_bytes() <= crypto_generichash_bytes_max());
    assert(crypto_generichash_keybytes_min() > 0U);
    assert(crypto_generichash_keybytes_max() > 0U);
    assert(crypto_generichash_keybytes() > 0U);
    assert(crypto_generichash_keybytes() >= crypto_generichash_keybytes_min());
    assert(crypto_generichash_keybytes() <= crypto_generichash_keybytes_max());
    assert(strcmp(crypto_generichash_primitive(), "blake2b") == 0);
    assert(crypto_generichash_bytes_min()
           == crypto_generichash_blake2b_bytes_min());
    assert(crypto_generichash_bytes_max()
           == crypto_generichash_blake2b_bytes_max());
    assert(crypto_generichash_bytes() == crypto_generichash_blake2b_bytes());
    assert(crypto_generichash_keybytes_min()
           == crypto_generichash_blake2b_keybytes_min());
    assert(crypto_generichash_keybytes_max()
           == crypto_generichash_blake2b_keybytes_max());
    assert(crypto_generichash_keybytes()
           == crypto_generichash_blake2b_keybytes());
    assert(crypto_generichash_blake2b_saltbytes() > 0U);
    assert(crypto_generichash_blake2b_personalbytes() > 0U);

    return 0;
}
コード例 #2
0
ファイル: crypto_kx.c プロジェクト: graydon/libsodium
int
crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
                       unsigned char sk[crypto_kx_SECRETKEYBYTES],
                       const unsigned char seed[crypto_kx_SEEDBYTES])
{
    crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
                       seed, crypto_kx_SEEDBYTES, NULL, 0);
    return crypto_scalarmult_base(pk, sk);
}
コード例 #3
0
ファイル: crypto.c プロジェクト: gvsurenderreddy/xTun
int
crypto_init(const char *password) {
    if (sodium_init() == -1) {
        return 1;
    }

    randombytes_set_implementation(&randombytes_salsa20_implementation);
    randombytes_stir();

    return crypto_generichash(secret_key, sizeof secret_key, (uint8_t*)password, strlen(password), NULL, 0);
}
コード例 #4
0
ファイル: profile.cpp プロジェクト: aszinovyev/qTox
QString Profile::avatarPath(const QString &ownerId, bool forceUnencrypted)
{
    if (password.isEmpty() || forceUnencrypted)
        return Settings::getInstance().getSettingsDirPath() + "avatars/" + ownerId + ".png";

    QByteArray idData = ownerId.toUtf8();
    constexpr int hashSize = TOX_PUBLIC_KEY_SIZE; // As long as an unencrypted hash
    static_assert(hashSize >= crypto_generichash_BYTES_MIN
                  && hashSize <= crypto_generichash_BYTES_MAX, "Hash size not supported by libsodium");
    QByteArray hash(hashSize, 0);
    crypto_generichash((uint8_t*)hash.data(), hashSize, (uint8_t*)idData.data(), idData.size(), nullptr, 0);
    return Settings::getInstance().getSettingsDirPath() + "avatars/" + hash.toHex().toUpper() + ".png";
}
コード例 #5
0
ファイル: demo-c.c プロジェクト: jrmarino/libsodium-ada
int main () {
   unsigned char hash[crypto_generichash_BYTES + 1] = {0};
   unsigned char minhash[crypto_generichash_BYTES_MIN + 1] = {0};
   unsigned char maxhash[crypto_generichash_BYTES_MAX + 1] = {0};
   unsigned char key[crypto_generichash_KEYBYTES] = "123456789 123456789 123456789 12";

   if (sodium_init() != 0) {
      return -1;
   }

   size_t min_hex_maxlen = crypto_generichash_BYTES_MIN * 2 + 1;
   size_t std_hex_maxlen = crypto_generichash_BYTES * 2 + 1;
   size_t max_hex_maxlen = crypto_generichash_BYTES_MAX * 2 + 1;
   unsigned char min_hex[min_hex_maxlen];
   unsigned char std_hex[std_hex_maxlen];
   unsigned char max_hex[max_hex_maxlen];

   printf ("text: %s\n", MESSAGE);
   crypto_generichash(minhash, crypto_generichash_BYTES_MIN,
                      MESSAGE, MESSAGE_LEN,
                      NULL, 0);
   sodium_bin2hex (min_hex, min_hex_maxlen, minhash, crypto_generichash_BYTES_MIN);
   printf ("min hash: %s\n", min_hex);
   printf ("hash length is %d\n", strlen (minhash));

   crypto_generichash(hash, crypto_generichash_BYTES,
                      MESSAGE, MESSAGE_LEN,
                      NULL, 0);
   sodium_bin2hex (std_hex, std_hex_maxlen, hash, crypto_generichash_BYTES);
   printf ("\nstd hash: %s\n", std_hex);
   printf ("hash length is %d\n", strlen (hash));

   crypto_generichash(maxhash, crypto_generichash_BYTES_MAX,
                      MESSAGE, MESSAGE_LEN,
                      NULL, 0);
   sodium_bin2hex (max_hex, max_hex_maxlen, maxhash, crypto_generichash_BYTES_MAX);
   printf ("\nmax hash: %s\n", max_hex);
   printf ("hash length is %d\n", strlen (maxhash));

   crypto_generichash(minhash, crypto_generichash_BYTES_MIN,
                      MESSAGE, MESSAGE_LEN,
                      key, sizeof key);
   sodium_bin2hex (min_hex, min_hex_maxlen, minhash, crypto_generichash_BYTES_MIN);
   printf ("\nkeyed min hash: %s\n", min_hex);

   crypto_generichash(hash, crypto_generichash_BYTES,
                      MESSAGE, MESSAGE_LEN,
                      key, sizeof key);
   sodium_bin2hex (std_hex, std_hex_maxlen, hash, crypto_generichash_BYTES);
   printf ("keyed std hash: %s\n", std_hex);

   crypto_generichash(maxhash, crypto_generichash_BYTES_MAX,
                      MESSAGE, MESSAGE_LEN,
                      key, sizeof key);
   sodium_bin2hex (max_hex, max_hex_maxlen, maxhash, crypto_generichash_BYTES_MAX);
   printf ("keyed max hash: %s\n", max_hex);
   return 0;
}
コード例 #6
0
ファイル: cmtp_common.c プロジェクト: darakian/cmtp
/*
Function is used to generate a unique string used as a filename for incomming mail.
unique_file_name_buffer should be 86 bytes for full encode of the 64 byte hash
(4/3 * 64) = 85.333
@param Salt used to mix up the hashing.
@param Pointer to a buffer where the unique file name will be written.
@return Length of the string written to unique_file_name_buffer
*/
int generate_unique_string(int salt, char * unique_file_name_buffer)
{
  struct timespec time_used_in_string_creation;
  clock_gettime(CLOCK_REALTIME, &time_used_in_string_creation);
  char meat_and_potatoes[24];
  memset(meat_and_potatoes, 0, sizeof(meat_and_potatoes));
  memcpy(meat_and_potatoes, &time_used_in_string_creation.tv_sec, sizeof(time_used_in_string_creation.tv_sec));
  memcpy(meat_and_potatoes+sizeof(time_used_in_string_creation.tv_sec), &salt, sizeof(salt));
  memcpy(meat_and_potatoes+sizeof(time_used_in_string_creation.tv_sec)+sizeof(salt), &time_used_in_string_creation.tv_nsec, sizeof(time_used_in_string_creation.tv_nsec));
  unsigned char hash[64]; //64 bytes because hash has a fixed size output
  crypto_generichash(hash, sizeof(hash), (const unsigned char *)meat_and_potatoes, sizeof(meat_and_potatoes),NULL, 0);
  int unique_file_name_length = base64_encode((char *)hash, sizeof(hash), unique_file_name_buffer, sizeof(unique_file_name_buffer), (char *)filesystem_safe_base64_string, 64);
  return unique_file_name_length;
}
コード例 #7
0
ファイル: metamorphic.c プロジェクト: chuckremes/rubinius
static void
mm_generichash(void)
{
    crypto_generichash_state st;
    unsigned char *h, *h2;
    unsigned char *k;
    unsigned char *m;
    size_t         hlen;
    size_t         klen;
    size_t         mlen;
    size_t         l1, l2;
    int            i;

    for (i = 0; i < MAX_ITER; i++) {
        mlen = randombytes_uniform(MAXLEN);
        m = (unsigned char *) sodium_malloc(mlen);
        klen = randombytes_uniform(crypto_generichash_KEYBYTES_MAX -
                                   crypto_generichash_KEYBYTES_MIN + 1U)
            + crypto_generichash_KEYBYTES_MIN;
        k = (unsigned char *) sodium_malloc(klen);
        hlen = randombytes_uniform(crypto_generichash_BYTES_MAX -
                                   crypto_generichash_BYTES_MIN + 1U)
            + crypto_generichash_BYTES_MIN;
        h = (unsigned char *) sodium_malloc(hlen);
        h2 = (unsigned char *) sodium_malloc(hlen);

        randombytes_buf(k, klen);
        randombytes_buf(m, mlen);

        crypto_generichash_init(&st, k, klen, hlen);
        l1 = randombytes_uniform(mlen);
        l2 = randombytes_uniform(mlen - l1);
        crypto_generichash_update(&st, m, l1);
        crypto_generichash_update(&st, m + l1, l2);
        crypto_generichash_update(&st, m + l1 + l2, mlen - l1 - l2);
        crypto_generichash_final(&st, h, hlen);

        crypto_generichash(h2, hlen, m, mlen, k, klen);

        assert(memcmp(h, h2, hlen) == 0);

        sodium_free(h2);
        sodium_free(h);
        sodium_free(k);
        sodium_free(m);
    }
}
コード例 #8
0
ファイル: scrypt.c プロジェクト: TLINDEN/pcp
byte* pcp_scrypt(PCPCTX *ptx, char *passwd, size_t passwdlen, byte *nonce, size_t noncelen) {
  byte *dk = smalloc(64);
  byte *salt = malloc(crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
  
  crypto_generichash(salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES,
                   nonce, noncelen, NULL, 0);

  int status = crypto_pwhash_scryptsalsa208sha256(dk, 64, passwd, passwdlen, salt,
                                                  crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE,
                                                  crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE);

  ucfree(salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
  if (status == 0) {
    return dk;
  }
  else {
    fatal(ptx, "crypto_pwhash_scryptsalsa208sha256() failed\n");
    return NULL;
  }
}
コード例 #9
0
ファイル: encrypt.c プロジェクト: netrice/shadowsocks-libev
int enc_init(const char *pass, const char *method)
{
    int m = TABLE;
    if (method != NULL) {
        for (m = TABLE; m < CIPHER_NUM; m++) {
            if (strcmp(method, supported_ciphers[m]) == 0) {
                break;
            }
        }
        if (m >= CIPHER_NUM) {
            LOGE("Invalid cipher name: %s, use table instead", method);
            m = TABLE;
        }
    }
    if (m == TABLE) {
        enc_table_init(pass);
    } else {
        enc_key_init(m, pass);
    }
    crypto_generichash(auth_key, ONETIMEAUTH_KEYBYTES, (uint8_t *)pass, strlen(pass), NULL, 0);
    return m;
}
コード例 #10
0
ファイル: crypto.c プロジェクト: 11liju/ShadowVPN
int crypto_set_password(const char *password,
                        unsigned long long password_len) {
  return crypto_generichash(key, sizeof key, (unsigned char *)password,
                            password_len, NULL, 0);
}
コード例 #11
0
ファイル: key_derivation.c プロジェクト: 01BTC10/blobcrypt
int
get_key_from_password(unsigned char *k, size_t k_bytes, int confirm)
{
#define SALT_PREFIX "Personalization for this example"
#define SALT_PREFIX_LEN 32

    char          email[1024U];
    char          pwd2[1024U];
    char          pwd[1024U];
    unsigned char salt[SALT_PREFIX_LEN + 1024U];
    unsigned char h0[56];
    size_t        email_len;
    size_t        i;
    int           ret;

    assert(strlen(SALT_PREFIX) == SALT_PREFIX_LEN);
    if (get_line(email, sizeof email, "Email: ") != 0) {
        return -1;
    }
    email_len = strlen(email);
    for (i = 0U; i < email_len; i++) {
        email[i] = (char) tolower((unsigned char) email[i]);
    }
    if (get_password(pwd, sizeof pwd, "Password: "******"Password (one more time): ") != 0) {
            sodium_memzero(pwd, sizeof pwd);
            sodium_memzero(pwd2, sizeof pwd2);
            return -1;
        }
        if (strcmp(pwd, pwd2) != 0) {
            sodium_memzero(pwd, sizeof pwd);
            sodium_memzero(pwd2, sizeof pwd2);
            safe_write(2, "Passwords don't match\n",
                       sizeof "Passwords don't match\n" - 1U, -1);
            return -1;
        }
        sodium_memzero(pwd2, sizeof pwd2);
    }
    safe_write(2, "Deriving key from password... ",
               sizeof "Deriving key from password... " - 1U, -1);
    crypto_generichash(h0, sizeof h0, (const unsigned char *) pwd,
                       strlen(pwd), NULL, 0);
    sodium_memzero(pwd, sizeof pwd);
    memcpy(salt + SALT_PREFIX_LEN, email, email_len);
    sodium_memzero(email, sizeof email);
    ret = crypto_pwhash_scryptsalsa208sha256_ll(h0, sizeof h0, salt,
                                                SALT_PREFIX_LEN + email_len,
                                                1ULL << 18, 1U, 8U, k, k_bytes);
    sodium_memzero(h0, sizeof h0);
    sodium_memzero(salt, sizeof salt);

    safe_write(2, "done\n", sizeof "done\n" - 1U, -1);

    return ret;
}
コード例 #12
0
ファイル: crypto.c プロジェクト: gvsurenderreddy/xTun
int
crypto_generickey(uint8_t *out, size_t outlen, uint8_t *in, size_t inlen, uint8_t *key, size_t keylen) {
    return crypto_generichash(out, outlen, in, inlen, key, keylen);
}
コード例 #13
0
ファイル: server_functions.c プロジェクト: darakian/cmtp
int32_t mail_responder(uint32_t socket)
{
  #ifdef DEBUG
  printf("Entering MAIL subroutine\n");
  #endif /*DEBUG*/
  //Allocate general variables

  //Allocate primary buffers and counters
  char source_account_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t source_account_length = 0;
  char source_domain_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t source_domain_length = 0;
  char dest_account_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t dest_account_length = 0;
  char dest_domain_buffer[ROUTING_FIELD_SIZE] = {0};
  int32_t dest_domain_length = 0;
  uint32_t version = 0;
  uint32_t attachment_count = 0;
  uint64_t message_length = 0;
  uint64_t log_length = 0;
  //Generate unique file from current time and current FD
  //Get time with nanosecond resolution (or so they say)
  struct timespec time_for_file;
  clock_gettime(CLOCK_REALTIME, &time_for_file);
  //Mix time with FD and hash
  //We are hashing two ints and a long, so
  char meat_and_potatoes[24] = {0};
  //memset(meat_and_potatoes, 0, sizeof(meat_and_potatoes));
  memcpy(meat_and_potatoes, &time_for_file.tv_sec, sizeof(time_for_file.tv_sec));
  memcpy(meat_and_potatoes+sizeof(time_for_file.tv_sec), &socket, sizeof(socket));
  memcpy(meat_and_potatoes+sizeof(time_for_file.tv_sec)+sizeof(socket), &time_for_file.tv_nsec, sizeof(time_for_file.tv_nsec));
  unsigned char hash[64]; //64 bytes because hash has a fixed size output
  crypto_generichash(hash, sizeof(hash), (const unsigned char *)meat_and_potatoes, sizeof(meat_and_potatoes),NULL, 0);

  //Get file ready to write
  //TODO needs to be /mail/user/unique_file_name
  char unique_file_name[129] = {0};

  //char base64_username[341] = {0};
  char unique_file_location[522] = {0};
  //TODO Need to check if user is part of this domain. If not the file location should be some temporary storage.

  //unique_file_name_length is not currently used. Should be fine.
  uint32_t unique_file_name_length = base64_encode((char *)hash, sizeof(hash), unique_file_name, sizeof(unique_file_name), (char *)filesystem_safe_base64_string, 64);
  if (unique_file_name_length<=0)
  {
    perror("base64_encode. unique_file_name failed to be created");
    print_to_log("base64_encode failed to create a unique_file_name.", LOG_ERR);
    return -1;
  }
  //uint32_t base64_username_length = base64_encode((char *)dest_account_buffer, strlen(dest_account_buffer), base64_username, strlen(base64_username), (char *)filesystem_safe_base64_string, 64);
  //Read primary routing and processing information
  //First read in fixed length fields
  if (read_n_bytes(socket, (unsigned char *)&version, 4)!=4)
  {
    perror("read_n_bytes version");
    print_to_log("Read error while reading crypto type", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&attachment_count, 4)!=4)
  {
    perror("read_n_bytes attachment_count");
    print_to_log("Read error while reading attachment count", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&log_length, 8)!=8)
  {
    perror("read_n_bytes log_length");
    print_to_log("Read error while reading message length", LOG_ERR);
    return -1;
  }
  if (read_n_bytes(socket, (unsigned char *)&message_length, 8)!=8)
  {
    perror("read_n_bytes message_length");
    print_to_log("Read error while reading message length", LOG_ERR);
    return -1;
  }
  //Read in account and domain info
  if ((dest_account_length=read_until(socket, (unsigned char *)dest_account_buffer, sizeof(dest_account_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading dest_account_buffer", LOG_ERR);
    return -1;
  }
  if (snprintf(unique_file_location, sizeof(unique_file_location), "%s%s%s%s", "/mail/", dest_account_buffer, "/" , unique_file_name)<0)
  {
    perror("snprintf");
    print_to_log("snprintf failed to create a new file string. Cannot write message out",LOG_ERR);
    return -1;
  }
  write_to_file((char *)&version, 4, unique_file_location);
  version = be32toh(version);
  write_to_file((char *)&attachment_count, 4, unique_file_location);
  attachment_count = be32toh(attachment_count);
  write_to_file((char *)&log_length, 8, unique_file_location);
  log_length = be64toh(log_length);
  write_to_file((char *)&message_length, 8, unique_file_location);
  message_length = be64toh(message_length);
  #ifdef DEBUG
  printf("Writing mail to %s\n", unique_file_location);
  printf("Log length = %ld\n", log_length);
  printf("Version = %d\n", version);
  printf("Attachment count = %d\n", attachment_count);
  printf("Message length = %ld\n", message_length);
  #endif /*DEBUG*/

  write_to_file(dest_account_buffer, dest_account_length, unique_file_location);
  #ifdef DEBUG
  printf("dest_account_length = %d\n", dest_account_length);
  #endif /*DEBUG*/
  if ((dest_domain_length=read_until(socket, (unsigned char *)dest_domain_buffer, sizeof(dest_domain_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading dest_domain_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(dest_domain_buffer, dest_domain_length, unique_file_location);
  #ifdef DEBUG
  printf("dest_domain_length = %d\n", dest_domain_length);
  #endif /*DEBUG*/
  //Check if this is the destination
  if((strcmp(dest_domain_buffer, home_domain)!=0)&&(forward==0))
  {
    //Send delivery failure, close connection, clean up and return.
    unsigned char signature_of_DELIVERYFAILURE[crypto_sign_BYTES] = {0};
    unsigned char write_buffer[sizeof(network_crypto_version)+sizeof(server_public_key)+sizeof(signature_of_DELIVERYFAILURE)+2];
    crypto_sign_detached(signature_of_DELIVERYFAILURE, NULL, signature_of_DELIVERYFAILURE, sizeof(signature_of_DELIVERYFAILURE), server_private_key);
    memcpy(write_buffer, &network_crypto_version, sizeof(network_crypto_version));
    memcpy(write_buffer+sizeof(network_crypto_version), cmtp_reply_DELIVERYFAILURE, sizeof(cmtp_reply_DELIVERYFAILURE));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_DELIVERYFAILURE), &signature_of_DELIVERYFAILURE, sizeof(signature_of_DELIVERYFAILURE));
    memcpy(write_buffer+sizeof(network_crypto_version)+sizeof(cmtp_reply_DELIVERYFAILURE)+sizeof(signature_of_DELIVERYFAILURE), &termination_char, sizeof(termination_char));
    write(socket, write_buffer, sizeof(write_buffer));
  }

  if ((source_account_length=read_until(socket, (unsigned char *)source_account_buffer, sizeof(source_account_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading source_account_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(source_account_buffer, source_account_length, unique_file_location);
  #ifdef DEBUG
  printf("source_account_length = %d\n", source_account_length);
  #endif /*DEBUG*/
  if ((source_domain_length=read_until(socket, (unsigned char *)source_domain_buffer, sizeof(source_domain_buffer), '\0'))<0)
  {
    perror("read_until");
    print_to_log("Read error while reading source_domain_buffer", LOG_ERR);
    return -1;
  }
  write_to_file(source_domain_buffer, source_domain_length, unique_file_location);
  #ifdef DEBUG
  printf("source_domain_length = %d\n", source_domain_length);
  #endif /*DEBUG*/
  //This completes the read of the header


  //uint64_t numeric_message_length = be64toh(*(uint64_t*)(&(message_length[0])));
  //uint64_t numeric_log_length = be64toh(*(uint64_t*)(&(log_length[0])));

  char temp_byte[1] = {0};
  //Read log
  for (uint64_t i = 0; i<log_length; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }
  //Read message body
  for (uint64_t i = 0; i<message_length; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }

  #ifdef DEBUG
  printf("Message body finished. Moving to attachment handling.\n");
  #endif /*DEBUG*/
  //Read for attachment
  //uint32_t numeric_attachment_count = be32toh(*(uint32_t*)(&(attachment_count[0])));
  temp_byte[0] = 0;
  for (uint64_t i = 0; i<attachment_count; i++)
  {
    if (read(socket, temp_byte, 1)<1)
    {
      print_to_log("read error while reading message body", LOG_ERR);
      perror("read");
      return -1;
    }
    write_to_file(temp_byte, 1, unique_file_location);
  }
  #ifdef DEBUG
  printf("Mail destin for %s\n", dest_domain_buffer);
  printf("Server domain is %s\n", home_domain);
  #endif /*DEBUG*/

  //Destination cases
   if ((memcmp(dest_domain_buffer, home_domain, dest_domain_length)==0)&&(memcmp(dest_account_buffer,"",1))==0)
   {
     #ifdef DEBUG
     printf("Devlivered mail is for server. Begin processing.\n");
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for the server. Processing.",LOG_INFO);
     //Destination is this domain and for the server
   }
   else if ((memcmp(dest_domain_buffer, home_domain, dest_domain_length)==0))
   {
     #ifdef DEBUG
     printf("Devlivered mail is for a user on this domain. Store.\n");
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for a user on this domain. Storing.",LOG_INFO);
     //Destination is for a user at this domain
   }
   else
   {
     #ifdef DEBUG
     printf("Devlivered mail is not destined for this domain. Forward to %s\n", dest_domain_buffer);
     #endif /*DEBUG*/
     print_to_log("Mail has arrived for another domain. Forwarding.",LOG_INFO);
     forwardMessage(unique_file_location, dest_domain_buffer);
     //Destination is on the web. Forward message.
   }
   #ifdef DEBUG
   printf("Mail section complete. Returning to mail loop.\n");
   #endif /*DEBUG*/
   return 0;
}