-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathrsa2der.c
140 lines (116 loc) · 2.29 KB
/
rsa2der.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <openssl/rsa.h>
/* reverse an array in situ */
void
reverse(unsigned char *p, unsigned int len)
{
char temp;
int i, j;
for (i = 0, j = len - 1; i < j; i++, j--)
{
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
int
read_file(char *filename, unsigned char *buffer, unsigned int maxlen)
{
int fd, len;
fd = open(filename, O_RDONLY);
if (fd == -1)
{
perror(filename);
return -1;
}
len = read(fd, buffer, maxlen);
close(fd);
return len;
}
int
write_file(char *filename, unsigned char *buffer, unsigned int len)
{
int fd;
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1)
{
perror(filename);
return -1;
}
len = write(fd, buffer, len);
close(fd);
return len;
}
BIGNUM *
parse_bignum(unsigned char **buf, unsigned int len)
{
BIGNUM *bn;
reverse(*buf, len);
bn = BN_bin2bn(*buf, len, NULL);
*buf += len;
return bn;
}
RSA *
parse_rsa2(unsigned char *buf, unsigned int len)
{
RSA *rsa;
unsigned int modlen;
if (strncmp(buf, "RSA2", 4) != 0)
{
fprintf(stderr, "Not an RSA2 private key\n");
return NULL;
}
/* FIXME: should be a DWORD */
modlen = *(buf + 4);
if (len < (20 + (9 * modlen / 2)))
{
fprintf(stderr, "Input file truncated?\n");
return NULL;
}
buf += 16;
rsa = RSA_new();
if (rsa == NULL)
return NULL;
rsa->e = parse_bignum(&buf, 4);
rsa->n = parse_bignum(&buf, modlen);
rsa->p = parse_bignum(&buf, modlen / 2);
rsa->q = parse_bignum(&buf, modlen / 2);
rsa->dmp1 = parse_bignum(&buf, modlen / 2);
rsa->dmq1 = parse_bignum(&buf, modlen / 2);
rsa->iqmp = parse_bignum(&buf, modlen / 2);
rsa->d = parse_bignum(&buf, modlen);
return rsa;
}
int
main(int argc, char *argv[])
{
unsigned char buffer[1024];
unsigned char *p = buffer;
unsigned int len;
RSA *rsa;
if (argc < 3)
{
fprintf(stderr, "Usage: %s <infile> <outfile>\n", argv[0]);
return 0;
}
if ((len = read_file(argv[1], buffer, sizeof(buffer))) == -1)
{
fprintf(stderr, "Failed to read file\n");
return 1;
}
if ((rsa = parse_rsa2(buffer, len)) == NULL)
{
fprintf(stderr, "Failed to parse RSA key\n");
return 1;
}
len = i2d_RSAPrivateKey(rsa, &p);
if (write_file(argv[2], buffer, len) == -1)
{
fprintf(stderr, "Failed to write file\n");
return 1;
}
return 0;
}