-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathrsa.c
99 lines (93 loc) · 3.26 KB
/
rsa.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* ==========================================================================
* rsa.c
*
* RSA-specific methods for Interrogate. Parses DER-encoded blobs and ouputs
* to file in the format privkey-00x.der
*
* Author: Carsten Maartmann-Moe <[email protected]>
* ==========================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include "interrogate.h"
/* Perform basic structural check on possible DER-encoded private key.
* Returns 0 if invalid, and the length of the DER blob if it is valid. Also
* prints some info about the key.
*/
int parse_der(unsigned char *buffer, int offset) {
if (buffer[offset + 4] == 0x02 &&
buffer[offset + 5] == 0x01 &&
buffer[offset + 6] == 0x00 &&
buffer[offset + 7] == 0x02) {
int length = (buffer[offset+2] << 8) |
(unsigned char) buffer[offset+3];
int end = 4 + length;
int pub_exp_field_length = 0;
int modlength, asn1length = (unsigned char) buffer[offset + 8];
if ((asn1length & 0x80) == 0) {
modlength = asn1length;
pub_exp_field_length = 1;
} else {
int numbytes = asn1length & 0x7F;
if (numbytes <= 8) {
int i;
pub_exp_field_length = 1 + numbytes;
modlength = (unsigned char) buffer[offset + 9];
for (i = 1; i < numbytes; i++) {
modlength = (modlength << 8) |
(unsigned char) buffer[offset + 9 + i];
}
} else {
printf("Found modulus length > 64 bits, this is not "
"supported.");
return 0;
}
}
int pub_exp_offset = offset + 8 + pub_exp_field_length + modlength;
int pub_exp = 0;
if (buffer[pub_exp_offset] == 0x02) {
if (buffer[pub_exp_offset + 1] == 0x01 &&
buffer[pub_exp_offset + 2] == 0x01) {
pub_exp = 1;
} else if (buffer[pub_exp_offset + 1] == 0x03 &&
buffer[pub_exp_offset + 2] == 0x01 &&
buffer[pub_exp_offset + 3] == 0x00 &&
buffer[pub_exp_offset + 4] == 0x01) {
pub_exp = 65537;
} else {
printf("Could not find public exponent, not a valid "
"key.\n");
return 0;
}
}
if (pub_exp != 0) {
printf("%08x: Key: %i bits, public exponent %i.\n", offset,
(modlength - 1) * 8, pub_exp);
return end;
} else {
return 0;
}
} else {
#if DEGUG
printf("Invalid key found.");
#endif
return 0;
}
}
/*
* Output DER information at offset 'offs'.
*/
void output_der(unsigned char *buffer, int offs, size_t size, long *count) {
char filename[15];
sprintf(filename, "privkey-%02li.der", *count);
FILE *fp = fopen(filename, "wb");
if (fp == NULL) {
perror("fopen()");
fprintf(stderr, "Failed to open %s.\n", filename);
exit(-1);
} else {
fwrite(&buffer[offs], 1, size, fp);
printf("Wrote key to file %s.\n", filename);
}
fclose(fp);
}