xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/openssl_crypto.c (revision 69d4f30f789bba62f419ef0c761a3970b87fb8b1)
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.27 2010/08/15 07:52:27 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 (hash->data) {
163 		(void) fprintf(stderr, "sha1_init: hash data non-null\n");
164 	}
165 	if ((hash->data = calloc(1, sizeof(SHA_CTX))) == NULL) {
166 		(void) fprintf(stderr, "sha1_init: bad alloc\n");
167 		return 0;
168 	}
169 	SHA1_Init(hash->data);
170 	return 1;
171 }
172 
173 static void
174 sha1_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
175 {
176 	if (__ops_get_debug_level(__FILE__)) {
177 		hexdump(stderr, "sha1_add", data, length);
178 	}
179 	SHA1_Update(hash->data, data, length);
180 }
181 
182 static unsigned
183 sha1_finish(__ops_hash_t *hash, uint8_t *out)
184 {
185 	SHA1_Final(out, hash->data);
186 	if (__ops_get_debug_level(__FILE__)) {
187 		hexdump(stderr, "sha1_finish", out, OPS_SHA1_HASH_SIZE);
188 	}
189 	free(hash->data);
190 	hash->data = NULL;
191 	return OPS_SHA1_HASH_SIZE;
192 }
193 
194 static const __ops_hash_t sha1 = {
195 	OPS_HASH_SHA1,
196 	OPS_SHA1_HASH_SIZE,
197 	"SHA1",
198 	sha1_init,
199 	sha1_add,
200 	sha1_finish,
201 	NULL
202 };
203 
204 /**
205    \ingroup Core_Crypto
206    \brief Initialise to SHA1
207    \param hash Hash to initialise
208 */
209 void
210 __ops_hash_sha1(__ops_hash_t *hash)
211 {
212 	*hash = sha1;
213 }
214 
215 static int
216 sha256_init(__ops_hash_t *hash)
217 {
218 	if (hash->data) {
219 		(void) fprintf(stderr, "sha256_init: hash data non-null\n");
220 	}
221 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
222 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
223 		return 0;
224 	}
225 	SHA256_Init(hash->data);
226 	return 1;
227 }
228 
229 static void
230 sha256_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
231 {
232 	if (__ops_get_debug_level(__FILE__)) {
233 		hexdump(stderr, "sha256_add", data, length);
234 	}
235 	SHA256_Update(hash->data, data, length);
236 }
237 
238 static unsigned
239 sha256_finish(__ops_hash_t *hash, uint8_t *out)
240 {
241 	SHA256_Final(out, hash->data);
242 	if (__ops_get_debug_level(__FILE__)) {
243 		hexdump(stderr, "sha1_finish", out, SHA256_DIGEST_LENGTH);
244 	}
245 	free(hash->data);
246 	hash->data = NULL;
247 	return SHA256_DIGEST_LENGTH;
248 }
249 
250 static const __ops_hash_t sha256 = {
251 	OPS_HASH_SHA256,
252 	SHA256_DIGEST_LENGTH,
253 	"SHA256",
254 	sha256_init,
255 	sha256_add,
256 	sha256_finish,
257 	NULL
258 };
259 
260 void
261 __ops_hash_sha256(__ops_hash_t *hash)
262 {
263 	*hash = sha256;
264 }
265 
266 /*
267  * SHA384
268  */
269 static int
270 sha384_init(__ops_hash_t *hash)
271 {
272 	if (hash->data) {
273 		(void) fprintf(stderr, "sha384_init: hash data non-null\n");
274 	}
275 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
276 		(void) fprintf(stderr, "sha384_init: bad alloc\n");
277 		return 0;
278 	}
279 	SHA384_Init(hash->data);
280 	return 1;
281 }
282 
283 static void
284 sha384_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
285 {
286 	if (__ops_get_debug_level(__FILE__)) {
287 		hexdump(stderr, "sha384_add", data, length);
288 	}
289 	SHA384_Update(hash->data, data, length);
290 }
291 
292 static unsigned
293 sha384_finish(__ops_hash_t *hash, uint8_t *out)
294 {
295 	SHA384_Final(out, hash->data);
296 	if (__ops_get_debug_level(__FILE__)) {
297 		hexdump(stderr, "sha384_finish", out, SHA384_DIGEST_LENGTH);
298 	}
299 	free(hash->data);
300 	hash->data = NULL;
301 	return SHA384_DIGEST_LENGTH;
302 }
303 
304 static const __ops_hash_t sha384 = {
305 	OPS_HASH_SHA384,
306 	SHA384_DIGEST_LENGTH,
307 	"SHA384",
308 	sha384_init,
309 	sha384_add,
310 	sha384_finish,
311 	NULL
312 };
313 
314 void
315 __ops_hash_sha384(__ops_hash_t *hash)
316 {
317 	*hash = sha384;
318 }
319 
320 /*
321  * SHA512
322  */
323 static int
324 sha512_init(__ops_hash_t *hash)
325 {
326 	if (hash->data) {
327 		(void) fprintf(stderr, "sha512_init: hash data non-null\n");
328 	}
329 	if ((hash->data = calloc(1, sizeof(SHA512_CTX))) == NULL) {
330 		(void) fprintf(stderr, "sha512_init: bad alloc\n");
331 		return 0;
332 	}
333 	SHA512_Init(hash->data);
334 	return 1;
335 }
336 
337 static void
338 sha512_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
339 {
340 	if (__ops_get_debug_level(__FILE__)) {
341 		hexdump(stderr, "sha512_add", data, length);
342 	}
343 	SHA512_Update(hash->data, data, length);
344 }
345 
346 static unsigned
347 sha512_finish(__ops_hash_t *hash, uint8_t *out)
348 {
349 	SHA512_Final(out, hash->data);
350 	if (__ops_get_debug_level(__FILE__)) {
351 		hexdump(stderr, "sha512_finish", out, SHA512_DIGEST_LENGTH);
352 	}
353 	free(hash->data);
354 	hash->data = NULL;
355 	return SHA512_DIGEST_LENGTH;
356 }
357 
358 static const __ops_hash_t sha512 = {
359 	OPS_HASH_SHA512,
360 	SHA512_DIGEST_LENGTH,
361 	"SHA512",
362 	sha512_init,
363 	sha512_add,
364 	sha512_finish,
365 	NULL
366 };
367 
368 void
369 __ops_hash_sha512(__ops_hash_t *hash)
370 {
371 	*hash = sha512;
372 }
373 
374 /*
375  * SHA224
376  */
377 
378 static int
379 sha224_init(__ops_hash_t *hash)
380 {
381 	if (hash->data) {
382 		(void) fprintf(stderr, "sha224_init: hash data non-null\n");
383 	}
384 	if ((hash->data = calloc(1, sizeof(SHA256_CTX))) == NULL) {
385 		(void) fprintf(stderr, "sha256_init: bad alloc\n");
386 		return 0;
387 	}
388 	SHA224_Init(hash->data);
389 	return 1;
390 }
391 
392 static void
393 sha224_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
394 {
395 	if (__ops_get_debug_level(__FILE__)) {
396 		hexdump(stderr, "sha224_add", data, length);
397 	}
398 	SHA224_Update(hash->data, data, length);
399 }
400 
401 static unsigned
402 sha224_finish(__ops_hash_t *hash, uint8_t *out)
403 {
404 	SHA224_Final(out, hash->data);
405 	if (__ops_get_debug_level(__FILE__)) {
406 		hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH);
407 	}
408 	free(hash->data);
409 	hash->data = NULL;
410 	return SHA224_DIGEST_LENGTH;
411 }
412 
413 static const __ops_hash_t sha224 = {
414 	OPS_HASH_SHA224,
415 	SHA224_DIGEST_LENGTH,
416 	"SHA224",
417 	sha224_init,
418 	sha224_add,
419 	sha224_finish,
420 	NULL
421 };
422 
423 void
424 __ops_hash_sha224(__ops_hash_t *hash)
425 {
426 	*hash = sha224;
427 }
428 
429 unsigned
430 __ops_dsa_verify(const uint8_t *hash, size_t hash_length,
431 	       const __ops_dsa_sig_t *sig,
432 	       const __ops_dsa_pubkey_t *dsa)
433 {
434 	unsigned	qlen;
435 	DSA_SIG        *osig;
436 	DSA            *odsa;
437 	int             ret;
438 
439 	osig = DSA_SIG_new();
440 	osig->r = sig->r;
441 	osig->s = sig->s;
442 
443 	odsa = DSA_new();
444 	odsa->p = dsa->p;
445 	odsa->q = dsa->q;
446 	odsa->g = dsa->g;
447 	odsa->pub_key = dsa->y;
448 
449 	if (__ops_get_debug_level(__FILE__)) {
450 		hexdump(stderr, "input hash", hash, hash_length);
451 		(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
452 	}
453 	if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
454 		hash_length = qlen;
455 	}
456 	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
457 	if (__ops_get_debug_level(__FILE__)) {
458 		(void) fprintf(stderr, "ret=%d\n", ret);
459 	}
460 	if (ret < 0) {
461 		(void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n");
462 		return 0;
463 	}
464 
465 	odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
466 	DSA_free(odsa);
467 
468 	osig->r = osig->s = NULL;
469 	DSA_SIG_free(osig);
470 
471 	return (unsigned)ret;
472 }
473 
474 /**
475    \ingroup Core_Crypto
476    \brief Recovers message digest from the signature
477    \param out Where to write decrypted data to
478    \param in Encrypted data
479    \param length Length of encrypted data
480    \param pubkey RSA public key
481    \return size of recovered message digest
482 */
483 int
484 __ops_rsa_public_decrypt(uint8_t *out,
485 			const uint8_t *in,
486 			size_t length,
487 			const __ops_rsa_pubkey_t *pubkey)
488 {
489 	RSA            *orsa;
490 	int             n;
491 
492 	orsa = RSA_new();
493 	orsa->n = pubkey->n;
494 	orsa->e = pubkey->e;
495 
496 	n = RSA_public_decrypt((int)length, in, out, orsa, RSA_NO_PADDING);
497 
498 	orsa->n = orsa->e = NULL;
499 	RSA_free(orsa);
500 
501 	return n;
502 }
503 
504 /**
505    \ingroup Core_Crypto
506    \brief Signs data with RSA
507    \param out Where to write signature
508    \param in Data to sign
509    \param length Length of data
510    \param seckey RSA secret key
511    \param pubkey RSA public key
512    \return number of bytes decrypted
513 */
514 int
515 __ops_rsa_private_encrypt(uint8_t *out,
516 			const uint8_t *in,
517 			size_t length,
518 			const __ops_rsa_seckey_t *seckey,
519 			const __ops_rsa_pubkey_t *pubkey)
520 {
521 	RSA            *orsa;
522 	int             n;
523 
524 	orsa = RSA_new();
525 	orsa->n = BN_dup(pubkey->n);
526 	orsa->d = seckey->d;
527 	orsa->p = seckey->q;
528 	orsa->q = seckey->p;
529 
530 	/* debug */
531 	orsa->e = BN_dup(pubkey->e);
532 	/* If this isn't set, it's very likely that the programmer hasn't */
533 	/* decrypted the secret key. RSA_check_key segfaults in that case. */
534 	/* Use __ops_decrypt_seckey() to do that. */
535 	if (orsa->d == NULL) {
536 		(void) fprintf(stderr, "orsa is not set\n");
537 		return 0;
538 	}
539 	if (RSA_check_key(orsa) != 1) {
540 		(void) fprintf(stderr, "RSA_check_key is not set\n");
541 		return 0;
542 	}
543 	/* end debug */
544 
545 	n = RSA_private_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
546 
547 	orsa->n = orsa->d = orsa->p = orsa->q = NULL;
548 	RSA_free(orsa);
549 
550 	return n;
551 }
552 
553 /**
554 \ingroup Core_Crypto
555 \brief Decrypts RSA-encrypted data
556 \param out Where to write the plaintext
557 \param in Encrypted data
558 \param length Length of encrypted data
559 \param seckey RSA secret key
560 \param pubkey RSA public key
561 \return size of recovered plaintext
562 */
563 int
564 __ops_rsa_private_decrypt(uint8_t *out,
565 			const uint8_t *in,
566 			size_t length,
567 			const __ops_rsa_seckey_t *seckey,
568 			const __ops_rsa_pubkey_t *pubkey)
569 {
570 	RSA            *keypair;
571 	int             n;
572 	char            errbuf[1024];
573 
574 	keypair = RSA_new();
575 	keypair->n = pubkey->n;	/* XXX: do we need n? */
576 	keypair->d = seckey->d;
577 	keypair->p = seckey->q;
578 	keypair->q = seckey->p;
579 
580 	/* debug */
581 	keypair->e = pubkey->e;
582 	if (RSA_check_key(keypair) != 1) {
583 		(void) fprintf(stderr, "RSA_check_key is not set\n");
584 		return 0;
585 	}
586 	/* end debug */
587 
588 	n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
589 
590 	if (__ops_get_debug_level(__FILE__)) {
591 		printf("__ops_rsa_private_decrypt: n=%d\n",n);
592 	}
593 
594 	errbuf[0] = '\0';
595 	if (n == -1) {
596 		unsigned long   err = ERR_get_error();
597 
598 		ERR_error_string(err, &errbuf[0]);
599 		(void) fprintf(stderr, "openssl error : %s\n", errbuf);
600 	}
601 	keypair->n = keypair->d = keypair->p = keypair->q = NULL;
602 	RSA_free(keypair);
603 
604 	return n;
605 }
606 
607 /**
608    \ingroup Core_Crypto
609    \brief RSA-encrypts data
610    \param out Where to write the encrypted data
611    \param in Plaintext
612    \param length Size of plaintext
613    \param pubkey RSA Public Key
614 */
615 int
616 __ops_rsa_public_encrypt(uint8_t *out,
617 			const uint8_t *in,
618 			size_t length,
619 			const __ops_rsa_pubkey_t *pubkey)
620 {
621 	RSA            *orsa;
622 	int             n;
623 
624 	/* printf("__ops_rsa_public_encrypt: length=%ld\n", length); */
625 
626 	orsa = RSA_new();
627 	orsa->n = pubkey->n;
628 	orsa->e = pubkey->e;
629 
630 	/* printf("len: %ld\n", length); */
631 	/* __ops_print_bn("n: ", orsa->n); */
632 	/* __ops_print_bn("e: ", orsa->e); */
633 	n = RSA_public_encrypt((int)length, in, out, orsa, RSA_NO_PADDING);
634 
635 	if (n == -1) {
636 		BIO            *fd_out;
637 
638 		fd_out = BIO_new_fd(fileno(stderr), BIO_NOCLOSE);
639 		ERR_print_errors(fd_out);
640 	}
641 	orsa->n = orsa->e = NULL;
642 	RSA_free(orsa);
643 
644 	return n;
645 }
646 
647 /**
648    \ingroup Core_Crypto
649    \brief Finalise openssl
650    \note Would usually call __ops_finish() instead
651    \sa __ops_finish()
652 */
653 void
654 __ops_crypto_finish(void)
655 {
656 	CRYPTO_cleanup_all_ex_data();
657 	ERR_remove_state((unsigned long)0);
658 }
659 
660 /**
661    \ingroup Core_Hashes
662    \brief Get Hash name
663    \param hash Hash struct
664    \return Hash name
665 */
666 const char     *
667 __ops_text_from_hash(__ops_hash_t *hash)
668 {
669 	return hash->name;
670 }
671 
672 /**
673  \ingroup HighLevel_KeyGenerate
674  \brief Generates an RSA keypair
675  \param numbits Modulus size
676  \param e Public Exponent
677  \param keydata Pointer to keydata struct to hold new key
678  \return 1 if key generated successfully; otherwise 0
679  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
680 */
681 static unsigned
682 rsa_generate_keypair(__ops_key_t *keydata,
683 			const int numbits,
684 			const unsigned long e,
685 			const char *hashalg)
686 {
687 	__ops_seckey_t *seckey;
688 	RSA            *rsa;
689 	BN_CTX         *ctx;
690 	__ops_output_t *output;
691 	__ops_memory_t   *mem;
692 
693 	ctx = BN_CTX_new();
694 	__ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY);
695 	seckey = __ops_get_writable_seckey(keydata);
696 
697 	/* generate the key pair */
698 
699 	rsa = RSA_generate_key(numbits, e, NULL, NULL);
700 
701 	/* populate __ops key from ssl key */
702 
703 	seckey->pubkey.version = OPS_V4;
704 	seckey->pubkey.birthtime = time(NULL);
705 	seckey->pubkey.days_valid = 0;
706 	seckey->pubkey.alg = OPS_PKA_RSA;
707 
708 	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
709 	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);
710 
711 	seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED;
712 	seckey->s2k_specifier = OPS_S2KS_SALTED;
713 	/* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */
714 	seckey->alg = OPS_SA_CAST5;	/* \todo make param */
715 	if ((seckey->hash_alg = __ops_str_to_hash_alg(hashalg)) == OPS_HASH_UNKNOWN) {
716 		seckey->hash_alg = OPS_HASH_SHA1;
717 	}
718 	seckey->octetc = 0;
719 	seckey->checksum = 0;
720 
721 	seckey->key.rsa.d = BN_dup(rsa->d);
722 	seckey->key.rsa.p = BN_dup(rsa->p);
723 	seckey->key.rsa.q = BN_dup(rsa->q);
724 	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
725 	if (seckey->key.rsa.u == NULL) {
726 		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
727 		return 0;
728 	}
729 	BN_CTX_free(ctx);
730 
731 	RSA_free(rsa);
732 
733 	__ops_keyid(keydata->sigid, OPS_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
734 	__ops_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);
735 
736 	/* Generate checksum */
737 
738 	output = NULL;
739 	mem = NULL;
740 
741 	__ops_setup_memory_write(&output, &mem, 128);
742 
743 	__ops_push_checksum_writer(output, seckey);
744 
745 	switch (seckey->pubkey.alg) {
746 	case OPS_PKA_DSA:
747 		return __ops_write_mpi(output, seckey->key.dsa.x);
748 	case OPS_PKA_RSA:
749 	case OPS_PKA_RSA_ENCRYPT_ONLY:
750 	case OPS_PKA_RSA_SIGN_ONLY:
751 		if (!__ops_write_mpi(output, seckey->key.rsa.d) ||
752 		    !__ops_write_mpi(output, seckey->key.rsa.p) ||
753 		    !__ops_write_mpi(output, seckey->key.rsa.q) ||
754 		    !__ops_write_mpi(output, seckey->key.rsa.u)) {
755 			return 0;
756 		}
757 		break;
758 	case OPS_PKA_ELGAMAL:
759 		return __ops_write_mpi(output, seckey->key.elgamal.x);
760 
761 	default:
762 		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
763 		return 0;
764 	}
765 
766 	/* close rather than pop, since its the only one on the stack */
767 	__ops_writer_close(output);
768 	__ops_teardown_memory_write(output, mem);
769 
770 	/* should now have checksum in seckey struct */
771 
772 	/* test */
773 	if (__ops_get_debug_level(__FILE__)) {
774 		test_seckey(seckey);
775 	}
776 
777 	return 1;
778 }
779 
780 /**
781  \ingroup HighLevel_KeyGenerate
782  \brief Creates a self-signed RSA keypair
783  \param numbits Modulus size
784  \param e Public Exponent
785  \param userid User ID
786  \return The new keypair or NULL
787 
788  \note It is the caller's responsibility to call __ops_keydata_free(keydata)
789  \sa rsa_generate_keypair()
790  \sa __ops_keydata_free()
791 */
792 __ops_key_t  *
793 __ops_rsa_new_selfsign_key(const int numbits,
794 				const unsigned long e,
795 				uint8_t *userid,
796 				const char *hashalg)
797 {
798 	__ops_key_t  *keydata;
799 
800 	keydata = __ops_keydata_new();
801 	if (!rsa_generate_keypair(keydata, numbits, e, hashalg) ||
802 	    !__ops_add_selfsigned_userid(keydata, userid)) {
803 		__ops_keydata_free(keydata);
804 		return NULL;
805 	}
806 	return keydata;
807 }
808 
809 DSA_SIG        *
810 __ops_dsa_sign(uint8_t *hashbuf,
811 		unsigned hashsize,
812 		const __ops_dsa_seckey_t *secdsa,
813 		const __ops_dsa_pubkey_t *pubdsa)
814 {
815 	DSA_SIG        *dsasig;
816 	DSA            *odsa;
817 
818 	odsa = DSA_new();
819 	odsa->p = pubdsa->p;
820 	odsa->q = pubdsa->q;
821 	odsa->g = pubdsa->g;
822 	odsa->pub_key = pubdsa->y;
823 	odsa->priv_key = secdsa->x;
824 
825 	dsasig = DSA_do_sign(hashbuf, (int)hashsize, odsa);
826 
827 	odsa->p = odsa->q = odsa->g = odsa->pub_key = odsa->priv_key = NULL;
828 	DSA_free(odsa);
829 
830 	return dsasig;
831 }
832 
833 int
834 openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose)
835 {
836 	FILE	*fp;
837 	DSA	*dsa;
838 	RSA	*rsa;
839 	int	 ok;
840 
841 	if ((fp = fopen(f, "r")) == NULL) {
842 		if (verbose) {
843 			(void) fprintf(stderr, "can't open '%s'\n", f);
844 		}
845 		return 0;
846 	}
847 	ok = 1;
848 	if (strcmp(type, "ssh-rsa") == 0) {
849 		if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
850 			ok = 0;
851 		} else {
852 			key->key.seckey.key.rsa.d = rsa->d;
853 			key->key.seckey.key.rsa.p = rsa->p;
854 			key->key.seckey.key.rsa.q = rsa->q;
855 			key->key.seckey.key.rsa.d = rsa->d;
856 		}
857 	} else if (strcmp(type, "ssh-dss") == 0) {
858 		if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) {
859 			ok = 0;
860 		} else {
861 			key->key.seckey.key.dsa.x = dsa->priv_key;
862 		}
863 	} else {
864 		ok = 0;
865 	}
866 	(void) fclose(fp);
867 	return ok;
868 }
869