/*
  common: Shared definitions and functions used by the privacy-preserving and anonymous document submission project based on blind signatures.
  source: http://www.ter.se/dss
*/

#define VERSION "v0.2, June 16, 2015"
#define DEFAULT_KEY_SIZE 2048

#define STUDENT_BLINDING_PASS_KEY      "student-blinding_pass.key"
#define STUDENT_BLINDING_FAIL_KEY      "student-blinding_fail.key"

#define STUDENT_BLINDED_HASHED_PASS_ID "student-blinded_hashed_pass_ID.b"
#define STUDENT_BLINDED_HASHED_FAIL_ID "student-blinded_hashed_fail_ID.b"

#define DSS_PRIVATE_PASS_KEY           "dss-private_pass.key"
#define DSS_PRIVATE_FAIL_KEY           "dss-private_fail.key"

#define DSS_PUBLIC_PASS_KEY            "dss-public_pass.key"
#define DSS_PUBLIC_FAIL_KEY            "dss-public_fail.key"

#define DSS_SIGNED_BLINDED_HASHED_ID   "dss-signed_blinded_hashed_ID.sig"
#define DSS_SIGNED_HASHED_ID           "dss-signed_hashed_ID.sig"

/**
 * Read data from file.
 */
int readDataFromFile (char* fileNameData, char** data, size_t* sizeData)
{
  FILE* dataFile;
  dataFile = fopen (fileNameData, "rb");
  if (dataFile)
  {
    printf ("Read data from file: %s\n", fileNameData);
    fseek (dataFile, 0, SEEK_END);
    *sizeData = ftell (dataFile);
    fseek (dataFile, 0, SEEK_SET);
    *data = malloc (*sizeData);
    fread (*data, *sizeData, 1, dataFile);
    fclose (dataFile);
  }
  else
  {
    printf ("Unable to open file: %s\n", fileNameData);
    return (1);
  }
  return (0);
}

/**
 * Write data to file.
 */
int writeDataToFile (char* fileNameData, char** data, size_t* sizeData)
{
  FILE* dataFile;
  dataFile = fopen (fileNameData, "wb");
  if (dataFile)
  {
    printf ("Write data to file: %s\n", fileNameData);
    fwrite (*data, *sizeData, 1, dataFile);
    fclose (dataFile);
  }
  else
  {
    printf ("Unable to open file: %s\n", fileNameData);
    return (1);
  }
  return (0);
}

/**
 * Read RSA blinding key from file.
 */
int readBlindingKeyFromFile (char* fileNameBlindingKey, struct GNUNET_CRYPTO_rsa_BlindingKey **blindingKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyFile = fopen (fileNameBlindingKey, "rb");
  if (keyFile)
  {
    printf ("Read RSA blinding key from file: %s\n", fileNameBlindingKey);
    fseek (keyFile, 0, SEEK_END);
    sizeKeyEncoded = ftell (keyFile);
    fseek (keyFile, 0, SEEK_SET);
    keyEncoded = malloc (sizeKeyEncoded);
    fread (keyEncoded, sizeKeyEncoded, 1, keyFile);
    *blindingKey = GNUNET_CRYPTO_rsa_blinding_key_decode (keyEncoded, sizeKeyEncoded);
    GNUNET_free (keyEncoded);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA blinding key file: %s\n", fileNameBlindingKey);
    return (1);
  }
  return (0);
}

/**
 * Write RSA blinding key to file.
 */
int writeBlindingKeyToFile (char* fileNameBlindingKey, struct GNUNET_CRYPTO_rsa_BlindingKey **blindingKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyEncoded = NULL;
  sizeKeyEncoded = GNUNET_CRYPTO_rsa_blinding_key_encode (*blindingKey, &keyEncoded);
  keyFile = fopen (fileNameBlindingKey, "wb");
  if (keyFile)
  {
    printf ("Write RSA blinding key to file: %s\n", fileNameBlindingKey);
    fwrite (keyEncoded, sizeKeyEncoded, 1, keyFile);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA blinding key file for writing: %s\n", fileNameBlindingKey);
    return (1);
  }
  GNUNET_free (keyEncoded);
  return (0);
}

/**
 * Read RSA private key from file.
 */
int readPrivateKeyFromFile (char* fileNamePrivateKey, struct GNUNET_CRYPTO_rsa_PrivateKey **privateKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyFile = fopen (fileNamePrivateKey, "rb");
  if (keyFile)
  {
    printf ("Read RSA private key from file: %s\n", fileNamePrivateKey);
    fseek (keyFile, 0, SEEK_END);
    sizeKeyEncoded = ftell (keyFile);
    fseek (keyFile, 0, SEEK_SET);
    keyEncoded = malloc (sizeKeyEncoded);
    fread (keyEncoded, sizeKeyEncoded, 1, keyFile);
    *privateKey = GNUNET_CRYPTO_rsa_private_key_decode (keyEncoded, sizeKeyEncoded);
    GNUNET_free (keyEncoded);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA private key file: %s\n", fileNamePrivateKey);
    return (1);
  }
  return (0);
}

/**
 * Write RSA private key to file.
 */
int writePrivateKeyToFile (char* fileNamePrivateKey, struct GNUNET_CRYPTO_rsa_PrivateKey **privateKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyEncoded = NULL;
  sizeKeyEncoded = GNUNET_CRYPTO_rsa_private_key_encode (*privateKey, &keyEncoded);
  keyFile = fopen (fileNamePrivateKey, "wb");
  if (keyFile)
  {
    printf ("Write RSA private key to file: %s\n", fileNamePrivateKey);
    fwrite (keyEncoded, sizeKeyEncoded, 1, keyFile);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA private key file for writing: %s\n", fileNamePrivateKey);
    return (1);
  }
  GNUNET_free (keyEncoded);
  return (0);
}

/**
 * Read RSA public key from file.
 */
int readPublicKeyFromFile (char* fileNamePublicKey, struct GNUNET_CRYPTO_rsa_PublicKey **publicKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyFile = fopen (fileNamePublicKey, "rb");
  if (keyFile)
  {
    printf ("Read RSA public key from file: %s\n", fileNamePublicKey);
    fseek (keyFile, 0, SEEK_END);
    sizeKeyEncoded = ftell (keyFile);
    fseek (keyFile, 0, SEEK_SET);
    keyEncoded = malloc (sizeKeyEncoded);
    fread (keyEncoded, sizeKeyEncoded, 1, keyFile);
    *publicKey = GNUNET_CRYPTO_rsa_public_key_decode (keyEncoded, sizeKeyEncoded);
    GNUNET_free (keyEncoded);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA public key file: %s\n", fileNamePublicKey);
    return (1);
  }
  return (0);
}

/**
 * Write RSA public key to file.
 */
int writePublicKeyToFile (char* fileNamePublicKey, struct GNUNET_CRYPTO_rsa_PublicKey **publicKey)
{
  size_t sizeKeyEncoded;
  char* keyEncoded;
  FILE* keyFile;
  keyEncoded = NULL;
  sizeKeyEncoded = GNUNET_CRYPTO_rsa_public_key_encode (*publicKey, &keyEncoded);
  keyFile = fopen (fileNamePublicKey, "wb");
  if (keyFile)
  {
    printf ("Write RSA public key to file: %s\n", fileNamePublicKey);
    fwrite (keyEncoded, sizeKeyEncoded, 1, keyFile);
    fclose (keyFile);
  }
  else
  {
    printf ("Unable to open RSA public key file for writing: %s\n", fileNamePublicKey);
    return (1);
  }
  GNUNET_free (keyEncoded);
  return (0);
}

/**
 * Read RSA signature from file.
 */
int readSignatureFromFile (char* fileNameSignature, struct GNUNET_CRYPTO_rsa_Signature **signature)
{
  size_t sizeSignatureEncoded;
  char* signatureEncoded;
  FILE* signatureFile;
  signatureFile = fopen (fileNameSignature, "rb");
  if (signatureFile)
  {
    printf ("Read RSA signature from file: %s\n", fileNameSignature);
    fseek (signatureFile, 0, SEEK_END);
    sizeSignatureEncoded = ftell (signatureFile);
    fseek (signatureFile, 0, SEEK_SET);
    signatureEncoded = malloc (sizeSignatureEncoded);
    fread (signatureEncoded, sizeSignatureEncoded, 1, signatureFile);
    *signature = GNUNET_CRYPTO_rsa_signature_decode (signatureEncoded, sizeSignatureEncoded);
    GNUNET_free (signatureEncoded);
    fclose (signatureFile);
  }
  else
  {
    printf ("Unable to open RSA signature file: %s\n", fileNameSignature);
    return (1);
  }
  return (0);
}

/**
 * Write RSA signature to file.
 */
int writeSignatureToFile (char* fileNameSignature, struct GNUNET_CRYPTO_rsa_Signature **signature)
{
  size_t sizeSignatureEncoded;
  char* signatureEncoded;
  FILE* signatureFile;
  signatureEncoded = NULL;
  sizeSignatureEncoded = GNUNET_CRYPTO_rsa_signature_encode (*signature, &signatureEncoded);
  signatureFile = fopen (fileNameSignature, "wb");
  if (signatureFile)
  {
    printf ("Write RSA signature to file: %s\n", fileNameSignature);
    fwrite (signatureEncoded, sizeSignatureEncoded, 1, signatureFile);
    fclose (signatureFile);
  }
  else
  {
    printf ("Unable to open RSA signature file for writing: %s\n", fileNameSignature);
    return (1);
  }
  GNUNET_free (signatureEncoded);
  return (0);
}

