mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-05 03:56:46 +00:00
83 lines
1.9 KiB
C
83 lines
1.9 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};
|
|
|
|
if (len < sizeof (versionmarker)) {
|
|
return -1;
|
|
}
|
|
|
|
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;
|
|
}
|