Skip to content

Commit 67aaeec

Browse files
committed
Keepass2john: Support newer format XML keyfile
The existing support was keyfile v1 only (meaning xml keyfile v1 of KeePass v2). This adds support for xml keyfile v2, tested with a v4 database.
1 parent f9bbdef commit 67aaeec

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

src/keepass2john.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ static void process_database(char* encryptedDatabase)
847847
}
848848

849849
if (keyfile) {
850-
buffer = mem_alloc(filesize_keyfile * sizeof(char));
850+
buffer = mem_alloc(filesize_keyfile + 1);
851851
printf("*1*64*"); /* inline keyfile content or hash - always 32 bytes */
852852
if (fread(buffer, filesize_keyfile, 1, kfp) != 1) {
853853
warn("%s: Error: read failed: %s.",
@@ -857,20 +857,42 @@ static void process_database(char* encryptedDatabase)
857857

858858
/*
859859
* As in Keepass 2.x implementation:
860-
* if keyfile is an xml, get <Data> content
860+
* if keyfile is an Version 1 XML, get <Data> content in Base64
861+
* if keyfile is an Version 2 XML, get <Data> content in hex
861862
* if filesize_keyfile == 32 then assume byte_array
862863
* if filesize_keyfile == 64 then assume hex(byte_array)
863864
* else byte_array = sha256(keyfile_content)
864865
*/
866+
buffer[filesize_keyfile] = 0;
865867

866868
if (!memcmp((char*) buffer, "<?xml", 5) &&
869+
((p = strstr((char*) buffer, "<Version>1.0")) != NULL) &&
867870
((p = strstr((char*) buffer, "<Key>")) != NULL) &&
868871
((p = strstr(p, "<Data>")) != NULL)) {
869872
p += strlen("<Data>");
870873
data = p;
871874
p = strstr(p, "</Data>");
872875
printf ("%s", base64_convert_cp(data, e_b64_mime, p - data, b64_decoded, e_b64_hex, sizeof(b64_decoded), flg_Base64_NO_FLAGS, 0));
873876
}
877+
else if (!memcmp((char*)buffer, "<?xml", 5) &&
878+
((p = strstr((char*) buffer, "<Version>2.0")) != NULL) &&
879+
((p = strstr((char*)buffer, "<Data")) != NULL) &&
880+
(p = strchr(p, '>'))) {
881+
char hex[64 + 1];
882+
int hidx = 0;
883+
p++;
884+
while (hidx < 64 && p - (char*)buffer < filesize_keyfile) {
885+
if (*p >= '0' && *p <= 'F')
886+
hex[hidx++] = *p++;
887+
else if (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
888+
p++;
889+
else
890+
break;
891+
}
892+
hex[hidx] = 0;
893+
strlwr(hex);
894+
printf ("%s", hex);
895+
}
874896
else if (filesize_keyfile == 32)
875897
print_hex(buffer, filesize_keyfile);
876898
else if (filesize_keyfile == 64)

0 commit comments

Comments
 (0)