radare2/libr/search/rsa-find.c
Fangrui Song c43e6880fb Refactor search (#8566)
* fix out-of-bounds read in r_search_strings_update
* Remove static variables searchhits maplist maxhits first_hit in cmd_search.c
* Change semantics of r_search_hit_new (update kw->count s->nhits in it), return 2 if search.maxhits is reached and stop searching immediately
* honor search.maxhits in r_search_regexp_update
* Refactor _cb_hit, remove bckwrds/do_bckwrd_srch and static cmdhit
* Fix mem leak in regexp.c
* Add support for /d (delta) /bd (backward + delta) when crossing blocksize boundaries
2017-09-20 17:00:18 +02:00

72 lines
1.8 KiB
C

// RSAKeyFinder 1.0 (2008-07-18)
// By Nadia Heninger and J. Alex Halderman
// Contribution to r2 by @santitox
// Integrated and refactored by jvoisin
#include <r_search.h>
/*Baby BER parser, just good enough for RSA keys.
This is not robust to errors in the memory image, but if we added
some entropy testing and intelligent guessing, it could be made to be.
Parses a single field of the key, beginning at start. Each field
consists of a type, a length, and a value. Puts the type of field
into type, the number of bytes into len, and returns a pointer to
the beginning of the value. */
static const ut8* parse_next_rsa_field(const ut8* start, ut32 *len) {
*len = 0;
if (!(start[1] & 128)) {
len = (ut32*)(start + 1);
return start + 2;
} else {
int i;
const int lensize = start[1] & 127;
for (i=0; i < lensize; i++)
*len = (*len << 8) | start[2+i];
return start + 2 + lensize;
}
}
// Check if `start` points to an ensemble of BER fields
static int check_rsa_fields(const ut8* start) {
#define NB_PRIV_FIELDS 10
ut32 len = 0;
int i;
// skip sequence field
ut8 const* ptr = parse_next_rsa_field (start, &len);
if (!len || len > 1024)
return false;
for (i = 0; i < NB_PRIV_FIELDS; i++)
if (!(ptr = parse_next_rsa_field (ptr, &len)))
return false;
return true;
}
// Finds and return index of private RSA key
R_API int r_search_rsa_update(RSearch* s, ut64 from, const ut8 *buf, int len) {
unsigned int i, k, index;
const ut8 versionmarker[] = {0x02, 0x01, 0x00, 0x02};
for (i = 0; i < len - sizeof (versionmarker); i++) {
if (memcmp (&buf[i], versionmarker, sizeof (versionmarker)))
continue;
index = 0;
for (k=i; k != 0 && k > i - 20; k--) {
if (buf[k] == '0'){ // The sequence identifier is '0'
index = k;
break;
}
}
if (!index)
continue;
if (check_rsa_fields(buf + index))
return i;
}
return -1;
}