r23456: Update Samba4 to current lorikeet-heimdal.
[sfrench/samba-autobuild/.git] / source / heimdal / lib / hcrypto / rsa.c
1 /*
2  * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden). 
4  * All rights reserved. 
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met: 
9  *
10  * 1. Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright 
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the distribution. 
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors 
18  *    may be used to endorse or promote products derived from this software 
19  *    without specific prior written permission. 
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
31  * SUCH DAMAGE. 
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 RCSID("$Id: rsa.c 20466 2007-04-20 08:29:05Z lha $");
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <krb5-types.h>
43 #include <rfc2459_asn1.h>
44
45 #include <rsa.h>
46
47 #include <roken.h>
48
49 RSA *
50 RSA_new(void)
51 {
52     return RSA_new_method(NULL);
53 }
54
55 RSA *
56 RSA_new_method(ENGINE *engine)
57 {
58     RSA *rsa;
59
60     rsa = calloc(1, sizeof(*rsa));
61     if (rsa == NULL)
62         return NULL;
63
64     rsa->references = 1;
65
66     if (engine) {
67         ENGINE_up_ref(engine);
68         rsa->engine = engine;
69     } else {
70         rsa->engine = ENGINE_get_default_RSA();
71     }
72
73     if (rsa->engine) {
74         rsa->meth = ENGINE_get_RSA(rsa->engine);
75         if (rsa->meth == NULL) {
76             ENGINE_finish(engine);
77             free(rsa);
78             return 0;
79         }
80     }
81
82     if (rsa->meth == NULL)
83         rsa->meth = rk_UNCONST(RSA_get_default_method());
84
85     (*rsa->meth->init)(rsa);
86
87     return rsa;
88 }
89
90
91 void
92 RSA_free(RSA *rsa)
93 {
94     if (rsa->references <= 0)
95         abort();
96
97     if (--rsa->references > 0)
98         return;
99
100     (*rsa->meth->finish)(rsa);
101
102     if (rsa->engine)
103         ENGINE_finish(rsa->engine);
104
105 #define free_if(f) if (f) { BN_free(f); }
106     free_if(rsa->n);
107     free_if(rsa->e);
108     free_if(rsa->d);
109     free_if(rsa->p);
110     free_if(rsa->q);
111     free_if(rsa->dmp1);
112     free_if(rsa->dmq1);
113     free_if(rsa->iqmp);
114 #undef free_if
115
116     memset(rsa, 0, sizeof(*rsa));
117     free(rsa);
118 }
119
120 int
121 RSA_up_ref(RSA *rsa)
122 {
123     return ++rsa->references;
124 }
125
126 const RSA_METHOD *
127 RSA_get_method(const RSA *rsa)
128 {
129     return rsa->meth;
130 }
131
132 int
133 RSA_set_method(RSA *rsa, const RSA_METHOD *method)
134 {
135     (*rsa->meth->finish)(rsa);
136
137     if (rsa->engine) {
138         ENGINE_finish(rsa->engine);
139         rsa->engine = NULL;
140     }
141
142     rsa->meth = method;
143     (*rsa->meth->init)(rsa);
144     return 1;
145 }
146
147 int
148 RSA_set_app_data(RSA *rsa, void *arg)
149 {
150     rsa->ex_data.sk = arg;
151     return 1;
152 }
153
154 void *
155 RSA_get_app_data(RSA *rsa)
156 {
157     return rsa->ex_data.sk;
158 }
159
160 int
161 RSA_check_key(const RSA *key)
162 {
163     static const unsigned char inbuf[] = "hello, world!";
164     RSA *rsa = rk_UNCONST(key);
165     void *buffer;
166     int ret;
167
168     /* 
169      * XXX I have no clue how to implement this w/o a bignum library.
170      * Well, when we have a RSA key pair, we can try to encrypt/sign
171      * and then decrypt/verify.
172      */
173
174     if ((rsa->d == NULL || rsa->n == NULL) &&
175         (rsa->p == NULL || rsa->q || rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL))
176         return 0;
177
178     buffer = malloc(RSA_size(rsa));
179     if (buffer == NULL)
180         return 0;
181     
182     ret = RSA_private_encrypt(sizeof(inbuf), inbuf, buffer, 
183                              rsa, RSA_PKCS1_PADDING);
184     if (ret == -1) {
185         free(buffer);
186         return 0;
187     }
188
189     ret = RSA_public_decrypt(ret, buffer, buffer,
190                               rsa, RSA_PKCS1_PADDING);
191     if (ret == -1) {
192         free(buffer);
193         return 0;
194     }
195
196     if (ret == sizeof(inbuf) && memcmp(buffer, inbuf, sizeof(inbuf)) == 0) {
197         free(buffer);
198         return 1;
199     }
200     free(buffer);
201     return 0; 
202 }
203
204 int
205 RSA_size(const RSA *rsa)
206 {
207     return BN_num_bytes(rsa->n);
208 }
209
210 #define RSAFUNC(name, body) \
211 int \
212 name(int flen,const unsigned char* f, unsigned char* t, RSA* r, int p){\
213     return body; \
214 }
215
216 RSAFUNC(RSA_public_encrypt, (r)->meth->rsa_pub_enc(flen, f, t, r, p))
217 RSAFUNC(RSA_public_decrypt, (r)->meth->rsa_pub_dec(flen, f, t, r, p))
218 RSAFUNC(RSA_private_encrypt, (r)->meth->rsa_priv_enc(flen, f, t, r, p))
219 RSAFUNC(RSA_private_decrypt, (r)->meth->rsa_priv_dec(flen, f, t, r, p))
220
221 /* XXX */
222 int
223 RSA_sign(int type, const unsigned char *from, unsigned int flen,
224          unsigned char *to, unsigned int *tlen, RSA *rsa)
225 {
226     return -1;
227 }
228
229 int
230 RSA_verify(int type, const unsigned char *from, unsigned int flen,
231            unsigned char *to, unsigned int tlen, RSA *rsa)
232 {
233     return -1;
234 }
235
236 /*
237  * A NULL RSA_METHOD that returns failure for all operations. This is
238  * used as the default RSA method if we don't have any native
239  * support.
240  */
241
242 static RSAFUNC(null_rsa_public_encrypt, -1)
243 static RSAFUNC(null_rsa_public_decrypt, -1)
244 static RSAFUNC(null_rsa_private_encrypt, -1)
245 static RSAFUNC(null_rsa_private_decrypt, -1)
246
247 /*
248  *
249  */
250
251 int
252 RSA_generate_key_ex(RSA *r, int bits, BIGNUM *e, BN_GENCB *cb)
253 {
254     if (r->meth->rsa_keygen)
255         return (*r->meth->rsa_keygen)(r, bits, e, cb);
256     return 0;
257 }
258
259
260 /*
261  *
262  */
263
264 static int 
265 null_rsa_init(RSA *rsa)
266 {
267     return 1;
268 }
269
270 static int
271 null_rsa_finish(RSA *rsa)
272 {
273     return 1;
274 }
275
276 static const RSA_METHOD rsa_null_method = {
277     "hcrypto null RSA",
278     null_rsa_public_encrypt,
279     null_rsa_public_decrypt,
280     null_rsa_private_encrypt,
281     null_rsa_private_decrypt,
282     NULL,
283     NULL,
284     null_rsa_init,
285     null_rsa_finish,
286     0,
287     NULL,
288     NULL,
289     NULL
290 };
291
292 const RSA_METHOD *
293 RSA_null_method(void)
294 {
295     return &rsa_null_method;
296 }
297
298 extern const RSA_METHOD hc_rsa_imath_method;
299 static const RSA_METHOD *default_rsa_method = &hc_rsa_imath_method;
300
301 const RSA_METHOD *
302 RSA_get_default_method(void)
303 {
304     return default_rsa_method;
305 }
306
307 void
308 RSA_set_default_method(const RSA_METHOD *meth)
309 {
310     default_rsa_method = meth;
311 }
312
313 /*
314  *
315  */
316
317 static BIGNUM *
318 heim_int2BN(const heim_integer *i)
319 {
320     BIGNUM *bn;
321
322     bn = BN_bin2bn(i->data, i->length, NULL);
323     if (bn)
324         BN_set_negative(bn, i->negative);
325     return bn;
326 }
327
328 static int
329 bn2heim_int(BIGNUM *bn, heim_integer *integer)
330 {
331     integer->length = BN_num_bytes(bn);
332     integer->data = malloc(integer->length);
333     if (integer->data == NULL) {
334         integer->length = 0;
335         return ENOMEM;
336     }
337     BN_bn2bin(bn, integer->data);
338     integer->negative = BN_is_negative(bn);
339     return 0;
340 }
341
342
343 RSA *
344 d2i_RSAPrivateKey(RSA *rsa, const unsigned char **pp, size_t len)
345 {
346     RSAPrivateKey data;
347     RSA *k = rsa;
348     size_t size;
349     int ret;
350
351     ret = decode_RSAPrivateKey(*pp, len, &data, &size);
352     if (ret)
353         return NULL;
354     
355     *pp += size;
356
357     if (k == NULL) {
358         k = RSA_new();
359         if (k == NULL) {
360             free_RSAPrivateKey(&data);
361             return NULL;
362         }
363     }
364
365     k->n = heim_int2BN(&data.modulus);
366     k->e = heim_int2BN(&data.publicExponent);
367     k->d = heim_int2BN(&data.privateExponent);
368     k->p = heim_int2BN(&data.prime1);
369     k->q = heim_int2BN(&data.prime2);
370     k->dmp1 = heim_int2BN(&data.exponent1);
371     k->dmq1 = heim_int2BN(&data.exponent2);
372     k->iqmp = heim_int2BN(&data.coefficient);
373     free_RSAPrivateKey(&data);
374
375     if (k->n == NULL || k->e == NULL || k->d == NULL || k->p == NULL ||
376         k->q == NULL || k->dmp1 == NULL || k->dmq1 == NULL || k->iqmp == NULL) 
377     {
378         RSA_free(k);
379         return NULL;
380     }
381         
382     return k;
383 }
384
385 int
386 i2d_RSAPrivateKey(RSA *rsa, unsigned char **pp)
387 {
388     RSAPrivateKey data;
389     size_t size;
390     int ret;
391
392     if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL || rsa->p == NULL ||
393         rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 == NULL ||
394         rsa->iqmp == NULL)
395         return -1;
396
397     memset(&data, 0, sizeof(data));
398
399     ret  = bn2heim_int(rsa->n, &data.modulus);
400     ret |= bn2heim_int(rsa->e, &data.publicExponent);
401     ret |= bn2heim_int(rsa->d, &data.privateExponent);
402     ret |= bn2heim_int(rsa->p, &data.prime1);
403     ret |= bn2heim_int(rsa->q, &data.prime2);
404     ret |= bn2heim_int(rsa->dmp1, &data.exponent1);
405     ret |= bn2heim_int(rsa->dmq1, &data.exponent2);
406     ret |= bn2heim_int(rsa->iqmp, &data.coefficient);
407     if (ret) {
408         free_RSAPrivateKey(&data);
409         return -1;
410     }
411
412     if (pp == NULL) {
413         size = length_RSAPrivateKey(&data);
414         free_RSAPrivateKey(&data);
415     } else {
416         void *p;
417         size_t len;
418
419         ASN1_MALLOC_ENCODE(RSAPrivateKey, p, len, &data, &size, ret);
420         free_RSAPrivateKey(&data);
421         if (ret)
422             return -1;
423         if (len != size)
424             abort();
425
426         memcpy(*pp, p, size);
427         free(p);
428
429         *pp += size;
430
431     }
432     return size;
433 }
434
435 int
436 i2d_RSAPublicKey(RSA *rsa, unsigned char **pp)
437 {
438     RSAPublicKey data;
439     size_t size;
440     int ret;
441
442     memset(&data, 0, sizeof(data));
443
444     if (bn2heim_int(rsa->n, &data.modulus) ||
445         bn2heim_int(rsa->e, &data.publicExponent))
446     {
447         free_RSAPublicKey(&data);
448         return -1;
449     }
450
451     if (pp == NULL) {
452         size = length_RSAPublicKey(&data);
453         free_RSAPublicKey(&data);
454     } else {
455         void *p;
456         size_t len;
457
458         ASN1_MALLOC_ENCODE(RSAPublicKey, p, len, &data, &size, ret);
459         free_RSAPublicKey(&data);
460         if (ret)
461             return -1;
462         if (len != size)
463             abort();
464     
465         memcpy(*pp, p, size);
466         free(p);
467
468         *pp += size;
469     }
470     
471     return size;
472 }