]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sshrsa.c
Added Pageant, a first-attempt PuTTY authentication agent
[PuTTY.git] / sshrsa.c
1 /*
2  * RSA implementation just sufficient for ssh client-side
3  * initialisation step
4  *
5  * Rewritten for more speed by Joris van Rantwijk, Jun 1999.
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #if defined TESTMODE || defined RSADEBUG
13 #ifndef DLVL
14 #define DLVL 10000
15 #endif
16 #define debug(x) bndebug(#x,x)
17 static int level = 0;
18 static void bndebug(char *name, Bignum b) {
19     int i;
20     int w = 50-level-strlen(name)-5*b[0];
21     if (level >= DLVL)
22         return;
23     if (w < 0) w = 0;
24     dprintf("%*s%s%*s", level, "", name, w, "");
25     for (i=b[0]; i>0; i--)
26         dprintf(" %04x", b[i]);
27     dprintf("\n");
28 }
29 #define dmsg(x) do {if(level<DLVL){dprintf("%*s",level,"");printf x;}} while(0)
30 #define enter(x) do { dmsg(x); level += 4; } while(0)
31 #define leave(x) do { level -= 4; dmsg(x); } while(0)
32 #else
33 #define debug(x)
34 #define dmsg(x)
35 #define enter(x)
36 #define leave(x)
37 #endif
38
39 #include "ssh.h"
40
41 int makekey(unsigned char *data, struct RSAKey *result,
42             unsigned char **keystr, int order) {
43     unsigned char *p = data;
44     int i;
45
46     result->bits = 0;
47     for (i=0; i<4; i++)
48         result->bits = (result->bits << 8) + *p++;
49
50     /*
51      * order=0 means exponent then modulus (the keys sent by the
52      * server). order=1 means modulus then exponent (the keys
53      * stored in a keyfile).
54      */
55
56     if (order == 0)
57         p += ssh1_read_bignum(p, &result->exponent);
58     result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
59     if (keystr) *keystr = p+2;
60     p += ssh1_read_bignum(p, &result->modulus);
61     if (order == 1)
62         p += ssh1_read_bignum(p, &result->exponent);
63
64     return p - data;
65 }
66
67 int makeprivate(unsigned char *data, struct RSAKey *result) {
68     return ssh1_read_bignum(data, &result->private_exponent);
69 }
70
71 void rsaencrypt(unsigned char *data, int length, struct RSAKey *key) {
72     Bignum b1, b2;
73     int w, i;
74     unsigned char *p;
75
76     debug(key->exponent);
77
78     memmove(data+key->bytes-length, data, length);
79     data[0] = 0;
80     data[1] = 2;
81
82     for (i = 2; i < key->bytes-length-1; i++) {
83         do {
84             data[i] = random_byte();
85         } while (data[i] == 0);
86     }
87     data[key->bytes-length-1] = 0;
88
89     w = (key->bytes+1)/2;
90
91     b1 = newbn(w);
92     b2 = newbn(w);
93
94     p = data;
95     for (i=1; i<=w; i++)
96         b1[i] = 0;
97     for (i=key->bytes; i-- ;) {
98         unsigned char byte = *p++;
99         if (i & 1)
100             b1[1+i/2] |= byte<<8;
101         else
102             b1[1+i/2] |= byte;
103     }
104
105     debug(b1);
106
107     modpow(b1, key->exponent, key->modulus, b2);
108
109     debug(b2);
110
111     p = data;
112     for (i=key->bytes; i-- ;) {
113         unsigned char b;
114         if (i & 1)
115             b = b2[1+i/2] >> 8;
116         else
117             b = b2[1+i/2] & 0xFF;
118         *p++ = b;
119     }
120
121     freebn(b1);
122     freebn(b2);
123 }
124
125 Bignum rsadecrypt(Bignum input, struct RSAKey *key) {
126     Bignum ret;
127     ret = newbn(key->modulus[0]);
128     modpow(input, key->private_exponent, key->modulus, ret);
129     return ret;
130 }
131
132 int rsastr_len(struct RSAKey *key) {
133     Bignum md, ex;
134
135     md = key->modulus;
136     ex = key->exponent;
137     return 4 * (ex[0]+md[0]) + 10;
138 }
139
140 void rsastr_fmt(char *str, struct RSAKey *key) {
141     Bignum md, ex;
142     int len = 0, i;
143
144     md = key->modulus;
145     ex = key->exponent;
146
147     for (i=1; i<=ex[0]; i++) {
148         sprintf(str+len, "%04x", ex[i]);
149         len += strlen(str+len);
150     }
151     str[len++] = '/';
152     for (i=1; i<=md[0]; i++) {
153         sprintf(str+len, "%04x", md[i]);
154         len += strlen(str+len);
155     }
156     str[len] = '\0';
157 }
158
159 void freersakey(struct RSAKey *key) {
160     if (key->modulus) freebn(key->modulus);
161     if (key->exponent) freebn(key->exponent);
162     if (key->private_exponent) freebn(key->private_exponent);
163     if (key->comment) free(key->comment);
164 }
165
166 #ifdef TESTMODE
167
168 #ifndef NODDY
169 #define p1 10007
170 #define p2 10069
171 #define p3 10177
172 #else
173 #define p1 3
174 #define p2 7
175 #define p3 13
176 #endif
177
178 unsigned short P1[2] = { 1, p1 };
179 unsigned short P2[2] = { 1, p2 };
180 unsigned short P3[2] = { 1, p3 };
181 unsigned short bigmod[5] = { 4, 0, 0, 0, 32768U };
182 unsigned short mod[5] = { 4, 0, 0, 0, 0 };
183 unsigned short a[5] = { 4, 0, 0, 0, 0 };
184 unsigned short b[5] = { 4, 0, 0, 0, 0 };
185 unsigned short c[5] = { 4, 0, 0, 0, 0 };
186 unsigned short One[2] = { 1, 1 };
187 unsigned short Two[2] = { 1, 2 };
188
189 int main(void) {
190     modmult(P1, P2, bigmod, a);   debug(a);
191     modmult(a, P3, bigmod, mod);  debug(mod);
192
193     sub(P1, One, a);              debug(a);
194     sub(P2, One, b);              debug(b);
195     modmult(a, b, bigmod, c);     debug(c);
196     sub(P3, One, a);              debug(a);
197     modmult(a, c, bigmod, b);     debug(b);
198
199     modpow(Two, b, mod, a);       debug(a);
200
201     return 0;
202 }
203
204 #endif