Created a tool using openssl crypto library. The tool can decrypt and

dump user's session key chain to stdout.
This commit is contained in:
S Rahul 2009-06-29 03:07:30 +00:00
parent 15ad4aec02
commit f4eab5a202
2 changed files with 202 additions and 0 deletions

View File

@ -0,0 +1,9 @@
CFLAGS=-fpermissive -g
all: micasa-decrypt.exe
micasa-decrypt.exe: main.cpp
g++ $(CFLAGS) $^ -o $@ -lcrypto
clean:
rm -f micasa-decrypt.exe

View File

@ -0,0 +1,193 @@
#include <iostream>
#include <stdio.h>
#include <assert.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
using namespace std;
#define AES_KEY_128 128
#define AES_KEY_256 256
#define AES_KEY_BYTES_128 (AES_KEY_128/8)
#define AES_KEY_BYTES_256 (AES_KEY_256/8)
int password_to_key(const string *password,
const unsigned char *salt,
size_t salt_len,
unsigned char *key,
size_t key_len)
{
int rc;
unsigned char hash[20];
assert(key_len == AES_KEY_BYTES_128);
assert(salt_len == 64);
rc = PKCS5_PBKDF2_HMAC_SHA1(password->c_str(),
password->length(),
salt,
salt_len,
1000 /*iter*/,
key_len,
key);
return (rc == 1)? 0 : 1;
}
int decrypt(const unsigned char *in,
unsigned char *out,
size_t len,
const unsigned char *key,
size_t key_len,
const unsigned char *IV,
size_t IV_len)
{
AES_KEY key_dec;
assert((key_len == AES_KEY_BYTES_128) || (key_len = AES_KEY_BYTES_256));
assert(IV_len == AES_KEY_BYTES_128);
assert(len % 16 == 0);
AES_set_decrypt_key(key, key_len*8, &key_dec);
AES_cbc_encrypt(in, out, len, &key_dec, IV, AES_DECRYPT);
return 0;
}
/* decrypt and validate checksum. in := (256 bit checksum) | (cipher text) */
int decrypt_and_validate(const unsigned char *in,
unsigned char *out,
size_t *len,
const unsigned char *key,
size_t key_len,
const unsigned char *IV,
size_t IV_len) {
int rc, l = *len;
const unsigned char *hash = in, *CT = in + 32;
unsigned char *h, md[32];
assert(*len > 32);
rc = decrypt(CT, out, *len - 32, key, key_len, IV, IV_len);
*len = (*len - 32) - out[*len - 32 - 1];
bzero(out + *len, l - *len);
h = SHA256(out, *len, md);
assert(memcmp(md, hash, 32) == 0);
return rc;
}
int decrypt_and_validate_file(string file,
unsigned char *out,
size_t *len,
const unsigned char *key,
size_t key_len)
{
int rc, l, in_len = *len;
unsigned char IV[16], *CT;
FILE *fd;
/* Open the encrypted file and read contents */
fd = fopen(file.c_str(), "r");
assert(fd != NULL);
CT = new unsigned char[*len];
*len = fread((void *)CT, 1, *len, fd);
assert(*len < in_len);
fclose(fd);
/* Read the IV */
file.append(".IV");
fd = fopen(file.c_str(), "r");
assert(fd != NULL);
l = fread((void *)IV, 1, sizeof(IV), fd);
assert(l == sizeof(IV));
/* Add a check to ensure that file size is exactly 16 bytes */
fclose(fd);
/* Decrypt */
rc = decrypt_and_validate(CT, out, len, key, key_len, IV, sizeof(IV));
bzero(out + (*len), in_len - (*len));
delete [] CT;
return rc;
}
main()
{
int rc;
size_t len;
FILE *fd;
unsigned char passcode[16], key[32];
string user, user_store;
cout << "User: ";
cin >> user;
user_store = "/home/.casa/" + user + "/";
/* Get passcode. Usually encrypted with desktop password */
{
unsigned char salt[64], passcode_dec[32], IV[16];
unsigned char passcode_enc[128], password_key[16];
string password;
/* Read salt */
fd = fopen((user_store + ".miCASAPCByDesktop.salt").c_str(), "r");
len = fread((void *)salt, 1, sizeof(salt), fd);
assert(len == sizeof(salt));
fclose(fd);
/* Read IV */
fd = fopen((user_store + ".miCASAPCByDesktop.IV").c_str(), "r");
len = fread((void *)IV, 1, sizeof(IV), fd);
assert(len == sizeof(IV));
fclose(fd);
/* Prompt user for password and convert password to key */
cout << "Password: ";
cin >> password;
password_to_key(&password, salt, sizeof(salt), password_key, sizeof(password_key));
/* Read encrypted passcode */
fd = fopen((user_store + ".miCASAPCByDesktop").c_str(), "r");
len = fread((void *)passcode_enc, 1, sizeof(passcode_enc), fd);
assert(len == sizeof(passcode_dec));
fclose(fd);
/* Decrypt */
rc = decrypt(passcode_enc, passcode_dec, len, password_key,
sizeof(password_key), IV, sizeof(IV));
assert(rc == 0);
memcpy(passcode, passcode_dec, sizeof(passcode));
}
/* get secret key from .miCASAKey */
{
unsigned char plain_text[128];
len = sizeof(plain_text);
rc = decrypt_and_validate_file(user_store + ".miCASAKey",
plain_text, &len, passcode,
sizeof(passcode));
assert(len == sizeof(key));
memcpy(key, plain_text, sizeof(key));
}
/* Decrypt micasa store */
{
unsigned char plain_text[4096];
len = sizeof(plain_text);
rc = decrypt_and_validate_file(user_store + ".miCASA",
plain_text, &len, key,
sizeof(key));
puts(plain_text);
}
}