xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c (revision c8da0e5fefd3800856b306200a18b2315c7fbb9f)
1 /*-
2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Alistair Crooks (agc@NetBSD.org)
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    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.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*
30  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31  * All rights reserved.
32  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33  * their moral rights under the UK Copyright Design and Patents Act 1988 to
34  * be recorded as the authors of this copyright work.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37  * use this file except in compliance with the License.
38  *
39  * You may obtain a copy of the License at
40  *     http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  *
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 
50 /** \file
51  */
52 #include "config.h"
53 
54 #ifdef HAVE_OPENSSL_MD5_H
55 #include <openssl/md5.h>
56 #endif
57 
58 #ifdef HAVE_OPENSSL_SHA_H
59 #include <openssl/sha.h>
60 #endif
61 
62 #ifdef HAVE_OPENSSL_DSA_H
63 #include <openssl/dsa.h>
64 #endif
65 
66 #ifdef HAVE_OPENSSL_RSA_H
67 #include <openssl/rsa.h>
68 #endif
69 
70 #ifdef HAVE_OPENSSL_ERR_H
71 #include <openssl/err.h>
72 #endif
73 
74 
75 #include <stdlib.h>
76 
77 /* Apple */
78 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
79 #undef MD5_DIGEST_LENGTH
80 #undef SHA_DIGEST_LENGTH
81 #define COMMON_DIGEST_FOR_OPENSSL	1
82 #include <CommonCrypto/CommonDigest.h>
83 #endif
84 
85 #include "crypto.h"
86 #include "keyring.h"
87 #include "readerwriter.h"
88 #include "netpgpdefs.h"
89 #include "keyring_local.h"
90 
91 
92 static void
93 test_seckey(const __ops_seckey_t * seckey)
94 {
95 	RSA            *test = RSA_new();
96 
97 	test->n = BN_dup(seckey->pubkey.key.rsa.n);
98 	test->e = BN_dup(seckey->pubkey.key.rsa.e);
99 
100 	test->d = BN_dup(seckey->key.rsa.d);
101 	test->p = BN_dup(seckey->key.rsa.p);
102 	test->q = BN_dup(seckey->key.rsa.q);
103 
104 	if (RSA_check_key(test) != 1) {
105 		(void) fprintf(stderr,
106 			"test_seckey: RSA_check_key failed\n");
107 	}
108 	RSA_free(test);
109 }
110 
111 static void
112 md5_init(__ops_hash_t * hash)
113 {
114 	if (hash->data) {
115 		(void) fprintf(stderr, "md5_init: hash data non-null\n");
116 	}
117 	hash->data = calloc(1, sizeof(MD5_CTX));
118 	MD5_Init(hash->data);
119 }
120 
121 static void
122 md5_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
123 {
124 	MD5_Update(hash->data, data, length);
125 }
126 
127 static unsigned
128 md5_finish(__ops_hash_t * hash, unsigned char *out)
129 {
130 	MD5_Final(out, hash->data);
131 	free(hash->data);
132 	hash->data = NULL;
133 	return 16;
134 }
135 
136 static __ops_hash_t md5 = {
137 	OPS_HASH_MD5,
138 	MD5_DIGEST_LENGTH,
139 	"MD5",
140 	md5_init,
141 	md5_add,
142 	md5_finish,
143 	NULL
144 };
145 
146 /**
147    \ingroup Core_Crypto
148    \brief Initialise to MD5
149    \param hash Hash to initialise
150 */
151 void
152 __ops_hash_md5(__ops_hash_t * hash)
153 {
154 	*hash = md5;
155 }
156 
157 static void
158 sha1_init(__ops_hash_t * hash)
159 {
160 	if (__ops_get_debug_level(__FILE__)) {
161 		fprintf(stderr, "***\n***\nsha1_init\n***\n");
162 	}
163 	if (hash->data) {
164 		(void) fprintf(stderr, "sha1_init: hash data non-null\n");
165 	}
166 	hash->data = calloc(1, sizeof(SHA_CTX));
167 	SHA1_Init(hash->data);
168 }
169 
170 static void
171 sha1_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
172 {
173 	if (__ops_get_debug_level(__FILE__)) {
174 		unsigned int    i;
175 
176 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
177 		for (i = 0; i < length; i++) {
178 			(void) fprintf(stderr, "0x%02x ", data[i]);
179 			if (!((i + 1) % 16)) {
180 				(void) fprintf(stderr, "\n");
181 			} else if (!((i + 1) % 8)) {
182 				(void) fprintf(stderr, "  ");
183 			}
184 		}
185 		(void) fprintf(stderr, "\n");
186 	}
187 	SHA1_Update(hash->data, data, length);
188 }
189 
190 static unsigned
191 sha1_finish(__ops_hash_t * hash, unsigned char *out)
192 {
193 	SHA1_Final(out, hash->data);
194 	if (__ops_get_debug_level(__FILE__)) {
195 		unsigned        i;
196 
197 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
198 		for (i = 0; i < OPS_SHA1_HASH_SIZE; i++)
199 			(void) fprintf(stderr, "0x%02x ", out[i]);
200 		(void) fprintf(stderr, "\n");
201 	}
202 	(void) free(hash->data);
203 	hash->data = NULL;
204 	return OPS_SHA1_HASH_SIZE;
205 }
206 
207 static __ops_hash_t sha1 = {
208 	OPS_HASH_SHA1,
209 	OPS_SHA1_HASH_SIZE,
210 	"SHA1",
211 	sha1_init,
212 	sha1_add,
213 	sha1_finish,
214 	NULL
215 };
216 
217 /**
218    \ingroup Core_Crypto
219    \brief Initialise to SHA1
220    \param hash Hash to initialise
221 */
222 void
223 __ops_hash_sha1(__ops_hash_t * hash)
224 {
225 	*hash = sha1;
226 }
227 
228 static void
229 sha256_init(__ops_hash_t * hash)
230 {
231 	if (__ops_get_debug_level(__FILE__)) {
232 		fprintf(stderr, "***\n***\nsha256_init\n***\n");
233 	}
234 	if (hash->data) {
235 		(void) fprintf(stderr, "sha256_init: hash data non-null\n");
236 	}
237 	hash->data = calloc(1, sizeof(SHA256_CTX));
238 	SHA256_Init(hash->data);
239 }
240 
241 static void
242 sha256_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
243 {
244 	if (__ops_get_debug_level(__FILE__)) {
245 		unsigned int    i;
246 
247 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
248 		for (i = 0; i < length; i++) {
249 			(void) fprintf(stderr, "0x%02x ", data[i]);
250 			if (!((i + 1) % 16))
251 				(void) fprintf(stderr, "\n");
252 			else if (!((i + 1) % 8))
253 				(void) fprintf(stderr, "  ");
254 		}
255 		(void) fprintf(stderr, "\n");
256 	}
257 	SHA256_Update(hash->data, data, length);
258 }
259 
260 static unsigned
261 sha256_finish(__ops_hash_t * hash, unsigned char *out)
262 {
263 	SHA256_Final(out, hash->data);
264 	if (__ops_get_debug_level(__FILE__)) {
265 		unsigned        i;
266 
267 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
268 		for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
269 			(void) fprintf(stderr, "0x%02x ", out[i]);
270 		(void) fprintf(stderr, "\n");
271 	}
272 	(void) free(hash->data);
273 	hash->data = NULL;
274 	return SHA256_DIGEST_LENGTH;
275 }
276 
277 static __ops_hash_t sha256 = {
278 	OPS_HASH_SHA256,
279 	SHA256_DIGEST_LENGTH,
280 	"SHA256",
281 	sha256_init,
282 	sha256_add,
283 	sha256_finish,
284 	NULL
285 };
286 
287 void
288 __ops_hash_sha256(__ops_hash_t *hash)
289 {
290 	*hash = sha256;
291 }
292 
293 /*
294  * SHA384
295  */
296 static void
297 sha384_init(__ops_hash_t *hash)
298 {
299 	if (__ops_get_debug_level(__FILE__)) {
300 		(void) fprintf(stderr, "***\n***\nsha384_init\n***\n");
301 	}
302 	if (hash->data) {
303 		(void) fprintf(stderr, "sha384_init: hash data non-null\n");
304 	}
305 	hash->data = calloc(1, sizeof(SHA512_CTX));
306 	SHA384_Init(hash->data);
307 }
308 
309 static void
310 sha384_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
311 {
312 	if (__ops_get_debug_level(__FILE__)) {
313 		unsigned int    i;
314 
315 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
316 		for (i = 0; i < length; i++) {
317 			(void) fprintf(stderr, "0x%02x ", data[i]);
318 			if (!((i + 1) % 16))
319 				(void) fprintf(stderr, "\n");
320 			else if (!((i + 1) % 8))
321 				(void) fprintf(stderr, "  ");
322 		}
323 		(void) fprintf(stderr, "\n");
324 	}
325 	SHA384_Update(hash->data, data, length);
326 }
327 
328 static unsigned
329 sha384_finish(__ops_hash_t * hash, unsigned char *out)
330 {
331 	SHA384_Final(out, hash->data);
332 	if (__ops_get_debug_level(__FILE__)) {
333 		unsigned        i;
334 
335 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
336 		for (i = 0; i < SHA384_DIGEST_LENGTH; i++)
337 			(void) fprintf(stderr, "0x%02x ", out[i]);
338 		(void) fprintf(stderr, "\n");
339 	}
340 	(void) free(hash->data);
341 	hash->data = NULL;
342 	return SHA384_DIGEST_LENGTH;
343 }
344 
345 static __ops_hash_t sha384 = {
346 	OPS_HASH_SHA384,
347 	SHA384_DIGEST_LENGTH,
348 	"SHA384",
349 	sha384_init,
350 	sha384_add,
351 	sha384_finish,
352 	NULL
353 };
354 
355 void
356 __ops_hash_sha384(__ops_hash_t *hash)
357 {
358 	*hash = sha384;
359 }
360 
361 /*
362  * SHA512
363  */
364 static void
365 sha512_init(__ops_hash_t * hash)
366 {
367 	if (__ops_get_debug_level(__FILE__)) {
368 		(void) fprintf(stderr, "***\n***\nsha512_init\n***\n");
369 	}
370 	if (hash->data) {
371 		(void) fprintf(stderr, "sha512_init: hash data non-null\n");
372 	}
373 	hash->data = calloc(1, sizeof(SHA512_CTX));
374 	SHA512_Init(hash->data);
375 }
376 
377 static void
378 sha512_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
379 {
380 	if (__ops_get_debug_level(__FILE__)) {
381 		unsigned int    i;
382 
383 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
384 		for (i = 0; i < length; i++) {
385 			(void) fprintf(stderr, "0x%02x ", data[i]);
386 			if (!((i + 1) % 16))
387 				(void) fprintf(stderr, "\n");
388 			else if (!((i + 1) % 8))
389 				(void) fprintf(stderr, "  ");
390 		}
391 		(void) fprintf(stderr, "\n");
392 	}
393 	SHA512_Update(hash->data, data, length);
394 }
395 
396 static unsigned
397 sha512_finish(__ops_hash_t * hash, unsigned char *out)
398 {
399 	SHA512_Final(out, hash->data);
400 	if (__ops_get_debug_level(__FILE__)) {
401 		unsigned        i;
402 
403 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
404 		for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
405 			(void) fprintf(stderr, "0x%02x ", out[i]);
406 		(void) fprintf(stderr, "\n");
407 	}
408 	(void) free(hash->data);
409 	hash->data = NULL;
410 	return SHA512_DIGEST_LENGTH;
411 }
412 
413 static __ops_hash_t sha512 = {
414 	OPS_HASH_SHA512,
415 	SHA512_DIGEST_LENGTH,
416 	"SHA512",
417 	sha512_init,
418 	sha512_add,
419 	sha512_finish,
420 	NULL
421 };
422 
423 void
424 __ops_hash_sha512(__ops_hash_t * hash)
425 {
426 	*hash = sha512;
427 }
428 
429 /*
430  * SHA224
431  */
432 
433 static void
434 sha224_init(__ops_hash_t * hash)
435 {
436 	if (__ops_get_debug_level(__FILE__)) {
437 		(void) fprintf(stderr, "***\n***\nsha1_init\n***\n");
438 	}
439 	if (hash->data) {
440 		(void) fprintf(stderr, "sha224_init: hash data non-null\n");
441 	}
442 	hash->data = calloc(1, sizeof(SHA256_CTX));
443 	SHA224_Init(hash->data);
444 }
445 
446 static void
447 sha224_add(__ops_hash_t * hash, const unsigned char *data, unsigned length)
448 {
449 	if (__ops_get_debug_level(__FILE__)) {
450 		unsigned int    i;
451 
452 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
453 		for (i = 0; i < length; i++) {
454 			(void) fprintf(stderr, "0x%02x ", data[i]);
455 			if (!((i + 1) % 16))
456 				(void) fprintf(stderr, "\n");
457 			else if (!((i + 1) % 8))
458 				(void) fprintf(stderr, "  ");
459 		}
460 		(void) fprintf(stderr, "\n");
461 	}
462 	SHA224_Update(hash->data, data, length);
463 }
464 
465 static unsigned
466 sha224_finish(__ops_hash_t * hash, unsigned char *out)
467 {
468 	SHA224_Final(out, hash->data);
469 	if (__ops_get_debug_level(__FILE__)) {
470 		unsigned        i;
471 
472 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
473 		for (i = 0; i < SHA224_DIGEST_LENGTH; i++)
474 			(void) fprintf(stderr, "0x%02x ", out[i]);
475 		(void) fprintf(stderr, "\n");
476 	}
477 	(void) free(hash->data);
478 	hash->data = NULL;
479 	return SHA224_DIGEST_LENGTH;
480 }
481 
482 static __ops_hash_t sha224 = {
483 	OPS_HASH_SHA224,
484 	SHA224_DIGEST_LENGTH,
485 	"SHA224",
486 	sha224_init,
487 	sha224_add,
488 	sha224_finish,
489 	NULL
490 };
491 
492 void
493 __ops_hash_sha224(__ops_hash_t * hash)
494 {
495 	*hash = sha224;
496 }
497 
498 bool
499 __ops_dsa_verify(const unsigned char *hash, size_t hash_length,
500 	       const __ops_dsa_sig_t * sig,
501 	       const __ops_dsa_pubkey_t * dsa)
502 {
503 	DSA_SIG        *osig;
504 	DSA            *odsa;
505 	int             ret;
506 	unsigned int    qlen;
507 
508 	osig = DSA_SIG_new();
509 	osig->r = sig->r;
510 	osig->s = sig->s;
511 
512 	odsa = DSA_new();
513 	odsa->p = dsa->p;
514 	odsa->q = dsa->q;
515 	odsa->g = dsa->g;
516 	odsa->pub_key = dsa->y;
517 
518 	if (__ops_get_debug_level(__FILE__)) {
519 		unsigned        i;
520 
521 		(void) fprintf(stderr, "hash passed in:\n");
522 		for (i = 0; i < hash_length; i++) {
523 			(void) fprintf(stderr, "%02x ", hash[i]);
524 		}
525 		(void) fprintf(stderr, "\n");
526 		printf("hash_length=%" PRIsize "d\n", hash_length);
527 	}
528 	/* printf("Q=%d\n", BN_num_bytes(odsa->q)); */
529 	if ((qlen = BN_num_bytes(odsa->q)) < hash_length) {
530 		hash_length = qlen;
531 	}
532 	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
533 	if (__ops_get_debug_level(__FILE__)) {
534 		(void) fprintf(stderr, "ret=%d\n", ret);
535 	}
536 	if (ret < 0) {
537 		(void) fprintf(stderr,
538 			"__ops_do_verify: DSA_do_verify failed\n");
539 		return 0;
540 	}
541 
542 	odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
543 	DSA_free(odsa);
544 
545 	osig->r = osig->s = NULL;
546 	DSA_SIG_free(osig);
547 
548 	return ret != 0;
549 }
550 
551 /**
552    \ingroup Core_Crypto
553    \brief Recovers message digest from the signature
554    \param out Where to write decrypted data to
555    \param in Encrypted data
556    \param length Length of encrypted data
557    \param rsa RSA public key
558    \return size of recovered message digest
559 */
560 int
561 __ops_rsa_public_decrypt(unsigned char *out, const unsigned char *in,
562 		       size_t length, const __ops_rsa_pubkey_t * rsa)
563 {
564 	RSA            *orsa;
565 	int             n;
566 
567 	orsa = RSA_new();
568 	orsa->n = rsa->n;
569 	orsa->e = rsa->e;
570 
571 	n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
572 
573 	orsa->n = orsa->e = NULL;
574 	RSA_free(orsa);
575 
576 	return n;
577 }
578 
579 /**
580    \ingroup Core_Crypto
581    \brief Signs data with RSA
582    \param out Where to write signature
583    \param in Data to sign
584    \param length Length of data
585    \param srsa RSA secret key
586    \param rsa RSA public key
587    \return number of bytes decrypted
588 */
589 int
590 __ops_rsa_private_encrypt(unsigned char *out,
591 			const unsigned char *in,
592 			size_t length,
593 			const __ops_rsa_seckey_t *srsa,
594 			const __ops_rsa_pubkey_t *rsa)
595 {
596 	RSA            *orsa;
597 	int             n;
598 
599 	orsa = RSA_new();
600 	orsa->n = rsa->n;	/* XXX: do we need n? */
601 	orsa->d = srsa->d;
602 	orsa->p = srsa->q;
603 	orsa->q = srsa->p;
604 
605 	/* debug */
606 	orsa->e = rsa->e;
607 	/* If this isn't set, it's very likely that the programmer hasn't */
608 	/* decrypted the secret key. RSA_check_key segfaults in that case. */
609 	/* Use __ops_decrypt_seckey() to do that. */
610 	if (orsa->d == NULL) {
611 		(void) fprintf(stderr, "orsa is not set\n");
612 		return 0;
613 	}
614 	if (RSA_check_key(orsa) != 1) {
615 		(void) fprintf(stderr, "RSA_check_key is not set\n");
616 		return 0;
617 	}
618 	/* end debug */
619 
620 	n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
621 
622 	orsa->n = orsa->d = orsa->p = orsa->q = NULL;
623 	RSA_free(orsa);
624 
625 	return n;
626 }
627 
628 /**
629 \ingroup Core_Crypto
630 \brief Decrypts RSA-encrypted data
631 \param out Where to write the plaintext
632 \param in Encrypted data
633 \param length Length of encrypted data
634 \param srsa RSA secret key
635 \param rsa RSA public key
636 \return size of recovered plaintext
637 */
638 int
639 __ops_rsa_private_decrypt(unsigned char *out, const unsigned char *in,
640 			size_t length, const __ops_rsa_seckey_t * srsa,
641 			const __ops_rsa_pubkey_t * rsa)
642 {
643 	RSA            *orsa;
644 	int             n;
645 	char            errbuf[1024];
646 
647 	orsa = RSA_new();
648 	orsa->n = rsa->n;	/* XXX: do we need n? */
649 	orsa->d = srsa->d;
650 	orsa->p = srsa->q;
651 	orsa->q = srsa->p;
652 
653 	/* debug */
654 	orsa->e = rsa->e;
655 	if (RSA_check_key(orsa) != 1) {
656 		(void) fprintf(stderr, "RSA_check_key is not set\n");
657 		return 0;
658 	}
659 	/* end debug */
660 
661 	n = RSA_private_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
662 
663 	if (__ops_get_debug_level(__FILE__)) {
664 		printf("__ops_rsa_private_decrypt: n=%d\n",n);
665 	}
666 
667 	errbuf[0] = '\0';
668 	if (n == -1) {
669 		unsigned long   err = ERR_get_error();
670 		ERR_error_string(err, &errbuf[0]);
671 		fprintf(stderr, "openssl error : %s\n", errbuf);
672 	}
673 	orsa->n = orsa->d = orsa->p = orsa->q = NULL;
674 	RSA_free(orsa);
675 
676 	return n;
677 }
678 
679 /**
680    \ingroup Core_Crypto
681    \brief RSA-encrypts data
682    \param out Where to write the encrypted data
683    \param in Plaintext
684    \param length Size of plaintext
685    \param rsa RSA Public Key
686 */
687 int
688 __ops_rsa_public_encrypt(unsigned char *out,
689 			const unsigned char *in,
690 			size_t length,
691 			const __ops_rsa_pubkey_t *rsa)
692 {
693 	RSA            *orsa;
694 	int             n;
695 
696 	/* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */
697 
698 	orsa = RSA_new();
699 	orsa->n = rsa->n;
700 	orsa->e = rsa->e;
701 
702 	/* printf("len: %ld\n", length); */
703 	/* __ops_print_bn("n: ", orsa->n); */
704 	/* __ops_print_bn("e: ", orsa->e); */
705 	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
706 
707 	if (n == -1) {
708 		BIO            *fd_out;
709 
710 		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
711 		ERR_print_errors(fd_out);
712 	}
713 	orsa->n = orsa->e = NULL;
714 	RSA_free(orsa);
715 
716 	return n;
717 }
718 
719 /**
720    \ingroup Core_Crypto
721    \brief initialises openssl
722    \note Would usually call __ops_init() instead
723    \sa __ops_init()
724 */
725 void
726 __ops_crypto_init()
727 {
728 #ifdef DMALLOC
729 	CRYPTO_malloc_debug_init();
730 	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
731 	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
732 #endif
733 }
734 
735 /**
736    \ingroup Core_Crypto
737    \brief Finalise openssl
738    \note Would usually call __ops_finish() instead
739    \sa __ops_finish()
740 */
741 void
742 __ops_crypto_finish()
743 {
744 	CRYPTO_cleanup_all_ex_data();
745 	ERR_remove_state((unsigned long)0);
746 #ifdef DMALLOC
747 	CRYPTO_mem_leaks_fp(stderr);
748 #endif
749 }
750 
751 /**
752    \ingroup Core_Hashes
753    \brief Get Hash name
754    \param hash Hash struct
755    \return Hash name
756 */
757 const char     *
758 __ops_text_from_hash(__ops_hash_t * hash)
759 {
760 	return hash->name;
761 }
762 
763 /**
764  \ingroup HighLevel_KeyGenerate
765  \brief Generates an RSA keypair
766  \param numbits Modulus size
767  \param e Public Exponent
768  \param keydata Pointer to keydata struct to hold new key
769  \return true if key generated successfully; otherwise false
770  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
771 */
772 bool
773 __ops_rsa_generate_keypair(const int numbits,
774 			const unsigned long e,
775 			__ops_keydata_t *keydata)
776 {
777 	__ops_seckey_t *seckey = NULL;
778 	RSA            *rsa = NULL;
779 	BN_CTX         *ctx = BN_CTX_new();
780 	__ops_createinfo_t *cinfo;
781 	__ops_memory_t   *mem;
782 
783 	__ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY);
784 	seckey = __ops_get_writable_seckey(keydata);
785 
786 	/* generate the key pair */
787 
788 	rsa = RSA_generate_key(numbits, e, NULL, NULL);
789 
790 	/* populate __ops key from ssl key */
791 
792 	seckey->pubkey.version = 4;
793 	seckey->pubkey.birthtime = time(NULL);
794 	seckey->pubkey.days_valid = 0;
795 	seckey->pubkey.alg = OPS_PKA_RSA;
796 
797 	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
798 	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
799 
800 	seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED;
801 	seckey->s2k_specifier = OPS_S2KS_SALTED;
802 	/* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */
803 	seckey->alg = OPS_SA_CAST5;	/* \todo make param */
804 	seckey->hash_alg = OPS_HASH_SHA1;	/* \todo make param */
805 	seckey->octetc = 0;
806 	seckey->checksum = 0;
807 
808 	seckey->key.rsa.d = BN_dup(rsa->d);
809 	seckey->key.rsa.p = BN_dup(rsa->p);
810 	seckey->key.rsa.q = BN_dup(rsa->q);
811 	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
812 	if (seckey->key.rsa.u == NULL) {
813 		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
814 		return 0;
815 	}
816 	BN_CTX_free(ctx);
817 
818 	RSA_free(rsa);
819 
820 	__ops_keyid(keydata->key_id, OPS_KEY_ID_SIZE, OPS_KEY_ID_SIZE,
821 			&keydata->key.seckey.pubkey);
822 	__ops_fingerprint(&keydata->fingerprint, &keydata->key.seckey.pubkey);
823 
824 	/* Generate checksum */
825 
826 	cinfo = NULL;
827 	mem = NULL;
828 
829 	__ops_setup_memory_write(&cinfo, &mem, 128);
830 
831 	__ops_push_skey_checksum_writer(cinfo, seckey);
832 
833 	switch (seckey->pubkey.alg) {
834 		/* case OPS_PKA_DSA: */
835 		/* return __ops_write_mpi(key->key.dsa.x,info); */
836 
837 	case OPS_PKA_RSA:
838 	case OPS_PKA_RSA_ENCRYPT_ONLY:
839 	case OPS_PKA_RSA_SIGN_ONLY:
840 		if (!__ops_write_mpi(seckey->key.rsa.d, cinfo) ||
841 		    !__ops_write_mpi(seckey->key.rsa.p, cinfo) ||
842 		    !__ops_write_mpi(seckey->key.rsa.q, cinfo) ||
843 		    !__ops_write_mpi(seckey->key.rsa.u, cinfo)) {
844 			return false;
845 		}
846 		break;
847 
848 		/* case OPS_PKA_ELGAMAL: */
849 		/* return __ops_write_mpi(key->key.elgamal.x,info); */
850 
851 	default:
852 		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
853 		return false;
854 	}
855 
856 	/* close rather than pop, since its the only one on the stack */
857 	__ops_writer_close(cinfo);
858 	__ops_teardown_memory_write(cinfo, mem);
859 
860 	/* should now have checksum in seckey struct */
861 
862 	/* test */
863 	if (__ops_get_debug_level(__FILE__)) {
864 		test_seckey(seckey);
865 	}
866 
867 	return true;
868 }
869 
870 /**
871  \ingroup HighLevel_KeyGenerate
872  \brief Creates a self-signed RSA keypair
873  \param numbits Modulus size
874  \param e Public Exponent
875  \param userid User ID
876  \return The new keypair or NULL
877 
878  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
879  \sa __ops_rsa_generate_keypair()
880  \sa __ops_keydata_free()
881 */
882 __ops_keydata_t  *
883 __ops_rsa_create_selfsigned_keypair(const int numbits,
884 			const unsigned long e,
885 			__ops_user_id_t *userid)
886 {
887 	__ops_keydata_t  *keydata = NULL;
888 
889 	keydata = __ops_keydata_new();
890 	if (__ops_rsa_generate_keypair(numbits, e, keydata) != true ||
891 	    __ops_add_selfsigned_userid_to_keydata(keydata, userid) != true) {
892 		__ops_keydata_free(keydata);
893 		return NULL;
894 	}
895 	return keydata;
896 }
897 
898 DSA_SIG        *
899 __ops_dsa_sign(unsigned char *hashbuf,
900 		unsigned hashsize,
901 		const __ops_dsa_seckey_t *sdsa,
902 		const __ops_dsa_pubkey_t *dsa)
903 {
904 	DSA_SIG        *dsasig;
905 	DSA            *odsa;
906 
907 	odsa = DSA_new();
908 	odsa->p = dsa->p;
909 	odsa->q = dsa->q;
910 	odsa->g = dsa->g;
911 	odsa->pub_key = dsa->y;
912 	odsa->priv_key = sdsa->x;
913 
914 	dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
915 
916 	odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
917 	DSA_free(odsa);
918 
919 	return dsasig;
920 }
921