2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
42 #include <krb5-types.h>
43 #include <rfc2459_asn1.h>
52 return RSA_new_method(NULL
);
56 RSA_new_method(ENGINE
*engine
)
60 rsa
= calloc(1, sizeof(*rsa
));
67 ENGINE_up_ref(engine
);
70 rsa
->engine
= ENGINE_get_default_RSA();
74 rsa
->meth
= ENGINE_get_RSA(rsa
->engine
);
75 if (rsa
->meth
== NULL
) {
76 ENGINE_finish(engine
);
82 if (rsa
->meth
== NULL
)
83 rsa
->meth
= rk_UNCONST(RSA_get_default_method());
85 (*rsa
->meth
->init
)(rsa
);
94 if (rsa
->references
<= 0)
97 if (--rsa
->references
> 0)
100 (*rsa
->meth
->finish
)(rsa
);
103 ENGINE_finish(rsa
->engine
);
105 #define free_if(f) if (f) { BN_free(f); }
116 memset(rsa
, 0, sizeof(*rsa
));
123 return ++rsa
->references
;
127 RSA_get_method(const RSA
*rsa
)
133 RSA_set_method(RSA
*rsa
, const RSA_METHOD
*method
)
135 (*rsa
->meth
->finish
)(rsa
);
138 ENGINE_finish(rsa
->engine
);
143 (*rsa
->meth
->init
)(rsa
);
148 RSA_set_app_data(RSA
*rsa
, void *arg
)
150 rsa
->ex_data
.sk
= arg
;
155 RSA_get_app_data(RSA
*rsa
)
157 return rsa
->ex_data
.sk
;
161 RSA_check_key(const RSA
*key
)
163 static const unsigned char inbuf
[] = "hello, world!";
164 RSA
*rsa
= rk_UNCONST(key
);
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.
174 if ((rsa
->d
== NULL
|| rsa
->n
== NULL
) &&
175 (rsa
->p
== NULL
|| rsa
->q
|| rsa
->dmp1
== NULL
|| rsa
->dmq1
== NULL
|| rsa
->iqmp
== NULL
))
178 buffer
= malloc(RSA_size(rsa
));
182 ret
= RSA_private_encrypt(sizeof(inbuf
), inbuf
, buffer
,
183 rsa
, RSA_PKCS1_PADDING
);
189 ret
= RSA_public_decrypt(ret
, buffer
, buffer
,
190 rsa
, RSA_PKCS1_PADDING
);
196 if (ret
== sizeof(inbuf
) && memcmp(buffer
, inbuf
, sizeof(inbuf
)) == 0) {
205 RSA_size(const RSA
*rsa
)
207 return BN_num_bytes(rsa
->n
);
210 #define RSAFUNC(name, body) \
212 name(int flen,const unsigned char* f, unsigned char* t, RSA* r, int p){\
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
))
223 RSA_sign(int type
, const unsigned char *from
, unsigned int flen
,
224 unsigned char *to
, unsigned int *tlen
, RSA
*rsa
)
230 RSA_verify(int type
, const unsigned char *from
, unsigned int flen
,
231 unsigned char *to
, unsigned int tlen
, RSA
*rsa
)
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
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)
252 RSA_generate_key_ex(RSA
*r
, int bits
, BIGNUM
*e
, BN_GENCB
*cb
)
254 if (r
->meth
->rsa_keygen
)
255 return (*r
->meth
->rsa_keygen
)(r
, bits
, e
, cb
);
265 null_rsa_init(RSA
*rsa
)
271 null_rsa_finish(RSA
*rsa
)
276 static const RSA_METHOD rsa_null_method
= {
278 null_rsa_public_encrypt
,
279 null_rsa_public_decrypt
,
280 null_rsa_private_encrypt
,
281 null_rsa_private_decrypt
,
293 RSA_null_method(void)
295 return &rsa_null_method
;
298 extern const RSA_METHOD hc_rsa_imath_method
;
299 static const RSA_METHOD
*default_rsa_method
= &hc_rsa_imath_method
;
302 RSA_get_default_method(void)
304 return default_rsa_method
;
308 RSA_set_default_method(const RSA_METHOD
*meth
)
310 default_rsa_method
= meth
;
318 heim_int2BN(const heim_integer
*i
)
322 bn
= BN_bin2bn(i
->data
, i
->length
, NULL
);
324 BN_set_negative(bn
, i
->negative
);
329 bn2heim_int(BIGNUM
*bn
, heim_integer
*integer
)
331 integer
->length
= BN_num_bytes(bn
);
332 integer
->data
= malloc(integer
->length
);
333 if (integer
->data
== NULL
) {
337 BN_bn2bin(bn
, integer
->data
);
338 integer
->negative
= BN_is_negative(bn
);
344 d2i_RSAPrivateKey(RSA
*rsa
, const unsigned char **pp
, size_t len
)
351 ret
= decode_RSAPrivateKey(*pp
, len
, &data
, &size
);
360 free_RSAPrivateKey(&data
);
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
);
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
)
386 i2d_RSAPrivateKey(RSA
*rsa
, unsigned char **pp
)
392 if (rsa
->n
== NULL
|| rsa
->e
== NULL
|| rsa
->d
== NULL
|| rsa
->p
== NULL
||
393 rsa
->q
== NULL
|| rsa
->dmp1
== NULL
|| rsa
->dmq1
== NULL
||
397 memset(&data
, 0, sizeof(data
));
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
);
408 free_RSAPrivateKey(&data
);
413 size
= length_RSAPrivateKey(&data
);
414 free_RSAPrivateKey(&data
);
419 ASN1_MALLOC_ENCODE(RSAPrivateKey
, p
, len
, &data
, &size
, ret
);
420 free_RSAPrivateKey(&data
);
426 memcpy(*pp
, p
, size
);
436 i2d_RSAPublicKey(RSA
*rsa
, unsigned char **pp
)
442 memset(&data
, 0, sizeof(data
));
444 if (bn2heim_int(rsa
->n
, &data
.modulus
) ||
445 bn2heim_int(rsa
->e
, &data
.publicExponent
))
447 free_RSAPublicKey(&data
);
452 size
= length_RSAPublicKey(&data
);
453 free_RSAPublicKey(&data
);
458 ASN1_MALLOC_ENCODE(RSAPublicKey
, p
, len
, &data
, &size
, ret
);
459 free_RSAPublicKey(&data
);
465 memcpy(*pp
, p
, size
);