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