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.33 2010/11/07 08:39:59 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 
81 #ifdef HAVE_UNISTD_H
82 #include <unistd.h>
83 #endif
84 
85 #include "crypto.h"
86 #include "keyring.h"
87 #include "readerwriter.h"
88 #include "netpgpdefs.h"
89 #include "netpgpdigest.h"
90 #include "packet.h"
91 
92 
93 static void
94 test_seckey(const pgp_seckey_t *seckey)
95 {
96 	RSA            *test = RSA_new();
97 
98 	test->n = BN_dup(seckey->pubkey.key.rsa.n);
99 	test->e = BN_dup(seckey->pubkey.key.rsa.e);
100 
101 	test->d = BN_dup(seckey->key.rsa.d);
102 	test->p = BN_dup(seckey->key.rsa.p);
103 	test->q = BN_dup(seckey->key.rsa.q);
104 
105 	if (RSA_check_key(test) != 1) {
106 		(void) fprintf(stderr,
107 			"test_seckey: RSA_check_key failed\n");
108 	}
109 	RSA_free(test);
110 }
111 
112 static int
113 md5_init(pgp_hash_t *hash)
114 {
115 	if (hash->data) {
116 		(void) fprintf(stderr, "md5_init: hash data non-null\n");
117 	}
118 	if ((hash->data = calloc(1, sizeof(MD5_CTX))) == NULL) {
119 		(void) fprintf(stderr, "md5_init: bad alloc\n");
120 		return 0;
121 	}
122 	MD5_Init(hash->data);
123 	return 1;
124 }
125 
126 static void
127 md5_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
128 {
129 	MD5_Update(hash->data, data, length);
130 }
131 
132 static unsigned
133 md5_finish(pgp_hash_t *hash, uint8_t *out)
134 {
135 	MD5_Final(out, hash->data);
136 	free(hash->data);
137 	hash->data = NULL;
138 	return 16;
139 }
140 
141 static const pgp_hash_t md5 = {
142 	PGP_HASH_MD5,
143 	MD5_DIGEST_LENGTH,
144 	"MD5",
145 	md5_init,
146 	md5_add,
147 	md5_finish,
148 	NULL
149 };
150 
151 /**
152    \ingroup Core_Crypto
153    \brief Initialise to MD5
154    \param hash Hash to initialise
155 */
156 void
157 pgp_hash_md5(pgp_hash_t *hash)
158 {
159 	*hash = md5;
160 }
161 
162 static int
163 sha1_init(pgp_hash_t *hash)
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(pgp_hash_t *hash, const uint8_t *data, unsigned length)
178 {
179 	if (pgp_get_debug_level(__FILE__)) {
180 		hexdump(stderr, "sha1_add", data, length);
181 	}
182 	SHA1_Update(hash->data, data, length);
183 }
184 
185 static unsigned
186 sha1_finish(pgp_hash_t *hash, uint8_t *out)
187 {
188 	SHA1_Final(out, hash->data);
189 	if (pgp_get_debug_level(__FILE__)) {
190 		hexdump(stderr, "sha1_finish", out, PGP_SHA1_HASH_SIZE);
191 	}
192 	free(hash->data);
193 	hash->data = NULL;
194 	return PGP_SHA1_HASH_SIZE;
195 }
196 
197 static const pgp_hash_t sha1 = {
198 	PGP_HASH_SHA1,
199 	PGP_SHA1_HASH_SIZE,
200 	"SHA1",
201 	sha1_init,
202 	sha1_add,
203 	sha1_finish,
204 	NULL
205 };
206 
207 /**
208    \ingroup Core_Crypto
209    \brief Initialise to SHA1
210    \param hash Hash to initialise
211 */
212 void
213 pgp_hash_sha1(pgp_hash_t *hash)
214 {
215 	*hash = sha1;
216 }
217 
218 static int
219 sha256_init(pgp_hash_t *hash)
220 {
221 	if (hash->data) {
222 		(void) fprintf(stderr, "sha256_init: hash data non-null\n");
223 	}
224 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
225 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
226 		return 0;
227 	}
228 	SHA256_Init(hash->data);
229 	return 1;
230 }
231 
232 static void
233 sha256_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
234 {
235 	if (pgp_get_debug_level(__FILE__)) {
236 		hexdump(stderr, "sha256_add", data, length);
237 	}
238 	SHA256_Update(hash->data, data, length);
239 }
240 
241 static unsigned
242 sha256_finish(pgp_hash_t *hash, uint8_t *out)
243 {
244 	SHA256_Final(out, hash->data);
245 	if (pgp_get_debug_level(__FILE__)) {
246 		hexdump(stderr, "sha1_finish", out, SHA256_DIGEST_LENGTH);
247 	}
248 	free(hash->data);
249 	hash->data = NULL;
250 	return SHA256_DIGEST_LENGTH;
251 }
252 
253 static const pgp_hash_t sha256 = {
254 	PGP_HASH_SHA256,
255 	SHA256_DIGEST_LENGTH,
256 	"SHA256",
257 	sha256_init,
258 	sha256_add,
259 	sha256_finish,
260 	NULL
261 };
262 
263 void
264 pgp_hash_sha256(pgp_hash_t *hash)
265 {
266 	*hash = sha256;
267 }
268 
269 /*
270  * SHA384
271  */
272 static int
273 sha384_init(pgp_hash_t *hash)
274 {
275 	if (hash->data) {
276 		(void) fprintf(stderr, "sha384_init: hash data non-null\n");
277 	}
278 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
279 		(void) fprintf(stderr, "sha384_init: bad alloc\n");
280 		return 0;
281 	}
282 	SHA384_Init(hash->data);
283 	return 1;
284 }
285 
286 static void
287 sha384_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
288 {
289 	if (pgp_get_debug_level(__FILE__)) {
290 		hexdump(stderr, "sha384_add", data, length);
291 	}
292 	SHA384_Update(hash->data, data, length);
293 }
294 
295 static unsigned
296 sha384_finish(pgp_hash_t *hash, uint8_t *out)
297 {
298 	SHA384_Final(out, hash->data);
299 	if (pgp_get_debug_level(__FILE__)) {
300 		hexdump(stderr, "sha384_finish", out, SHA384_DIGEST_LENGTH);
301 	}
302 	free(hash->data);
303 	hash->data = NULL;
304 	return SHA384_DIGEST_LENGTH;
305 }
306 
307 static const pgp_hash_t sha384 = {
308 	PGP_HASH_SHA384,
309 	SHA384_DIGEST_LENGTH,
310 	"SHA384",
311 	sha384_init,
312 	sha384_add,
313 	sha384_finish,
314 	NULL
315 };
316 
317 void
318 pgp_hash_sha384(pgp_hash_t *hash)
319 {
320 	*hash = sha384;
321 }
322 
323 /*
324  * SHA512
325  */
326 static int
327 sha512_init(pgp_hash_t *hash)
328 {
329 	if (hash->data) {
330 		(void) fprintf(stderr, "sha512_init: hash data non-null\n");
331 	}
332 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
333 		(void) fprintf(stderr, "sha512_init: bad alloc\n");
334 		return 0;
335 	}
336 	SHA512_Init(hash->data);
337 	return 1;
338 }
339 
340 static void
341 sha512_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
342 {
343 	if (pgp_get_debug_level(__FILE__)) {
344 		hexdump(stderr, "sha512_add", data, length);
345 	}
346 	SHA512_Update(hash->data, data, length);
347 }
348 
349 static unsigned
350 sha512_finish(pgp_hash_t *hash, uint8_t *out)
351 {
352 	SHA512_Final(out, hash->data);
353 	if (pgp_get_debug_level(__FILE__)) {
354 		hexdump(stderr, "sha512_finish", out, SHA512_DIGEST_LENGTH);
355 	}
356 	free(hash->data);
357 	hash->data = NULL;
358 	return SHA512_DIGEST_LENGTH;
359 }
360 
361 static const pgp_hash_t sha512 = {
362 	PGP_HASH_SHA512,
363 	SHA512_DIGEST_LENGTH,
364 	"SHA512",
365 	sha512_init,
366 	sha512_add,
367 	sha512_finish,
368 	NULL
369 };
370 
371 void
372 pgp_hash_sha512(pgp_hash_t *hash)
373 {
374 	*hash = sha512;
375 }
376 
377 /*
378  * SHA224
379  */
380 
381 static int
382 sha224_init(pgp_hash_t *hash)
383 {
384 	if (hash->data) {
385 		(void) fprintf(stderr, "sha224_init: hash data non-null\n");
386 	}
387 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
388 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
389 		return 0;
390 	}
391 	SHA224_Init(hash->data);
392 	return 1;
393 }
394 
395 static void
396 sha224_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
397 {
398 	if (pgp_get_debug_level(__FILE__)) {
399 		hexdump(stderr, "sha224_add", data, length);
400 	}
401 	SHA224_Update(hash->data, data, length);
402 }
403 
404 static unsigned
405 sha224_finish(pgp_hash_t *hash, uint8_t *out)
406 {
407 	SHA224_Final(out, hash->data);
408 	if (pgp_get_debug_level(__FILE__)) {
409 		hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH);
410 	}
411 	free(hash->data);
412 	hash->data = NULL;
413 	return SHA224_DIGEST_LENGTH;
414 }
415 
416 static const pgp_hash_t sha224 = {
417 	PGP_HASH_SHA224,
418 	SHA224_DIGEST_LENGTH,
419 	"SHA224",
420 	sha224_init,
421 	sha224_add,
422 	sha224_finish,
423 	NULL
424 };
425 
426 void
427 pgp_hash_sha224(pgp_hash_t *hash)
428 {
429 	*hash = sha224;
430 }
431 
432 unsigned
433 pgp_dsa_verify(const uint8_t *hash, size_t hash_length,
434 	       const pgp_dsa_sig_t *sig,
435 	       const pgp_dsa_pubkey_t *dsa)
436 {
437 	unsigned	qlen;
438 	DSA_SIG        *osig;
439 	DSA            *odsa;
440 	int             ret;
441 
442 	osig = DSA_SIG_new();
443 	osig->r = sig->r;
444 	osig->s = sig->s;
445 
446 	odsa = DSA_new();
447 	odsa->p = dsa->p;
448 	odsa->q = dsa->q;
449 	odsa->g = dsa->g;
450 	odsa->pub_key = dsa->y;
451 
452 	if (pgp_get_debug_level(__FILE__)) {
453 		hexdump(stderr, "input hash", hash, hash_length);
454 		(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
455 	}
456 	if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
457 		hash_length = qlen;
458 	}
459 	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
460 	if (pgp_get_debug_level(__FILE__)) {
461 		(void) fprintf(stderr, "ret=%d\n", ret);
462 	}
463 	if (ret < 0) {
464 		(void) fprintf(stderr, "pgp_dsa_verify: DSA verification\n");
465 		return 0;
466 	}
467 
468 	odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
469 	DSA_free(odsa);
470 
471 	osig->r = osig->s = NULL;
472 	DSA_SIG_free(osig);
473 
474 	return (unsigned)ret;
475 }
476 
477 /**
478    \ingroup Core_Crypto
479    \brief Recovers message digest from the signature
480    \param out Where to write decrypted data to
481    \param in Encrypted data
482    \param length Length of encrypted data
483    \param pubkey RSA public key
484    \return size of recovered message digest
485 */
486 int
487 pgp_rsa_public_decrypt(uint8_t *out,
488 			const uint8_t *in,
489 			size_t length,
490 			const pgp_rsa_pubkey_t *pubkey)
491 {
492 	RSA            *orsa;
493 	int             n;
494 
495 	orsa = RSA_new();
496 	orsa->n = pubkey->n;
497 	orsa->e = pubkey->e;
498 
499 	n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
500 
501 	orsa->n = orsa->e = NULL;
502 	RSA_free(orsa);
503 
504 	return n;
505 }
506 
507 /**
508    \ingroup Core_Crypto
509    \brief Signs data with RSA
510    \param out Where to write signature
511    \param in Data to sign
512    \param length Length of data
513    \param seckey RSA secret key
514    \param pubkey RSA public key
515    \return number of bytes decrypted
516 */
517 int
518 pgp_rsa_private_encrypt(uint8_t *out,
519 			const uint8_t *in,
520 			size_t length,
521 			const pgp_rsa_seckey_t *seckey,
522 			const pgp_rsa_pubkey_t *pubkey)
523 {
524 	RSA            *orsa;
525 	int             n;
526 
527 	orsa = RSA_new();
528 	orsa->n = BN_dup(pubkey->n);
529 	orsa->d = seckey->d;
530 	orsa->p = seckey->q;	/* p and q are round the other way in openssl */
531 	orsa->q = seckey->p;
532 
533 	/* debug */
534 	orsa->e = BN_dup(pubkey->e);
535 	/* If this isn't set, it's very likely that the programmer hasn't */
536 	/* decrypted the secret key. RSA_check_key segfaults in that case. */
537 	/* Use pgp_decrypt_seckey() to do that. */
538 	if (orsa->d == NULL) {
539 		(void) fprintf(stderr, "orsa is not set\n");
540 		return 0;
541 	}
542 	if (RSA_check_key(orsa) != 1) {
543 		(void) fprintf(stderr, "RSA_check_key is not set\n");
544 		return 0;
545 	}
546 	/* end debug */
547 
548 	n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
549 
550 	orsa->n = orsa->d = orsa->p = orsa->q = NULL;
551 	RSA_free(orsa);
552 
553 	return n;
554 }
555 
556 /**
557 \ingroup Core_Crypto
558 \brief Decrypts RSA-encrypted data
559 \param out Where to write the plaintext
560 \param in Encrypted data
561 \param length Length of encrypted data
562 \param seckey RSA secret key
563 \param pubkey RSA public key
564 \return size of recovered plaintext
565 */
566 int
567 pgp_rsa_private_decrypt(uint8_t *out,
568 			const uint8_t *in,
569 			size_t length,
570 			const pgp_rsa_seckey_t *seckey,
571 			const pgp_rsa_pubkey_t *pubkey)
572 {
573 	RSA            *keypair;
574 	int             n;
575 	char            errbuf[1024];
576 
577 	keypair = RSA_new();
578 	keypair->n = pubkey->n;	/* XXX: do we need n? */
579 	keypair->d = seckey->d;
580 	keypair->p = seckey->q;
581 	keypair->q = seckey->p;
582 
583 	/* debug */
584 	keypair->e = pubkey->e;
585 	if (RSA_check_key(keypair) != 1) {
586 		(void) fprintf(stderr, "RSA_check_key is not set\n");
587 		return 0;
588 	}
589 	/* end debug */
590 
591 	n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
592 
593 	if (pgp_get_debug_level(__FILE__)) {
594 		printf("pgp_rsa_private_decrypt: n=%d\n",n);
595 	}
596 
597 	errbuf[0] = '\0';
598 	if (n == -1) {
599 		unsigned long   err = ERR_get_error();
600 
601 		ERR_error_string(err, &errbuf[0]);
602 		(void) fprintf(stderr, "openssl error : %s\n", errbuf);
603 	}
604 	keypair->n = keypair->d = keypair->p = keypair->q = NULL;
605 	RSA_free(keypair);
606 
607 	return n;
608 }
609 
610 /**
611    \ingroup Core_Crypto
612    \brief RSA-encrypts data
613    \param out Where to write the encrypted data
614    \param in Plaintext
615    \param length Size of plaintext
616    \param pubkey RSA Public Key
617 */
618 int
619 pgp_rsa_public_encrypt(uint8_t *out,
620 			const uint8_t *in,
621 			size_t length,
622 			const pgp_rsa_pubkey_t *pubkey)
623 {
624 	RSA            *orsa;
625 	int             n;
626 
627 	/* printf("pgp_rsa_public_encrypt: length=%ld\n", length); */
628 
629 	orsa = RSA_new();
630 	orsa->n = pubkey->n;
631 	orsa->e = pubkey->e;
632 
633 	/* printf("len: %ld\n", length); */
634 	/* pgp_print_bn("n: ", orsa->n); */
635 	/* pgp_print_bn("e: ", orsa->e); */
636 	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
637 
638 	if (n == -1) {
639 		BIO            *fd_out;
640 
641 		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
642 		ERR_print_errors(fd_out);
643 	}
644 	orsa->n = orsa->e = NULL;
645 	RSA_free(orsa);
646 
647 	return n;
648 }
649 
650 /**
651    \ingroup Core_Crypto
652    \brief Finalise openssl
653    \note Would usually call pgp_finish() instead
654    \sa pgp_finish()
655 */
656 void
657 pgp_crypto_finish(void)
658 {
659 	CRYPTO_cleanup_all_ex_data();
660 	ERR_remove_state((unsigned long)0);
661 }
662 
663 /**
664    \ingroup Core_Hashes
665    \brief Get Hash name
666    \param hash Hash struct
667    \return Hash name
668 */
669 const char     *
670 pgp_text_from_hash(pgp_hash_t *hash)
671 {
672 	return hash->name;
673 }
674 
675 /**
676  \ingroup HighLevel_KeyGenerate
677  \brief Generates an RSA keypair
678  \param numbits Modulus size
679  \param e Public Exponent
680  \param keydata Pointer to keydata struct to hold new key
681  \return 1 if key generated successfully; otherwise 0
682  \note It is the caller's responsibility to call pgp_keydata_free(keydata)
683 */
684 static unsigned
685 rsa_generate_keypair(pgp_key_t *keydata,
686 			const int numbits,
687 			const unsigned long e,
688 			const char *hashalg,
689 			const char *cipher)
690 {
691 	pgp_seckey_t *seckey;
692 	RSA            *rsa;
693 	BN_CTX         *ctx;
694 	pgp_output_t *output;
695 	pgp_memory_t   *mem;
696 
697 	ctx = BN_CTX_new();
698 	pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
699 	seckey = pgp_get_writable_seckey(keydata);
700 
701 	/* generate the key pair */
702 
703 	rsa = RSA_generate_key(numbits, e, NULL, NULL);
704 
705 	/* populate pgp key from ssl key */
706 
707 	seckey->pubkey.version = PGP_V4;
708 	seckey->pubkey.birthtime = time(NULL);
709 	seckey->pubkey.days_valid = 0;
710 	seckey->pubkey.alg = PGP_PKA_RSA;
711 
712 	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
713 	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
714 
715 	seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
716 	seckey->s2k_specifier = PGP_S2KS_SALTED;
717 	/* seckey->s2k_specifier=PGP_S2KS_SIMPLE; */
718 	if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
719 		seckey->hash_alg = PGP_HASH_SHA1;
720 	}
721 	seckey->alg = pgp_str_to_cipher(cipher);
722 	seckey->octetc = 0;
723 	seckey->checksum = 0;
724 
725 	seckey->key.rsa.d = BN_dup(rsa->d);
726 	seckey->key.rsa.p = BN_dup(rsa->p);
727 	seckey->key.rsa.q = BN_dup(rsa->q);
728 	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
729 	if (seckey->key.rsa.u == NULL) {
730 		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
731 		return 0;
732 	}
733 	BN_CTX_free(ctx);
734 
735 	RSA_free(rsa);
736 
737 	pgp_keyid(keydata->sigid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
738 	pgp_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
739 
740 	/* Generate checksum */
741 
742 	output = NULL;
743 	mem = NULL;
744 
745 	pgp_setup_memory_write(&output, &mem, 128);
746 
747 	pgp_push_checksum_writer(output, seckey);
748 
749 	switch (seckey->pubkey.alg) {
750 	case PGP_PKA_DSA:
751 		return pgp_write_mpi(output, seckey->key.dsa.x);
752 	case PGP_PKA_RSA:
753 	case PGP_PKA_RSA_ENCRYPT_ONLY:
754 	case PGP_PKA_RSA_SIGN_ONLY:
755 		if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
756 		    !pgp_write_mpi(output, seckey->key.rsa.p) ||
757 		    !pgp_write_mpi(output, seckey->key.rsa.q) ||
758 		    !pgp_write_mpi(output, seckey->key.rsa.u)) {
759 			return 0;
760 		}
761 		break;
762 	case PGP_PKA_ELGAMAL:
763 		return pgp_write_mpi(output, seckey->key.elgamal.x);
764 
765 	default:
766 		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
767 		return 0;
768 	}
769 
770 	/* close rather than pop, since its the only one on the stack */
771 	pgp_writer_close(output);
772 	pgp_teardown_memory_write(output, mem);
773 
774 	/* should now have checksum in seckey struct */
775 
776 	/* test */
777 	if (pgp_get_debug_level(__FILE__)) {
778 		test_seckey(seckey);
779 	}
780 
781 	return 1;
782 }
783 
784 /**
785  \ingroup HighLevel_KeyGenerate
786  \brief Creates a self-signed RSA keypair
787  \param numbits Modulus size
788  \param e Public Exponent
789  \param userid User ID
790  \return The new keypair or NULL
791 
792  \note It is the caller's responsibility to call pgp_keydata_free(keydata)
793  \sa rsa_generate_keypair()
794  \sa pgp_keydata_free()
795 */
796 pgp_key_t  *
797 pgp_rsa_new_selfsign_key(const int numbits,
798 				const unsigned long e,
799 				uint8_t *userid,
800 				const char *hashalg,
801 				const char *cipher)
802 {
803 	pgp_key_t  *keydata;
804 
805 	keydata = pgp_keydata_new();
806 	if (!rsa_generate_keypair(keydata, numbits, e, hashalg, cipher) ||
807 	    !pgp_add_selfsigned_userid(keydata, userid)) {
808 		pgp_keydata_free(keydata);
809 		return NULL;
810 	}
811 	return keydata;
812 }
813 
814 DSA_SIG        *
815 pgp_dsa_sign(uint8_t *hashbuf,
816 		unsigned hashsize,
817 		const pgp_dsa_seckey_t *secdsa,
818 		const pgp_dsa_pubkey_t *pubdsa)
819 {
820 	DSA_SIG        *dsasig;
821 	DSA            *odsa;
822 
823 	odsa = DSA_new();
824 	odsa->p = pubdsa->p;
825 	odsa->q = pubdsa->q;
826 	odsa->g = pubdsa->g;
827 	odsa->pub_key = pubdsa->y;
828 	odsa->priv_key = secdsa->x;
829 
830 	dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
831 
832 	odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
833 	DSA_free(odsa);
834 
835 	return dsasig;
836 }
837 
838 int
839 openssl_read_pem_seckey(const char *f, pgp_key_t *key, const char *type, int verbose)
840 {
841 	FILE	*fp;
842 	char	 prompt[BUFSIZ];
843 	char	*pass;
844 	DSA	*dsa;
845 	RSA	*rsa;
846 	int	 ok;
847 
848 	OpenSSL_add_all_algorithms();
849 	if ((fp = fopen(f, "r")) == NULL) {
850 		if (verbose) {
851 			(void) fprintf(stderr, "can't open '%s'\n", f);
852 		}
853 		return 0;
854 	}
855 	ok = 1;
856 	if (strcmp(type, "ssh-rsa") == 0) {
857 		if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
858 			(void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f);
859 			do {
860 				pass = getpass(prompt);
861 				rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass);
862 			} while (rsa == NULL);
863 		}
864 		key->key.seckey.key.rsa.d = rsa->d;
865 		key->key.seckey.key.rsa.p = rsa->p;
866 		key->key.seckey.key.rsa.q = rsa->q;
867 		key->key.seckey.key.rsa.d = rsa->d;
868 	} else if (strcmp(type, "ssh-dss") == 0) {
869 		if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
870 			ok = 0;
871 		} else {
872 			key->key.seckey.key.dsa.x = dsa->priv_key;
873 		}
874 	} else {
875 		ok = 0;
876 	}
877 	(void) fclose(fp);
878 	return ok;
879 }
880 
881 /*
882  * Decide the number of bits in the random componont k
883  *
884  * It should be in the same range as p for signing (which
885  * is deprecated), but can be much smaller for encrypting.
886  *
887  * Until I research it further, I just mimic gpg behaviour.
888  * It has a special mapping table, for values <= 5120,
889  * above that it uses 'arbitrary high number'.	Following
890  * algorihm hovers 10-70 bits above gpg values.  And for
891  * larger p, it uses gpg's algorihm.
892  *
893  * The point is - if k gets large, encryption will be
894  * really slow.  It does not matter for decryption.
895  */
896 static int
897 decide_k_bits(int p_bits)
898 {
899 	return (p_bits <= 5120) ? p_bits / 10 + 160 : (p_bits / 8 + 200) * 3 / 2;
900 }
901 
902 int
903 pgp_elgamal_public_encrypt(uint8_t *g_to_k, uint8_t *encm,
904 			const uint8_t *in,
905 			size_t size,
906 			const pgp_elgamal_pubkey_t *pubkey)
907 {
908 	int	ret = 0;
909 	int	k_bits;
910 	BIGNUM	   *m;
911 	BIGNUM	   *p;
912 	BIGNUM	   *g;
913 	BIGNUM	   *y;
914 	BIGNUM	   *k;
915 	BIGNUM	   *yk;
916 	BIGNUM	   *c1;
917 	BIGNUM	   *c2;
918 	BN_CTX	   *tmp;
919 
920 	m = BN_bin2bn(in, (int)size, NULL);
921 	p = pubkey->p;
922 	g = pubkey->g;
923 	y = pubkey->y;
924 	k = BN_new();
925 	yk = BN_new();
926 	c1 = BN_new();
927 	c2 = BN_new();
928 	tmp = BN_CTX_new();
929 	if (!m || !p || !g || !y || !k || !yk || !c1 || !c2 || !tmp) {
930 		goto done;
931 	}
932 	/*
933 	 * generate k
934 	 */
935 	k_bits = decide_k_bits(BN_num_bits(p));
936 	if (!BN_rand(k, k_bits, 0, 0)) {
937 		goto done;
938 	}
939 	/*
940 	 * c1 = g^k c2 = m * y^k
941 	 */
942 	if (!BN_mod_exp(c1, g, k, p, tmp)) {
943 		goto done;
944 	}
945 	if (!BN_mod_exp(yk, y, k, p, tmp)) {
946 		goto done;
947 	}
948 	if (!BN_mod_mul(c2, m, yk, p, tmp)) {
949 		goto done;
950 	}
951 	/* result */
952 	BN_bn2bin(c1, g_to_k);
953 	ret = BN_num_bytes(c1);	/* c1 = g^k */
954 	BN_bn2bin(c2, encm);
955 	ret += BN_num_bytes(c2); /* c2 = m * y^k */
956 done:
957 	if (tmp) {
958 		BN_CTX_free(tmp);
959 	}
960 	if (c2) {
961 		BN_clear_free(c2);
962 	}
963 	if (c1) {
964 		BN_clear_free(c1);
965 	}
966 	if (yk) {
967 		BN_clear_free(yk);
968 	}
969 	if (k) {
970 		BN_clear_free(k);
971 	}
972 	if (g) {
973 		BN_clear_free(g);
974 	}
975 	return ret;
976 }
977 
978 int
979 pgp_elgamal_private_decrypt(uint8_t *out,
980 				const uint8_t *g_to_k,
981 				const uint8_t *in,
982 				size_t length,
983 				const pgp_elgamal_seckey_t *seckey,
984 				const pgp_elgamal_pubkey_t *pubkey)
985 {
986 	BIGNUM	*bndiv;
987 	BIGNUM	*c1x;
988 	BN_CTX	*tmp;
989 	BIGNUM	*c1;
990 	BIGNUM	*c2;
991 	BIGNUM	*p;
992 	BIGNUM	*x;
993 	BIGNUM	*m;
994 	int	 ret;
995 
996 	ret = 0;
997 	/* c1 and c2 are in g_to_k and in, respectively*/
998 	c1 = BN_bin2bn(g_to_k, (int)length, NULL);
999 	c2 = BN_bin2bn(in, (int)length, NULL);
1000 	/* other bits */
1001 	p = pubkey->p;
1002 	x = seckey->x;
1003 	c1x = BN_new();
1004 	bndiv = BN_new();
1005 	m = BN_new();
1006 	tmp = BN_CTX_new();
1007 	if (!c1 || !c2 || !p || !x || !c1x || !bndiv || !m || !tmp) {
1008 		goto done;
1009 	}
1010 	/*
1011 	 * m = c2 / (c1^x)
1012 	 */
1013 	if (!BN_mod_exp(c1x, c1, x, p, tmp)) {
1014 		goto done;
1015 	}
1016 	if (!BN_mod_inverse(bndiv, c1x, p, tmp)) {
1017 		goto done;
1018 	}
1019 	if (!BN_mod_mul(m, c2, bndiv, p, tmp)) {
1020 		goto done;
1021 	}
1022 	/* result */
1023 	ret = BN_bn2bin(m, out);
1024 done:
1025 	if (tmp) {
1026 		BN_CTX_free(tmp);
1027 	}
1028 	if (m) {
1029 		BN_clear_free(m);
1030 	}
1031 	if (bndiv) {
1032 		BN_clear_free(bndiv);
1033 	}
1034 	if (c1x) {
1035 		BN_clear_free(c1x);
1036 	}
1037 	if (x) {
1038 		BN_clear_free(x);
1039 	}
1040 	if (p) {
1041 		BN_clear_free(p);
1042 	}
1043 	if (c1) {
1044 		BN_clear_free(c1);
1045 	}
1046 	if (c2) {
1047 		BN_clear_free(c2);
1048 	}
1049 	return ret;
1050 }
1051