Apply latest CVS on top. I will rewrite history properly later.
parent
e2deb0dad4
commit
2d645bae53
|
@ -133,6 +133,15 @@ xx/03/2007 - 2.0.0 - ntfsmount sports full r/w and ntfsresize supports Vista.
|
|||
- ntfsmount: st_block calculation was wrong. (Yuval)
|
||||
- mkntfs: Use Vista $Boot rather than XP one. (Anton)
|
||||
- ntfsmount: use utimens() instead of deprecated utime(). (Yura)
|
||||
- libntfs: Ignore bootsector checksum inconsistencies as too many 3rd
|
||||
party utilities update the boot sector without correcting the
|
||||
checksum. Ported change from kernel driver. (Anton)
|
||||
- ntfsdecrypt: Major improvement! We now validate the .pfx file to be
|
||||
the right type of RSA key and we also determine the thumbprint and
|
||||
compare the one in the keys to the one in the .pfx file thus we only
|
||||
try to decrypt the FEK once we have the correct key. Several other
|
||||
bug fixes leading to crashes. Also make compilation work on OS X
|
||||
when gnutls is otherwise not found. (Anton, Yura)
|
||||
|
||||
21/06/2006 - 1.13.1 - Various fixes.
|
||||
|
||||
|
|
|
@ -63,22 +63,26 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b,
|
|||
|
||||
ntfs_log_debug("\nBeginning bootsector check...\n");
|
||||
|
||||
/* Calculate the checksum. Note, this is just a simple addition of
|
||||
all u32 values in the bootsector starting at the beginning and
|
||||
finishing at the offset of the checksum itself (i.e. not including
|
||||
the checksum...). */
|
||||
if ((void*)b < (void*)&b->checksum) {
|
||||
/*
|
||||
* Check that checksum == sum of u32 values from b to the checksum
|
||||
* field. If checksum is zero, no checking is done. We will work when
|
||||
* the checksum test fails, since some utilities update the boot sector
|
||||
* ignoring the checksum which leaves the checksum out-of-date. We
|
||||
* report a warning if this is the case.
|
||||
*/
|
||||
if ((void*)b < (void*)&b->checksum && b->checksum) {
|
||||
u32 *u = (u32 *)b;
|
||||
u32 *bi = (u32 *)(&b->checksum);
|
||||
|
||||
ntfs_log_debug("Calculating bootsector checksum... ");
|
||||
|
||||
for (i = 0; u < bi; ++u)
|
||||
i += le32_to_cpup(u);
|
||||
|
||||
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i)
|
||||
goto not_ntfs;
|
||||
ntfs_log_debug("OK\n");
|
||||
if (le32_to_cpu(b->checksum) && le32_to_cpu(b->checksum) != i) {
|
||||
ntfs_log_debug("FAILED\n");
|
||||
ntfs_log_debug("The NTFS bootsector contains an "
|
||||
"incorrect checksum.");
|
||||
} else
|
||||
ntfs_log_debug("OK\n");
|
||||
}
|
||||
|
||||
/* Check OEMidentifier is "NTFS " */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* ntfsdecrypt - Decrypt ntfs encrypted files. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2005 Yuval Fledel
|
||||
* Copyright (c) 2005 Anton Altaparmakov
|
||||
* Copyright (c) 2005-2007 Anton Altaparmakov
|
||||
*
|
||||
* This utility will decrypt files and print the decrypted data on the standard
|
||||
* output.
|
||||
|
@ -66,6 +66,19 @@
|
|||
|
||||
typedef gcry_sexp_t ntfs_rsa_private_key;
|
||||
|
||||
#define NTFS_SHA1_THUMBPRINT_SIZE 0x14
|
||||
|
||||
#define NTFS_CRED_TYPE_CERT_THUMBPRINT const_cpu_to_le32(3)
|
||||
|
||||
#define NTFS_EFS_CERT_PURPOSE_OID_DDF "1.3.6.1.4.1.311.10.3.4"
|
||||
#define NTFS_EFS_CERT_PURPOSE_OID_DRF "1.3.6.1.4.1.311.10.3.4.1"
|
||||
|
||||
typedef enum {
|
||||
DF_TYPE_UNKNOWN,
|
||||
DF_TYPE_DDF,
|
||||
DF_TYPE_DRF,
|
||||
} NTFS_DF_TYPES;
|
||||
|
||||
/**
|
||||
* enum NTFS_CRYPTO_ALGORITHMS - List of crypto algorithms used by EFS (32 bit)
|
||||
*
|
||||
|
@ -439,19 +452,34 @@ static ntfs_rsa_private_key ntfs_rsa_private_key_import_from_gnutls(
|
|||
return (ntfs_rsa_private_key)rsa_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_rsa_private_key_release
|
||||
*/
|
||||
static void ntfs_rsa_private_key_release(ntfs_rsa_private_key rsa_key)
|
||||
{
|
||||
gcry_sexp_release((gcry_sexp_t)rsa_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_pkcs12_extract_rsa_key
|
||||
*/
|
||||
static ntfs_rsa_private_key ntfs_pkcs12_extract_rsa_key(u8 *pfx, int pfx_size,
|
||||
char *password)
|
||||
char *password, char *thumbprint, int thumbprint_size,
|
||||
NTFS_DF_TYPES *df_type)
|
||||
{
|
||||
int err, bag_index, flags;
|
||||
gnutls_datum_t dpfx, dkey;
|
||||
gnutls_pkcs12_t pkcs12;
|
||||
gnutls_pkcs12_bag_t bag;
|
||||
gnutls_x509_privkey_t pkey;
|
||||
gnutls_pkcs12_t pkcs12 = NULL;
|
||||
gnutls_pkcs12_bag_t bag = NULL;
|
||||
gnutls_x509_privkey_t pkey = NULL;
|
||||
gnutls_x509_crt_t crt = NULL;
|
||||
ntfs_rsa_private_key rsa_key = NULL;
|
||||
char purpose_oid[100];
|
||||
size_t purpose_oid_size = sizeof(purpose_oid);
|
||||
size_t tp_size = thumbprint_size;
|
||||
BOOL have_thumbprint = FALSE;
|
||||
|
||||
*df_type = DF_TYPE_UNKNOWN;
|
||||
/* Create a pkcs12 structure. */
|
||||
err = gnutls_pkcs12_init(&pkcs12);
|
||||
if (err) {
|
||||
|
@ -467,7 +495,7 @@ static ntfs_rsa_private_key ntfs_pkcs12_extract_rsa_key(u8 *pfx, int pfx_size,
|
|||
ntfs_log_error("Failed to convert the PFX file from DER to "
|
||||
"native PKCS#12 format: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto out;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Verify that the password is correct and that the key file has not
|
||||
|
@ -484,9 +512,9 @@ retry_verify:
|
|||
password = NULL;
|
||||
goto retry_verify;
|
||||
}
|
||||
ntfs_log_error("Failed to verify the MAC (%s). Is the "
|
||||
ntfs_log_error("Failed to verify the MAC: %s Is the "
|
||||
"password correct?\n", gnutls_strerror(err));
|
||||
goto out;
|
||||
goto err;
|
||||
}
|
||||
for (bag_index = 0; ; bag_index++) {
|
||||
err = gnutls_pkcs12_bag_init(&bag);
|
||||
|
@ -494,29 +522,31 @@ retry_verify:
|
|||
ntfs_log_error("Failed to initialize PKCS#12 Bag "
|
||||
"structure: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto out;
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_pkcs12_get_bag(pkcs12, bag_index, bag);
|
||||
if (err) {
|
||||
if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
|
||||
if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
ntfs_log_error("Failed to obtain Bag from PKCS#12 "
|
||||
"structure: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
check_again:
|
||||
err = gnutls_pkcs12_bag_get_count(bag);
|
||||
if (err < 0) {
|
||||
ntfs_log_error("Failed to obtain Bag count: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_pkcs12_bag_get_type(bag, 0);
|
||||
if (err < 0) {
|
||||
ntfs_log_error("Failed to determine Bag type: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
flags = 0;
|
||||
switch (err) {
|
||||
|
@ -527,14 +557,14 @@ check_again:
|
|||
if (err < 0) {
|
||||
ntfs_log_error("Failed to obtain Bag data: "
|
||||
"%s\n", gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_x509_privkey_init(&pkey);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to initialized "
|
||||
"private key structure: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
/* Decrypt the private key into GNU TLS format. */
|
||||
err = gnutls_x509_privkey_import_pkcs8(pkey, &dkey,
|
||||
|
@ -544,7 +574,7 @@ check_again:
|
|||
"key from DER to GNU TLS "
|
||||
"format: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto key_out;
|
||||
goto err;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
|
@ -572,38 +602,110 @@ check_again:
|
|||
#endif
|
||||
/* Convert the private key to our internal format. */
|
||||
rsa_key = ntfs_rsa_private_key_import_from_gnutls(pkey);
|
||||
goto key_out;
|
||||
if (!rsa_key)
|
||||
goto err;
|
||||
break;
|
||||
case GNUTLS_BAG_ENCRYPTED:
|
||||
err = gnutls_pkcs12_bag_decrypt(bag, password);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to decrypt Bag: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto bag_out;
|
||||
goto err;
|
||||
}
|
||||
goto check_again;
|
||||
case GNUTLS_BAG_CERTIFICATE:
|
||||
err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey);
|
||||
if (err < 0) {
|
||||
ntfs_log_error("Failed to obtain Bag data: "
|
||||
"%s\n", gnutls_strerror(err));
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_x509_crt_init(&crt);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to initialize "
|
||||
"certificate structure: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_x509_crt_import(crt, &dkey,
|
||||
GNUTLS_X509_FMT_DER);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to convert certificate "
|
||||
"from DER to GNU TLS format: "
|
||||
"%s\n", gnutls_strerror(err));
|
||||
goto err;
|
||||
}
|
||||
err = gnutls_x509_crt_get_key_purpose_oid(crt, 0,
|
||||
purpose_oid, &purpose_oid_size, NULL);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to get key purpose "
|
||||
"OID: %s\n",
|
||||
gnutls_strerror(err));
|
||||
goto err;
|
||||
}
|
||||
purpose_oid[purpose_oid_size - 1] = '\0';
|
||||
if (!strncmp(purpose_oid,
|
||||
NTFS_EFS_CERT_PURPOSE_OID_DRF,
|
||||
strlen(
|
||||
NTFS_EFS_CERT_PURPOSE_OID_DRF)))
|
||||
*df_type = DF_TYPE_DRF;
|
||||
else if (!strncmp(purpose_oid,
|
||||
NTFS_EFS_CERT_PURPOSE_OID_DDF,
|
||||
strlen(
|
||||
NTFS_EFS_CERT_PURPOSE_OID_DDF)))
|
||||
*df_type = DF_TYPE_DDF;
|
||||
else {
|
||||
ntfs_log_error("Certificate has unknown "
|
||||
"purpose OID %s.\n",
|
||||
purpose_oid);
|
||||
err = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
/* Return the thumbprint to the caller. */
|
||||
err = gnutls_x509_crt_get_fingerprint(crt,
|
||||
GNUTLS_DIG_SHA1, thumbprint, &tp_size);
|
||||
if (err) {
|
||||
ntfs_log_error("Failed to get thumbprint: "
|
||||
"%s\n", gnutls_strerror(err));
|
||||
goto err;
|
||||
}
|
||||
if (tp_size != NTFS_SHA1_THUMBPRINT_SIZE) {
|
||||
ntfs_log_error("Invalid thumbprint size %zd. "
|
||||
"Should be %d.\n", tp_size,
|
||||
thumbprint_size);
|
||||
err = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
have_thumbprint = TRUE;
|
||||
gnutls_x509_crt_deinit(crt);
|
||||
crt = NULL;
|
||||
break;
|
||||
default:
|
||||
/* We do not care about other types. */
|
||||
break;
|
||||
}
|
||||
gnutls_pkcs12_bag_deinit(bag);
|
||||
}
|
||||
key_out:
|
||||
gnutls_x509_privkey_deinit(pkey);
|
||||
bag_out:
|
||||
gnutls_pkcs12_bag_deinit(bag);
|
||||
out:
|
||||
gnutls_pkcs12_deinit(pkcs12);
|
||||
err:
|
||||
if (rsa_key && (err || *df_type == DF_TYPE_UNKNOWN ||
|
||||
!have_thumbprint)) {
|
||||
if (!err)
|
||||
ntfs_log_error("Key type or thumbprint not found, "
|
||||
"aborting.\n");
|
||||
ntfs_rsa_private_key_release(rsa_key);
|
||||
rsa_key = NULL;
|
||||
}
|
||||
if (crt)
|
||||
gnutls_x509_crt_deinit(crt);
|
||||
if (pkey)
|
||||
gnutls_x509_privkey_deinit(pkey);
|
||||
if (bag)
|
||||
gnutls_pkcs12_bag_deinit(bag);
|
||||
if (pkcs12)
|
||||
gnutls_pkcs12_deinit(pkcs12);
|
||||
return rsa_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_rsa_private_key_release
|
||||
*/
|
||||
static void ntfs_rsa_private_key_release(ntfs_rsa_private_key rsa_key)
|
||||
{
|
||||
gcry_sexp_release((gcry_sexp_t)rsa_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_buffer_reverse -
|
||||
*
|
||||
|
@ -964,16 +1066,20 @@ static inline BOOL ntfs_des_test(void)
|
|||
/**
|
||||
* ntfs_fek_import_from_raw
|
||||
*/
|
||||
static ntfs_fek *ntfs_fek_import_from_raw(u8 *fek_buf,
|
||||
unsigned fek_size __attribute__((unused)))
|
||||
static ntfs_fek *ntfs_fek_import_from_raw(u8 *fek_buf, unsigned fek_size)
|
||||
{
|
||||
ntfs_fek *fek;
|
||||
u32 key_size, wanted_key_size, gcry_algo;
|
||||
gcry_error_t err;
|
||||
|
||||
// TODO: Sanity checking of sizes and offsets.
|
||||
key_size = le32_to_cpup(fek_buf);
|
||||
//ntfs_log_debug("key_size 0x%x\n", key_size);
|
||||
ntfs_log_debug("key_size 0x%x\n", key_size);
|
||||
if (key_size + 16 > fek_size) {
|
||||
ntfs_log_debug("Invalid FEK. It was probably decrypted with "
|
||||
"the incorrect RSA key.");
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
fek = malloc(((((sizeof(*fek) + 7) & ~7) + key_size + 7) & ~7) +
|
||||
sizeof(gcry_cipher_hd_t));
|
||||
if (!fek) {
|
||||
|
@ -1032,7 +1138,8 @@ static ntfs_fek *ntfs_fek_import_from_raw(u8 *fek_buf,
|
|||
}
|
||||
if (key_size != wanted_key_size) {
|
||||
ntfs_log_error("%s key of %u bytes but needed size is %u "
|
||||
"bytes, assuming corrupt key. Aborting.\n",
|
||||
"bytes, assuming corrupt or incorrect key. "
|
||||
"Aborting.\n",
|
||||
gcry_cipher_algo_name(gcry_algo),
|
||||
(unsigned)key_size, (unsigned)wanted_key_size);
|
||||
err = EIO;
|
||||
|
@ -1076,7 +1183,8 @@ static void ntfs_fek_release(ntfs_fek *fek)
|
|||
* ntfs_df_array_fek_get
|
||||
*/
|
||||
static ntfs_fek *ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER *df_array,
|
||||
ntfs_rsa_private_key rsa_key)
|
||||
ntfs_rsa_private_key rsa_key, char *thumbprint,
|
||||
int thumbprint_size)
|
||||
{
|
||||
EFS_DF_HEADER *df_header;
|
||||
EFS_DF_CREDENTIAL_HEADER *df_cred;
|
||||
|
@ -1086,14 +1194,41 @@ static ntfs_fek *ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER *df_array,
|
|||
u32 df_count, fek_size;
|
||||
unsigned i;
|
||||
|
||||
df_header = (EFS_DF_HEADER*)(df_array + 1);
|
||||
df_count = le32_to_cpu(df_array->df_count);
|
||||
for (i = 0; i < df_count; i++) {
|
||||
if (!df_count)
|
||||
ntfs_log_error("There are no elements in the DF array.\n");
|
||||
df_header = (EFS_DF_HEADER*)(df_array + 1);
|
||||
for (i = 0; i < df_count; i++, df_header = (EFS_DF_HEADER*)(
|
||||
(u8*)df_header + le32_to_cpu(df_header->df_length))) {
|
||||
df_cred = (EFS_DF_CREDENTIAL_HEADER*)((u8*)df_header +
|
||||
le32_to_cpu(df_header->cred_header_offset));
|
||||
if (df_cred->type != NTFS_CRED_TYPE_CERT_THUMBPRINT) {
|
||||
ntfs_log_debug("Credential type is not certificate "
|
||||
"thumbprint, skipping DF entry.\n");
|
||||
continue;
|
||||
}
|
||||
df_cert = (EFS_DF_CERT_THUMBPRINT_HEADER*)((u8*)df_cred +
|
||||
le32_to_cpu(
|
||||
df_cred->cert_thumbprint_header_offset));
|
||||
if (le32_to_cpu(df_cert->thumbprint_size) != thumbprint_size) {
|
||||
ntfs_log_error("Thumbprint size %d is not valid "
|
||||
"(should be %d), skipping this DF "
|
||||
"entry.\n",
|
||||
le32_to_cpu(df_cert->thumbprint_size),
|
||||
thumbprint_size);
|
||||
continue;
|
||||
}
|
||||
if (memcmp((u8*)df_cert +
|
||||
le32_to_cpu(df_cert->thumbprint_offset),
|
||||
thumbprint, thumbprint_size)) {
|
||||
ntfs_log_debug("Thumbprints do not match, skipping "
|
||||
"this DF entry.\n");
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* The thumbprints match so this is probably the DF entry
|
||||
* matching the RSA key. Try to decrypt the FEK with it.
|
||||
*/
|
||||
fek_size = le32_to_cpu(df_header->fek_size);
|
||||
fek_buf = (u8*)df_header + le32_to_cpu(df_header->fek_offset);
|
||||
/* Decrypt the FEK. Note: This is done in place. */
|
||||
|
@ -1108,8 +1243,6 @@ static ntfs_fek *ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER *df_array,
|
|||
} else
|
||||
ntfs_log_error("Failed to decrypt the file "
|
||||
"encryption key.\n");
|
||||
df_header = (EFS_DF_HEADER*)((u8*)df_header +
|
||||
le32_to_cpu(df_header->df_length));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1118,10 +1251,11 @@ static ntfs_fek *ntfs_df_array_fek_get(EFS_DF_ARRAY_HEADER *df_array,
|
|||
* ntfs_inode_fek_get -
|
||||
*/
|
||||
static ntfs_fek *ntfs_inode_fek_get(ntfs_inode *inode,
|
||||
ntfs_rsa_private_key rsa_key)
|
||||
ntfs_rsa_private_key rsa_key, char *thumbprint,
|
||||
int thumbprint_size, NTFS_DF_TYPES df_type)
|
||||
{
|
||||
EFS_ATTR_HEADER *efs;
|
||||
EFS_DF_ARRAY_HEADER *df_array;
|
||||
EFS_DF_ARRAY_HEADER *df_array = NULL;
|
||||
ntfs_fek *fek = NULL;
|
||||
|
||||
/* Obtain the $EFS contents. */
|
||||
|
@ -1130,17 +1264,29 @@ static ntfs_fek *ntfs_inode_fek_get(ntfs_inode *inode,
|
|||
ntfs_log_perror("Failed to read $EFS attribute");
|
||||
return NULL;
|
||||
}
|
||||
/* Iterate through the DDFs & DRFs until we obtain a key. */
|
||||
if (efs->offset_to_ddf_array) {
|
||||
df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
|
||||
le32_to_cpu(efs->offset_to_ddf_array));
|
||||
fek = ntfs_df_array_fek_get(df_array, rsa_key);
|
||||
}
|
||||
if (!fek && efs->offset_to_drf_array) {
|
||||
df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
|
||||
le32_to_cpu(efs->offset_to_drf_array));
|
||||
fek = ntfs_df_array_fek_get(df_array, rsa_key);
|
||||
}
|
||||
/*
|
||||
* Depending on whether the key is a normal key or a data recovery key,
|
||||
* iterate through the DDF or DRF array, respectively.
|
||||
*/
|
||||
if (df_type == DF_TYPE_DDF) {
|
||||
if (efs->offset_to_ddf_array)
|
||||
df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
|
||||
le32_to_cpu(efs->offset_to_ddf_array));
|
||||
else
|
||||
ntfs_log_error("There are no entries in the DDF "
|
||||
"array.\n");
|
||||
} else if (df_type == DF_TYPE_DRF) {
|
||||
if (efs->offset_to_drf_array)
|
||||
df_array = (EFS_DF_ARRAY_HEADER*)((u8*)efs +
|
||||
le32_to_cpu(efs->offset_to_drf_array));
|
||||
else
|
||||
ntfs_log_error("There are no entries in the DRF "
|
||||
"array.\n");
|
||||
} else
|
||||
ntfs_log_error("Invalid DF type.\n");
|
||||
if (df_array)
|
||||
fek = ntfs_df_array_fek_get(df_array, rsa_key, thumbprint,
|
||||
thumbprint_size);
|
||||
free(efs);
|
||||
return fek;
|
||||
}
|
||||
|
@ -1267,6 +1413,8 @@ int main(int argc, char *argv[])
|
|||
ntfs_fek *fek;
|
||||
unsigned pfx_size;
|
||||
int res;
|
||||
NTFS_DF_TYPES df_type;
|
||||
char thumbprint[NTFS_SHA1_THUMBPRINT_SIZE];
|
||||
|
||||
ntfs_log_set_handler(ntfs_log_handler_stderr);
|
||||
|
||||
|
@ -1295,14 +1443,14 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
/* Obtain the user's private RSA key from the key file. */
|
||||
rsa_key = ntfs_pkcs12_extract_rsa_key(pfx_buf, pfx_size, password);
|
||||
rsa_key = ntfs_pkcs12_extract_rsa_key(pfx_buf, pfx_size, password,
|
||||
thumbprint, sizeof(thumbprint), &df_type);
|
||||
/* Destroy the password. */
|
||||
memset(password, 0, strlen(password));
|
||||
/* No longer need the pfx file contents. */
|
||||
free(pfx_buf);
|
||||
if (!rsa_key) {
|
||||
ntfs_log_error("Failed to extract the private RSA key. Did "
|
||||
"you perhaps mistype the password?\n");
|
||||
ntfs_log_error("Failed to extract the private RSA key.\n");
|
||||
ntfs_crypto_deinit();
|
||||
return 1;
|
||||
}
|
||||
|
@ -1328,7 +1476,8 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
/* Obtain the file encryption key of the encrypted file. */
|
||||
fek = ntfs_inode_fek_get(inode, rsa_key);
|
||||
fek = ntfs_inode_fek_get(inode, rsa_key, thumbprint,
|
||||
sizeof(thumbprint), df_type);
|
||||
ntfs_rsa_private_key_release(rsa_key);
|
||||
if (fek) {
|
||||
res = ntfs_cat_decrypt(inode, fek);
|
||||
|
|
Loading…
Reference in New Issue