Example #1
0
/**
 * mega_aes_key_get_ubase64:
 * @aes_key: a #MegaAesKey
 *
 * Get UBase64 encoded key data.
 *
 * Returns: UBase64 encoded string.
 */
gchar* mega_aes_key_get_ubase64(MegaAesKey* aes_key)
{
    g_return_val_if_fail(MEGA_IS_AES_KEY(aes_key), NULL);
    g_return_val_if_fail(aes_key->priv->loaded, NULL);

    return mega_base64urlencode(aes_key->priv->key, 16);
}
Example #2
0
/**
 * mega_aes_key_make_username_hash:
 * @aes_key: a #MegaAesKey
 * @username: E-mail
 *
 * Generate username hash (uh paraemter for 'us' API call) used for authentication to mega.nz.
 *
 * Returns: Username hash string
 */
gchar* mega_aes_key_make_username_hash(MegaAesKey* aes_key, const gchar* username)
{
    gchar* username_lower;

    g_return_val_if_fail(MEGA_IS_AES_KEY(aes_key), NULL);
    g_return_val_if_fail(username != NULL, NULL);

    username_lower = g_ascii_strdown(username, -1);

    gint l, i;
    guchar hash[16] = {0}, hash_tmp[16], oh[8];

    for (i = 0, l = strlen(username_lower); i < l; i++)
        hash[i % 16] ^= username_lower[i];

    for (i = 16384; i--; )
    {
        AES_encrypt(hash, hash_tmp, &aes_key->priv->enc_key);
        memcpy(hash, hash_tmp, 16);
    }

    memcpy(oh, hash, 4);
    memcpy(oh + 4, hash + 8, 4);

    g_free(username_lower);

    return mega_base64urlencode(oh, 8);
}
Example #3
0
void test_rsa(void)
{
  // my keys
  MegaAesKey* mk = mega_aes_key_new_from_ubase64(MY_MASTER_KEY);
  MegaRsaKey* rk = mega_rsa_key_new();
  
  g_assert(mega_rsa_key_load_enc_privk(rk, MY_PRIVK_ENC, mk));
  g_assert(mega_rsa_key_load_pubk(rk, MY_PUBK));

  GBytes* sid_bytes = mega_rsa_key_decrypt(rk, MY_CSID);
  g_assert_cmpuint(g_bytes_get_size(sid_bytes), >=, 43);
  gchar* sid = mega_base64urlencode(g_bytes_get_data(sid_bytes, NULL), 43);
  g_assert_cmpstr(sid, ==, MY_SID);

  g_assert_cmpstr(mega_rsa_key_get_pubk(rk), ==, MY_PUBK);
  // last block can be different, because it's random padded
  g_assert_cmpstr(trim_last_block(mega_rsa_key_get_enc_privk(rk, mk)), ==, trim_last_block(MY_PRIVK_ENC));

  // test encryption

  guchar plain[16] = {0xff};
  gchar* cipher = mega_rsa_key_encrypt(rk, plain, 16);
  GBytes* plain_bytes = mega_rsa_key_decrypt(rk, cipher);
  g_assert(plain_bytes != NULL);
  g_assert_cmpuint(g_bytes_get_size(plain_bytes), >, 16);
  g_assert(memcmp(g_bytes_get_data(plain_bytes, NULL), plain, 16) == 0);

  // Mega BUG: Plaintext can't start with zero!
  memset(plain, 0, 16);
  cipher = mega_rsa_key_encrypt(rk, plain, 16);
  plain_bytes = mega_rsa_key_decrypt(rk, cipher);
  g_assert(plain_bytes != NULL);
  g_assert_cmpuint(g_bytes_get_size(plain_bytes), >, 16);
  g_assert(memcmp(g_bytes_get_data(plain_bytes, NULL), plain, 16) == 0);

  // generate key

  g_assert(mega_rsa_key_generate(rk));
  gchar* privk1 = mega_rsa_key_get_enc_privk(rk, mk);
  gchar* pubk1 = mega_rsa_key_get_pubk(rk);

  g_assert(mega_rsa_key_generate(rk));
  gchar* privk2 = mega_rsa_key_get_enc_privk(rk, mk);
  gchar* pubk2 = mega_rsa_key_get_pubk(rk);

  g_assert_cmpstr(pubk1, !=, pubk2);
  // last block can be different, because it's random padded
  g_assert_cmpstr(trim_last_block(privk1), !=, trim_last_block(privk2));

  // INVALID USES

  g_assert(!mega_rsa_key_load_enc_privk(rk, MY_CSID, mk));
  g_assert(!mega_rsa_key_load_pubk(rk, MY_CSID));
  g_assert(!mega_rsa_key_load_enc_privk(rk, KEY_INVALID, mk));
  g_assert(!mega_rsa_key_load_pubk(rk, KEY_INVALID));
  g_assert(!mega_rsa_key_load_enc_privk(rk, KEY_NULL, mk));
  g_assert(!mega_rsa_key_load_pubk(rk, KEY_NULL));
}
Example #4
0
/**
 * mega_aes_key_encrypt:
 * @aes_key: a #MegaAesKey
 * @plain: (in) (element-type guint8) (array length=len): Plaintext input data
 * @len: (in): 16 byte aligned length of plaintext data.
 *
 * Encrypt binary data into ubase64 encoded string.
 *
 * Returns: UBase64 encoded ciphertext.
 */
gchar* mega_aes_key_encrypt(MegaAesKey* aes_key, const guchar* plain, gsize len)
{
    guchar* cipher;
    gchar* str;

    g_return_val_if_fail(MEGA_IS_AES_KEY(aes_key), NULL);
    g_return_val_if_fail(plain != NULL, NULL);
    g_return_val_if_fail((len % 16) == 0, NULL);
    g_return_val_if_fail(len > 0, NULL);

    cipher = g_malloc0(len);
    mega_aes_key_encrypt_raw(aes_key, plain, cipher, len);
    str = mega_base64urlencode(cipher, len);
    g_free(cipher);
    return str;
}
Example #5
0
/**
 * mega_aes_key_encrypt_cbc:
 * @aes_key: a #MegaAesKey
 * @plain: (in) (element-type guint8) (array length=len): Plaintext input data
 * @len: (in): 16 byte aligned length of plaintext data.
 *
 * Encrypt plaintext blocks using AES key in CBC mode with zero IV into UBase64
 * ciphertext.
 *
 * Returns: UBase64 encoded ciphertext.
 */
gchar* mega_aes_key_encrypt_cbc(MegaAesKey* aes_key, const guchar* plain, gsize len)
{
    guchar* cipher;
    gchar* str;
    guchar iv[AES_BLOCK_SIZE] = {0};

    g_return_val_if_fail(MEGA_IS_AES_KEY(aes_key), NULL);
    g_return_val_if_fail(plain != NULL, NULL);
    g_return_val_if_fail((len % 16) == 0, NULL);
    g_return_val_if_fail(len > 0, NULL);

    cipher = g_malloc0(len);
    AES_cbc_encrypt(plain, cipher, len, &aes_key->priv->enc_key, iv, 1);
    str = mega_base64urlencode(cipher, len);
    g_free(cipher);

    return str;
}