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.32 2010/11/07 06:56:52 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
93static void
94test_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
112static int
113md5_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
126static void
127md5_add(pgp_hash_t *hash, const uint8_t *data, unsigned length)
128{
129	MD5_Update(hash->data, data, length);
130}
131
132static unsigned
133md5_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
141static 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*/
156void
157pgp_hash_md5(pgp_hash_t *hash)
158{
159	*hash = md5;
160}
161
162static int
163sha1_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
176static void
177sha1_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
185static unsigned
186sha1_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
197static 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*/
212void
213pgp_hash_sha1(pgp_hash_t *hash)
214{
215	*hash = sha1;
216}
217
218static int
219sha256_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
232static void
233sha256_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
241static unsigned
242sha256_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
253static 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
263void
264pgp_hash_sha256(pgp_hash_t *hash)
265{
266	*hash = sha256;
267}
268
269/*
270 * SHA384
271 */
272static int
273sha384_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
286static void
287sha384_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
295static unsigned
296sha384_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
307static 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
317void
318pgp_hash_sha384(pgp_hash_t *hash)
319{
320	*hash = sha384;
321}
322
323/*
324 * SHA512
325 */
326static int
327sha512_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
340static void
341sha512_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
349static unsigned
350sha512_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
361static 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
371void
372pgp_hash_sha512(pgp_hash_t *hash)
373{
374	*hash = sha512;
375}
376
377/*
378 * SHA224
379 */
380
381static int
382sha224_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
395static void
396sha224_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
404static unsigned
405sha224_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
416static 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
426void
427pgp_hash_sha224(pgp_hash_t *hash)
428{
429	*hash = sha224;
430}
431
432unsigned
433pgp_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*/
486int
487pgp_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*/
517int
518pgp_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*/
566int
567pgp_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*/
618int
619pgp_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*/
656void
657pgp_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*/
669const char     *
670pgp_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*/
684static unsigned
685rsa_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*/
796pgp_key_t  *
797pgp_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
814DSA_SIG        *
815pgp_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
838int
839openssl_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 */
896static int
897decide_k_bits(int p_bits)
898{
899	return (p_bits <= 5120) ? p_bits / 10 + 160 : (p_bits / 8 + 200) * 3 / 2;
900}
901
902int
903pgp_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 */
956done:
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
978int
979pgp_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);
1024done:
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