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