xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c (revision 520c968fd9f344d2ad067e2d118edfbbbada82f4)
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_SYS_CDEFS_H
55 #include <sys/cdefs.h>
56 #endif
57 
58 #if defined(__NetBSD__)
59 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
60 __RCSID("$NetBSD: openssl_crypto.c,v 1.25 2010/07/09 05:35:34 agc Exp $");
61 #endif
62 
63 #ifdef HAVE_OPENSSL_DSA_H
64 #include <openssl/dsa.h>
65 #endif
66 
67 #ifdef HAVE_OPENSSL_RSA_H
68 #include <openssl/rsa.h>
69 #endif
70 
71 #ifdef HAVE_OPENSSL_ERR_H
72 #include <openssl/err.h>
73 #endif
74 
75 #include <openssl/pem.h>
76 #include <openssl/evp.h>
77 
78 #include <stdlib.h>
79 #include <string.h>
80 /* Hash size for secret key check */
81 
82 #include "crypto.h"
83 #include "keyring.h"
84 #include "readerwriter.h"
85 #include "netpgpdefs.h"
86 #include "netpgpdigest.h"
87 #include "packet.h"
88 
89 
90 static void
91 test_seckey(const __ops_seckey_t *seckey)
92 {
93 	RSA            *test = RSA_new();
94 
95 	test->n = BN_dup(seckey->pubkey.key.rsa.n);
96 	test->e = BN_dup(seckey->pubkey.key.rsa.e);
97 
98 	test->d = BN_dup(seckey->key.rsa.d);
99 	test->p = BN_dup(seckey->key.rsa.p);
100 	test->q = BN_dup(seckey->key.rsa.q);
101 
102 	if (RSA_check_key(test) != 1) {
103 		(void) fprintf(stderr,
104 			"test_seckey: RSA_check_key failed\n");
105 	}
106 	RSA_free(test);
107 }
108 
109 static int
110 md5_init(__ops_hash_t *hash)
111 {
112 	if (hash->data) {
113 		(void) fprintf(stderr, "md5_init: hash data non-null\n");
114 	}
115 	if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) {
116 		(void) fprintf(stderr, "md5_init: bad alloc\n");
117 		return 0;
118 	}
119 	MD5_Init(hash->data);
120 	return 1;
121 }
122 
123 static void
124 md5_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
125 {
126 	MD5_Update(hash->data, data, length);
127 }
128 
129 static unsigned
130 md5_finish(__ops_hash_t *hash, uint8_t *out)
131 {
132 	MD5_Final(out, hash->data);
133 	free(hash->data);
134 	hash->data = NULL;
135 	return 16;
136 }
137 
138 static const __ops_hash_t md5 = {
139 	OPS_HASH_MD5,
140 	MD5_DIGEST_LENGTH,
141 	"MD5",
142 	md5_init,
143 	md5_add,
144 	md5_finish,
145 	NULL
146 };
147 
148 /**
149    \ingroup Core_Crypto
150    \brief Initialise to MD5
151    \param hash Hash to initialise
152 */
153 void
154 __ops_hash_md5(__ops_hash_t *hash)
155 {
156 	*hash = md5;
157 }
158 
159 static int
160 sha1_init(__ops_hash_t *hash)
161 {
162 	if (__ops_get_debug_level(__FILE__)) {
163 		fprintf(stderr, "***\n***\nsha1_init\n***\n");
164 	}
165 	if (hash->data) {
166 		(void) fprintf(stderr, "sha1_init: hash data non-null\n");
167 	}
168 	if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) {
169 		(void) fprintf(stderr, "sha1_init: bad alloc\n");
170 		return 0;
171 	}
172 	SHA1_Init(hash->data);
173 	return 1;
174 }
175 
176 static void
177 sha1_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
178 {
179 	if (__ops_get_debug_level(__FILE__)) {
180 		unsigned    i;
181 
182 		(void) fprintf(stderr, "adding %u to hash:\n ", length);
183 		for (i = 0; i < length; i++) {
184 			(void) fprintf(stderr, "0x%02x ", data[i]);
185 			if (!((i + 1) % 16)) {
186 				(void) fprintf(stderr, "\n");
187 			} else if (!((i + 1) % 8)) {
188 				(void) fprintf(stderr, "  ");
189 			}
190 		}
191 		(void) fprintf(stderr, "\n");
192 	}
193 	SHA1_Update(hash->data, data, length);
194 }
195 
196 static unsigned
197 sha1_finish(__ops_hash_t *hash, uint8_t *out)
198 {
199 	SHA1_Final(out, hash->data);
200 	if (__ops_get_debug_level(__FILE__)) {
201 		unsigned        i;
202 
203 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
204 		for (i = 0; i < OPS_SHA1_HASH_SIZE; i++)
205 			(void) fprintf(stderr, "0x%02x ", out[i]);
206 		(void) fprintf(stderr, "\n");
207 	}
208 	free(hash->data);
209 	hash->data = NULL;
210 	return OPS_SHA1_HASH_SIZE;
211 }
212 
213 static const __ops_hash_t sha1 = {
214 	OPS_HASH_SHA1,
215 	OPS_SHA1_HASH_SIZE,
216 	"SHA1",
217 	sha1_init,
218 	sha1_add,
219 	sha1_finish,
220 	NULL
221 };
222 
223 /**
224    \ingroup Core_Crypto
225    \brief Initialise to SHA1
226    \param hash Hash to initialise
227 */
228 void
229 __ops_hash_sha1(__ops_hash_t *hash)
230 {
231 	*hash = sha1;
232 }
233 
234 static int
235 sha256_init(__ops_hash_t *hash)
236 {
237 	if (__ops_get_debug_level(__FILE__)) {
238 		fprintf(stderr, "***\n***\nsha256_init\n***\n");
239 	}
240 	if (hash->data) {
241 		(void) fprintf(stderr, "sha256_init: hash data non-null\n");
242 	}
243 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
244 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
245 		return 0;
246 	}
247 	SHA256_Init(hash->data);
248 	return 1;
249 }
250 
251 static void
252 sha256_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
253 {
254 	if (__ops_get_debug_level(__FILE__)) {
255 		unsigned    i;
256 
257 		(void) fprintf(stderr, "adding %d to hash:\n ", length);
258 		for (i = 0; i < length; i++) {
259 			(void) fprintf(stderr, "0x%02x ", data[i]);
260 			if (!((i + 1) % 16))
261 				(void) fprintf(stderr, "\n");
262 			else if (!((i + 1) % 8))
263 				(void) fprintf(stderr, "  ");
264 		}
265 		(void) fprintf(stderr, "\n");
266 	}
267 	SHA256_Update(hash->data, data, length);
268 }
269 
270 static unsigned
271 sha256_finish(__ops_hash_t *hash, uint8_t *out)
272 {
273 	SHA256_Final(out, hash->data);
274 	if (__ops_get_debug_level(__FILE__)) {
275 		unsigned        i;
276 
277 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
278 		for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
279 			(void) fprintf(stderr, "0x%02x ", out[i]);
280 		(void) fprintf(stderr, "\n");
281 	}
282 	free(hash->data);
283 	hash->data = NULL;
284 	return SHA256_DIGEST_LENGTH;
285 }
286 
287 static const __ops_hash_t sha256 = {
288 	OPS_HASH_SHA256,
289 	SHA256_DIGEST_LENGTH,
290 	"SHA256",
291 	sha256_init,
292 	sha256_add,
293 	sha256_finish,
294 	NULL
295 };
296 
297 void
298 __ops_hash_sha256(__ops_hash_t *hash)
299 {
300 	*hash = sha256;
301 }
302 
303 /*
304  * SHA384
305  */
306 static int
307 sha384_init(__ops_hash_t *hash)
308 {
309 	if (__ops_get_debug_level(__FILE__)) {
310 		(void) fprintf(stderr, "***\n***\nsha384_init\n***\n");
311 	}
312 	if (hash->data) {
313 		(void) fprintf(stderr, "sha384_init: hash data non-null\n");
314 	}
315 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
316 		(void) fprintf(stderr, "sha512_init: bad alloc\n");
317 		return 0;
318 	}
319 	SHA384_Init(hash->data);
320 	return 1;
321 }
322 
323 static void
324 sha384_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
325 {
326 	if (__ops_get_debug_level(__FILE__)) {
327 		unsigned    i;
328 
329 		(void) fprintf(stderr, "adding %u to hash:\n ", length);
330 		for (i = 0; i < length; i++) {
331 			(void) fprintf(stderr, "0x%02x ", data[i]);
332 			if (!((i + 1) % 16))
333 				(void) fprintf(stderr, "\n");
334 			else if (!((i + 1) % 8))
335 				(void) fprintf(stderr, "  ");
336 		}
337 		(void) fprintf(stderr, "\n");
338 	}
339 	SHA384_Update(hash->data, data, length);
340 }
341 
342 static unsigned
343 sha384_finish(__ops_hash_t *hash, uint8_t *out)
344 {
345 	SHA384_Final(out, hash->data);
346 	if (__ops_get_debug_level(__FILE__)) {
347 		unsigned        i;
348 
349 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
350 		for (i = 0; i < SHA384_DIGEST_LENGTH; i++)
351 			(void) fprintf(stderr, "0x%02x ", out[i]);
352 		(void) fprintf(stderr, "\n");
353 	}
354 	free(hash->data);
355 	hash->data = NULL;
356 	return SHA384_DIGEST_LENGTH;
357 }
358 
359 static const __ops_hash_t sha384 = {
360 	OPS_HASH_SHA384,
361 	SHA384_DIGEST_LENGTH,
362 	"SHA384",
363 	sha384_init,
364 	sha384_add,
365 	sha384_finish,
366 	NULL
367 };
368 
369 void
370 __ops_hash_sha384(__ops_hash_t *hash)
371 {
372 	*hash = sha384;
373 }
374 
375 /*
376  * SHA512
377  */
378 static int
379 sha512_init(__ops_hash_t *hash)
380 {
381 	if (__ops_get_debug_level(__FILE__)) {
382 		(void) fprintf(stderr, "***\n***\nsha512_init\n***\n");
383 	}
384 	if (hash->data) {
385 		(void) fprintf(stderr, "sha512_init: hash data non-null\n");
386 	}
387 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
388 		(void) fprintf(stderr, "sha512_init: bad alloc\n");
389 		return 0;
390 	}
391 	SHA512_Init(hash->data);
392 	return 1;
393 }
394 
395 static void
396 sha512_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
397 {
398 	if (__ops_get_debug_level(__FILE__)) {
399 		unsigned    i;
400 
401 		(void) fprintf(stderr, "adding %u to hash:\n ", length);
402 		for (i = 0; i < length; i++) {
403 			(void) fprintf(stderr, "0x%02x ", data[i]);
404 			if (!((i + 1) % 16))
405 				(void) fprintf(stderr, "\n");
406 			else if (!((i + 1) % 8))
407 				(void) fprintf(stderr, "  ");
408 		}
409 		(void) fprintf(stderr, "\n");
410 	}
411 	SHA512_Update(hash->data, data, length);
412 }
413 
414 static unsigned
415 sha512_finish(__ops_hash_t *hash, uint8_t *out)
416 {
417 	SHA512_Final(out, hash->data);
418 	if (__ops_get_debug_level(__FILE__)) {
419 		unsigned        i;
420 
421 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
422 		for (i = 0; i < SHA512_DIGEST_LENGTH; i++)
423 			(void) fprintf(stderr, "0x%02x ", out[i]);
424 		(void) fprintf(stderr, "\n");
425 	}
426 	free(hash->data);
427 	hash->data = NULL;
428 	return SHA512_DIGEST_LENGTH;
429 }
430 
431 static const __ops_hash_t sha512 = {
432 	OPS_HASH_SHA512,
433 	SHA512_DIGEST_LENGTH,
434 	"SHA512",
435 	sha512_init,
436 	sha512_add,
437 	sha512_finish,
438 	NULL
439 };
440 
441 void
442 __ops_hash_sha512(__ops_hash_t *hash)
443 {
444 	*hash = sha512;
445 }
446 
447 /*
448  * SHA224
449  */
450 
451 static int
452 sha224_init(__ops_hash_t *hash)
453 {
454 	if (__ops_get_debug_level(__FILE__)) {
455 		(void) fprintf(stderr, "***\n***\nsha1_init\n***\n");
456 	}
457 	if (hash->data) {
458 		(void) fprintf(stderr, "sha224_init: hash data non-null\n");
459 	}
460 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
461 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
462 		return 0;
463 	}
464 	SHA224_Init(hash->data);
465 	return 1;
466 }
467 
468 static void
469 sha224_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
470 {
471 	if (__ops_get_debug_level(__FILE__)) {
472 		unsigned    i;
473 
474 		(void) fprintf(stderr, "adding %u to hash:\n ", length);
475 		for (i = 0; i < length; i++) {
476 			(void) fprintf(stderr, "0x%02x ", data[i]);
477 			if (!((i + 1) % 16))
478 				(void) fprintf(stderr, "\n");
479 			else if (!((i + 1) % 8))
480 				(void) fprintf(stderr, "  ");
481 		}
482 		(void) fprintf(stderr, "\n");
483 	}
484 	SHA224_Update(hash->data, data, length);
485 }
486 
487 static unsigned
488 sha224_finish(__ops_hash_t *hash, uint8_t *out)
489 {
490 	SHA224_Final(out, hash->data);
491 	if (__ops_get_debug_level(__FILE__)) {
492 		unsigned        i;
493 
494 		(void) fprintf(stderr, "***\n***\nsha1_finish\n***\n");
495 		for (i = 0; i < SHA224_DIGEST_LENGTH; i++)
496 			(void) fprintf(stderr, "0x%02x ", out[i]);
497 		(void) fprintf(stderr, "\n");
498 	}
499 	free(hash->data);
500 	hash->data = NULL;
501 	return SHA224_DIGEST_LENGTH;
502 }
503 
504 static const __ops_hash_t sha224 = {
505 	OPS_HASH_SHA224,
506 	SHA224_DIGEST_LENGTH,
507 	"SHA224",
508 	sha224_init,
509 	sha224_add,
510 	sha224_finish,
511 	NULL
512 };
513 
514 void
515 __ops_hash_sha224(__ops_hash_t *hash)
516 {
517 	*hash = sha224;
518 }
519 
520 unsigned
521 __ops_dsa_verify(const uint8_t *hash, size_t hash_length,
522 	       const __ops_dsa_sig_t *sig,
523 	       const __ops_dsa_pubkey_t *dsa)
524 {
525 	unsigned	qlen;
526 	DSA_SIG        *osig;
527 	DSA            *odsa;
528 	int             ret;
529 
530 	osig = DSA_SIG_new();
531 	osig->r = sig->r;
532 	osig->s = sig->s;
533 
534 	odsa = DSA_new();
535 	odsa->p = dsa->p;
536 	odsa->q = dsa->q;
537 	odsa->g = dsa->g;
538 	odsa->pub_key = dsa->y;
539 
540 	if (__ops_get_debug_level(__FILE__)) {
541 		hexdump(stderr, "input hash", hash, hash_length);
542 		(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
543 	}
544 	if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
545 		hash_length = qlen;
546 	}
547 	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
548 	if (__ops_get_debug_level(__FILE__)) {
549 		(void) fprintf(stderr, "ret=%d\n", ret);
550 	}
551 	if (ret < 0) {
552 		(void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n");
553 		return 0;
554 	}
555 
556 	odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
557 	DSA_free(odsa);
558 
559 	osig->r = osig->s = NULL;
560 	DSA_SIG_free(osig);
561 
562 	return (unsigned)ret;
563 }
564 
565 /**
566    \ingroup Core_Crypto
567    \brief Recovers message digest from the signature
568    \param out Where to write decrypted data to
569    \param in Encrypted data
570    \param length Length of encrypted data
571    \param pubkey RSA public key
572    \return size of recovered message digest
573 */
574 int
575 __ops_rsa_public_decrypt(uint8_t *out,
576 			const uint8_t *in,
577 			size_t length,
578 			const __ops_rsa_pubkey_t *pubkey)
579 {
580 	RSA            *orsa;
581 	int             n;
582 
583 	orsa = RSA_new();
584 	orsa->n = pubkey->n;
585 	orsa->e = pubkey->e;
586 
587 	n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
588 
589 	orsa->n = orsa->e = NULL;
590 	RSA_free(orsa);
591 
592 	return n;
593 }
594 
595 /**
596    \ingroup Core_Crypto
597    \brief Signs data with RSA
598    \param out Where to write signature
599    \param in Data to sign
600    \param length Length of data
601    \param seckey RSA secret key
602    \param pubkey RSA public key
603    \return number of bytes decrypted
604 */
605 int
606 __ops_rsa_private_encrypt(uint8_t *out,
607 			const uint8_t *in,
608 			size_t length,
609 			const __ops_rsa_seckey_t *seckey,
610 			const __ops_rsa_pubkey_t *pubkey)
611 {
612 	RSA            *orsa;
613 	int             n;
614 
615 	orsa = RSA_new();
616 	orsa->n = BN_dup(pubkey->n);
617 	orsa->d = seckey->d;
618 	orsa->p = seckey->q;
619 	orsa->q = seckey->p;
620 
621 	/* debug */
622 	orsa->e = BN_dup(pubkey->e);
623 	/* If this isn't set, it's very likely that the programmer hasn't */
624 	/* decrypted the secret key. RSA_check_key segfaults in that case. */
625 	/* Use __ops_decrypt_seckey() to do that. */
626 	if (orsa->d == NULL) {
627 		(void) fprintf(stderr, "orsa is not set\n");
628 		return 0;
629 	}
630 	if (RSA_check_key(orsa) != 1) {
631 		(void) fprintf(stderr, "RSA_check_key is not set\n");
632 		return 0;
633 	}
634 	/* end debug */
635 
636 	n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
637 
638 	orsa->n = orsa->d = orsa->p = orsa->q = NULL;
639 	RSA_free(orsa);
640 
641 	return n;
642 }
643 
644 /**
645 \ingroup Core_Crypto
646 \brief Decrypts RSA-encrypted data
647 \param out Where to write the plaintext
648 \param in Encrypted data
649 \param length Length of encrypted data
650 \param seckey RSA secret key
651 \param pubkey RSA public key
652 \return size of recovered plaintext
653 */
654 int
655 __ops_rsa_private_decrypt(uint8_t *out,
656 			const uint8_t *in,
657 			size_t length,
658 			const __ops_rsa_seckey_t *seckey,
659 			const __ops_rsa_pubkey_t *pubkey)
660 {
661 	RSA            *keypair;
662 	int             n;
663 	char            errbuf[1024];
664 
665 	keypair = RSA_new();
666 	keypair->n = pubkey->n;	/* XXX: do we need n? */
667 	keypair->d = seckey->d;
668 	keypair->p = seckey->q;
669 	keypair->q = seckey->p;
670 
671 	/* debug */
672 	keypair->e = pubkey->e;
673 	if (RSA_check_key(keypair) != 1) {
674 		(void) fprintf(stderr, "RSA_check_key is not set\n");
675 		return 0;
676 	}
677 	/* end debug */
678 
679 	n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
680 
681 	if (__ops_get_debug_level(__FILE__)) {
682 		printf("__ops_rsa_private_decrypt: n=%d\n",n);
683 	}
684 
685 	errbuf[0] = '\0';
686 	if (n == -1) {
687 		unsigned long   err = ERR_get_error();
688 
689 		ERR_error_string(err, &errbuf[0]);
690 		(void) fprintf(stderr, "openssl error : %s\n", errbuf);
691 	}
692 	keypair->n = keypair->d = keypair->p = keypair->q = NULL;
693 	RSA_free(keypair);
694 
695 	return n;
696 }
697 
698 /**
699    \ingroup Core_Crypto
700    \brief RSA-encrypts data
701    \param out Where to write the encrypted data
702    \param in Plaintext
703    \param length Size of plaintext
704    \param pubkey RSA Public Key
705 */
706 int
707 __ops_rsa_public_encrypt(uint8_t *out,
708 			const uint8_t *in,
709 			size_t length,
710 			const __ops_rsa_pubkey_t *pubkey)
711 {
712 	RSA            *orsa;
713 	int             n;
714 
715 	/* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */
716 
717 	orsa = RSA_new();
718 	orsa->n = pubkey->n;
719 	orsa->e = pubkey->e;
720 
721 	/* printf("len: %ld\n", length); */
722 	/* __ops_print_bn("n: ", orsa->n); */
723 	/* __ops_print_bn("e: ", orsa->e); */
724 	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
725 
726 	if (n == -1) {
727 		BIO            *fd_out;
728 
729 		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
730 		ERR_print_errors(fd_out);
731 	}
732 	orsa->n = orsa->e = NULL;
733 	RSA_free(orsa);
734 
735 	return n;
736 }
737 
738 /**
739    \ingroup Core_Crypto
740    \brief Finalise openssl
741    \note Would usually call __ops_finish() instead
742    \sa __ops_finish()
743 */
744 void
745 __ops_crypto_finish(void)
746 {
747 	CRYPTO_cleanup_all_ex_data();
748 	ERR_remove_state((unsigned long)0);
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 1 if key generated successfully; otherwise 0
770  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
771 */
772 static unsigned
773 rsa_generate_keypair(__ops_key_t *keydata,
774 			const int numbits,
775 			const unsigned long e,
776 			const char *hashalg)
777 {
778 	__ops_seckey_t *seckey;
779 	RSA            *rsa;
780 	BN_CTX         *ctx;
781 	__ops_output_t *output;
782 	__ops_memory_t   *mem;
783 
784 	ctx = BN_CTX_new();
785 	__ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY);
786 	seckey = __ops_get_writable_seckey(keydata);
787 
788 	/* generate the key pair */
789 
790 	rsa = RSA_generate_key(numbits, e, NULL, NULL);
791 
792 	/* populate __ops key from ssl key */
793 
794 	seckey->pubkey.version = OPS_V4;
795 	seckey->pubkey.birthtime = time(NULL);
796 	seckey->pubkey.days_valid = 0;
797 	seckey->pubkey.alg = OPS_PKA_RSA;
798 
799 	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
800 	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
801 
802 	seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED;
803 	seckey->s2k_specifier = OPS_S2KS_SALTED;
804 	/* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */
805 	seckey->alg = OPS_SA_CAST5;	/* \todo make param */
806 	if ((seckey->hash_alg = __ops_str_to_hash_alg(hashalg)) == OPS_HASH_UNKNOWN) {
807 		seckey->hash_alg = OPS_HASH_SHA1;
808 	}
809 	seckey->octetc = 0;
810 	seckey->checksum = 0;
811 
812 	seckey->key.rsa.d = BN_dup(rsa->d);
813 	seckey->key.rsa.p = BN_dup(rsa->p);
814 	seckey->key.rsa.q = BN_dup(rsa->q);
815 	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
816 	if (seckey->key.rsa.u == NULL) {
817 		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
818 		return 0;
819 	}
820 	BN_CTX_free(ctx);
821 
822 	RSA_free(rsa);
823 
824 	__ops_keyid(keydata->key_id, OPS_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
825 	__ops_fingerprint(&keydata->fingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
826 
827 	/* Generate checksum */
828 
829 	output = NULL;
830 	mem = NULL;
831 
832 	__ops_setup_memory_write(&output, &mem, 128);
833 
834 	__ops_push_checksum_writer(output, seckey);
835 
836 	switch (seckey->pubkey.alg) {
837 	case OPS_PKA_DSA:
838 		return __ops_write_mpi(output, seckey->key.dsa.x);
839 	case OPS_PKA_RSA:
840 	case OPS_PKA_RSA_ENCRYPT_ONLY:
841 	case OPS_PKA_RSA_SIGN_ONLY:
842 		if (!__ops_write_mpi(output, seckey->key.rsa.d) ||
843 		    !__ops_write_mpi(output, seckey->key.rsa.p) ||
844 		    !__ops_write_mpi(output, seckey->key.rsa.q) ||
845 		    !__ops_write_mpi(output, seckey->key.rsa.u)) {
846 			return 0;
847 		}
848 		break;
849 	case OPS_PKA_ELGAMAL:
850 		return __ops_write_mpi(output, seckey->key.elgamal.x);
851 
852 	default:
853 		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
854 		return 0;
855 	}
856 
857 	/* close rather than pop, since its the only one on the stack */
858 	__ops_writer_close(output);
859 	__ops_teardown_memory_write(output, mem);
860 
861 	/* should now have checksum in seckey struct */
862 
863 	/* test */
864 	if (__ops_get_debug_level(__FILE__)) {
865 		test_seckey(seckey);
866 	}
867 
868 	return 1;
869 }
870 
871 /**
872  \ingroup HighLevel_KeyGenerate
873  \brief Creates a self-signed RSA keypair
874  \param numbits Modulus size
875  \param e Public Exponent
876  \param userid User ID
877  \return The new keypair or NULL
878 
879  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
880  \sa rsa_generate_keypair()
881  \sa __ops_keydata_free()
882 */
883 __ops_key_t  *
884 __ops_rsa_new_selfsign_key(const int numbits,
885 				const unsigned long e,
886 				uint8_t *userid,
887 				const char *hashalg)
888 {
889 	__ops_key_t  *keydata;
890 
891 	keydata = __ops_keydata_new();
892 	if (!rsa_generate_keypair(keydata, numbits, e, hashalg) ||
893 	    !__ops_add_selfsigned_userid(keydata, userid)) {
894 		__ops_keydata_free(keydata);
895 		return NULL;
896 	}
897 	return keydata;
898 }
899 
900 DSA_SIG        *
901 __ops_dsa_sign(uint8_t *hashbuf,
902 		unsigned hashsize,
903 		const __ops_dsa_seckey_t *secdsa,
904 		const __ops_dsa_pubkey_t *pubdsa)
905 {
906 	DSA_SIG        *dsasig;
907 	DSA            *odsa;
908 
909 	odsa = DSA_new();
910 	odsa->p = pubdsa->p;
911 	odsa->q = pubdsa->q;
912 	odsa->g = pubdsa->g;
913 	odsa->pub_key = pubdsa->y;
914 	odsa->priv_key = secdsa->x;
915 
916 	dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
917 
918 	odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
919 	DSA_free(odsa);
920 
921 	return dsasig;
922 }
923 
924 int
925 openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose)
926 {
927 	FILE	*fp;
928 	DSA	*dsa;
929 	RSA	*rsa;
930 	int	 ok;
931 
932 	if ((fp = fopen(f, "r")) == NULL) {
933 		if (verbose) {
934 			(void) fprintf(stderr, "can't open '%s'\n", f);
935 		}
936 		return 0;
937 	}
938 	ok = 1;
939 	if (strcmp(type, "ssh-rsa") == 0) {
940 		if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
941 			ok = 0;
942 		} else {
943 			key->key.seckey.key.rsa.d = rsa->d;
944 			key->key.seckey.key.rsa.p = rsa->p;
945 			key->key.seckey.key.rsa.q = rsa->q;
946 			key->key.seckey.key.rsa.d = rsa->d;
947 		}
948 	} else if (strcmp(type, "ssh-dss") == 0) {
949 		if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
950 			ok = 0;
951 		} else {
952 			key->key.seckey.key.dsa.x = dsa->priv_key;
953 		}
954 	} else {
955 		ok = 0;
956 	}
957 	(void) fclose(fp);
958 	return ok;
959 }
960