xref: /freebsd/contrib/ntp/util/ntp-keygen.c (revision 2be1a816b9ff69588e55be0a84cbe2a31efc0f2f)
1 /*
2  * Program to generate cryptographic keys for NTP clients and servers
3  *
4  * This program generates files "ntpkey_<type>_<hostname>.<filestamp>",
5  * where <type> is the file type, <hostname> is the generating host and
6  * <filestamp> is the NTP seconds in decimal format. The NTP programs
7  * expect generic names such as "ntpkey_<type>_whimsy.udel.edu" with the
8  * association maintained by soft links.
9  *
10  * Files are prefixed with a header giving the name and date of creation
11  * followed by a type-specific descriptive label and PEM-encoded data
12  * string compatible with programs of the OpenSSL library.
13  *
14  * Note that private keys can be password encrypted as per OpenSSL
15  * conventions.
16  *
17  * The file types include
18  *
19  * ntpkey_MD5key_<hostname>.<filestamp>
20  * 	MD5 (128-bit) keys used to compute message digests in symmetric
21  *	key cryptography
22  *
23  * ntpkey_RSAkey_<hostname>.<filestamp>
24  * ntpkey_host_<hostname> (RSA) link
25  *	RSA private/public host key pair used for public key signatures
26  *	and data encryption
27  *
28  * ntpkey_DSAkey_<hostname>.<filestamp>
29  * ntpkey_sign_<hostname> (RSA or DSA) link
30  *	DSA private/public sign key pair used for public key signatures,
31  *	but not data encryption
32  *
33  * ntpkey_IFFpar_<hostname>.<filestamp>
34  * ntpkey_iff_<hostname> (IFF server/client) link
35  * ntpkey_iffkey_<hostname> (IFF client) link
36  *	Schnorr (IFF) server/client identity parameters
37  *
38  * ntpkey_IFFkey_<hostname>.<filestamp>
39  *	Schnorr (IFF) client identity parameters
40  *
41  * ntpkey_GQpar_<hostname>.<filestamp>,
42  * ntpkey_gq_<hostname> (GQ) link
43  *	Guillou-Quisquater (GQ) identity parameters
44  *
45  * ntpkey_MVpar_<hostname>.<filestamp>,
46  *	Mu-Varadharajan (MV) server identity parameters
47  *
48  * ntpkey_MVkeyX_<hostname>.<filestamp>,
49  * ntpkey_mv_<hostname> (MV server) link
50  * ntpkey_mvkey_<hostname> (MV client) link
51  *	Mu-Varadharajan (MV) client identity parameters
52  *
53  * ntpkey_XXXcert_<hostname>.<filestamp>
54  * ntpkey_cert_<hostname> (RSA or DSA) link
55  *	X509v3 certificate using RSA or DSA public keys and signatures.
56  *	XXX is a code identifying the message digest and signature
57  *	encryption algorithm
58  *
59  * Available digest/signature schemes
60  *
61  * RSA:	RSA-MD2, RSA-MD5, RSA-SHA, RSA-SHA1, RSA-MDC2, EVP-RIPEMD160
62  * DSA:	DSA-SHA, DSA-SHA1
63  *
64  * Note: Once in a while because of some statistical fluke this program
65  * fails to generate and verify some cryptographic data, as indicated by
66  * exit status -1. In this case simply run the program again. If the
67  * program does complete with return code 0, the data are correct as
68  * verified.
69  *
70  * These cryptographic routines are characterized by the prime modulus
71  * size in bits. The default value of 512 bits is a compromise between
72  * cryptographic strength and computing time and is ordinarily
73  * considered adequate for this application. The routines have been
74  * tested with sizes of 256, 512, 1024 and 2048 bits. Not all message
75  * digest and signature encryption schemes work with sizes less than 512
76  * bits. The computing time for sizes greater than 2048 bits is
77  * prohibitive on all but the fastest processors. An UltraSPARC Blade
78  * 1000 took something over nine minutes to generate and verify the
79  * values with size 2048. An old SPARC IPC would take a week.
80  *
81  * The OpenSSL library used by this program expects a random seed file.
82  * As described in the OpenSSL documentation, the file name defaults to
83  * first the RANDFILE environment variable in the user's home directory
84  * and then .rnd in the user's home directory.
85  */
86 #ifdef HAVE_CONFIG_H
87 # include <config.h>
88 #endif
89 #include <string.h>
90 #include <stdio.h>
91 #include <stdlib.h>
92 #include <unistd.h>
93 #include <sys/stat.h>
94 #include <sys/time.h>
95 #if HAVE_SYS_TYPES_H
96 # include <sys/types.h>
97 #endif
98 #include "ntp_types.h"
99 #include "l_stdlib.h"
100 
101 #ifdef SYS_WINNT
102 extern	int	ntp_getopt	P((int, char **, const char *));
103 #define getopt ntp_getopt
104 #define optarg ntp_optarg
105 #endif
106 
107 #ifdef OPENSSL
108 #include "openssl/bn.h"
109 #include "openssl/evp.h"
110 #include "openssl/err.h"
111 #include "openssl/rand.h"
112 #include "openssl/pem.h"
113 #include "openssl/x509v3.h"
114 #include <openssl/objects.h>
115 #endif /* OPENSSL */
116 
117 /*
118  * Cryptodefines
119  */
120 #define	MD5KEYS		16	/* number of MD5 keys generated */
121 #define	JAN_1970	ULONG_CONST(2208988800) /* NTP seconds */
122 #define YEAR		((long)60*60*24*365) /* one year in seconds */
123 #define MAXFILENAME	256	/* max file name length */
124 #define MAXHOSTNAME	256	/* max host name length */
125 #ifdef OPENSSL
126 #define	PLEN		512	/* default prime modulus size (bits) */
127 
128 /*
129  * Strings used in X509v3 extension fields
130  */
131 #define KEY_USAGE		"digitalSignature,keyCertSign"
132 #define BASIC_CONSTRAINTS	"critical,CA:TRUE"
133 #define EXT_KEY_PRIVATE		"private"
134 #define EXT_KEY_TRUST		"trustRoot"
135 #endif /* OPENSSL */
136 
137 /*
138  * Prototypes
139  */
140 FILE	*fheader	P((const char *, const char *));
141 void	fslink		P((const char *, const char *));
142 int	gen_md5		P((char *));
143 #ifdef OPENSSL
144 EVP_PKEY *gen_rsa	P((char *));
145 EVP_PKEY *gen_dsa	P((char *));
146 EVP_PKEY *gen_iff	P((char *));
147 EVP_PKEY *gen_gqpar	P((char *));
148 EVP_PKEY *gen_gqkey	P((char *, EVP_PKEY *));
149 EVP_PKEY *gen_mv	P((char *));
150 int	x509		P((EVP_PKEY *, const EVP_MD *, char *, char *));
151 void	cb		P((int, int, void *));
152 EVP_PKEY *genkey	P((char *, char *));
153 u_long	asn2ntp		P((ASN1_TIME *));
154 #endif /* OPENSSL */
155 
156 /*
157  * Program variables
158  */
159 extern char *optarg;		/* command line argument */
160 int	debug = 0;		/* debug, not de bug */
161 int	rval;			/* return status */
162 #ifdef OPENSSL
163 u_int	modulus = PLEN;		/* prime modulus size (bits) */
164 #endif
165 int	nkeys = 0;		/* MV keys */
166 time_t	epoch;			/* Unix epoch (seconds) since 1970 */
167 char	*hostname;		/* host name (subject name) */
168 char	*trustname;		/* trusted host name (issuer name) */
169 char	filename[MAXFILENAME + 1]; /* file name */
170 char	*passwd1 = NULL;	/* input private key password */
171 char	*passwd2 = NULL;	/* output private key password */
172 #ifdef OPENSSL
173 long	d0, d1, d2, d3;		/* callback counters */
174 #endif /* OPENSSL */
175 
176 #ifdef SYS_WINNT
177 BOOL init_randfile();
178 
179 /*
180  * Don't try to follow symbolic links
181  */
182 int
183 readlink(char * link, char * file, int len) {
184 	return (-1);
185 }
186 /*
187  * Don't try to create a symbolic link for now.
188  * Just move the file to the name you need.
189  */
190 int
191 symlink(char *filename, char *linkname) {
192 	DeleteFile(linkname);
193 	MoveFile(filename, linkname);
194 	return 0;
195 }
196 void
197 InitWin32Sockets() {
198 	WORD wVersionRequested;
199 	WSADATA wsaData;
200 	wVersionRequested = MAKEWORD(2,0);
201 	if (WSAStartup(wVersionRequested, &wsaData))
202 	{
203 		fprintf(stderr, "No useable winsock.dll");
204 		exit(1);
205 	}
206 }
207 #endif /* SYS_WINNT */
208 
209 /*
210  * Main program
211  */
212 int
213 main(
214 	int	argc,		/* command line options */
215 	char	**argv
216 	)
217 {
218 	struct timeval tv;	/* initialization vector */
219 #ifdef OPENSSL
220 	X509	*cert = NULL;	/* X509 certificate */
221 	EVP_PKEY *pkey_host = NULL; /* host key */
222 	EVP_PKEY *pkey_sign = NULL; /* sign key */
223 	EVP_PKEY *pkey_iff = NULL; /* IFF parameters */
224 	EVP_PKEY *pkey_gq = NULL; /* GQ parameters */
225 	EVP_PKEY *pkey_mv = NULL; /* MV parameters */
226 #endif
227 	int	md5key = 0;	/* generate MD5 keys */
228 #ifdef OPENSSL
229 	int	hostkey = 0;	/* generate RSA keys */
230 	int	iffkey = 0;	/* generate IFF parameters */
231 	int	gqpar = 0;	/* generate GQ parameters */
232 	int	gqkey = 0;	/* update GQ keys */
233 	int	mvpar = 0;	/* generate MV parameters */
234 	int	mvkey = 0;	/* update MV keys */
235 	char	*sign = NULL;	/* sign key */
236 	EVP_PKEY *pkey = NULL;	/* temp key */
237 	const EVP_MD *ectx;	/* EVP digest */
238 	char	pathbuf[MAXFILENAME + 1];
239 	const char *scheme = NULL; /* digest/signature scheme */
240 	char	*exten = NULL;	/* private extension */
241 	char	*grpkey = NULL;	/* identity extension */
242 	int	nid;		/* X509 digest/signature scheme */
243 	FILE	*fstr = NULL;	/* file handle */
244 	int	iffsw = 0;	/* IFF key switch */
245 #endif /* OPENSSL */
246 	char	hostbuf[MAXHOSTNAME + 1];
247 	u_int	temp;
248 
249 #ifdef SYS_WINNT
250 	/* Initialize before OpenSSL checks */
251 	InitWin32Sockets();
252 	if(!init_randfile())
253 		fprintf(stderr, "Unable to initialize .rnd file\n");
254 #endif
255 
256 #ifdef OPENSSL
257 	if (SSLeay() != OPENSSL_VERSION_NUMBER) {
258 		fprintf(stderr,
259 		    "OpenSSL version mismatch. Built against %lx, you have %lx\n",
260 		    OPENSSL_VERSION_NUMBER, SSLeay());
261 		return (-1);
262 
263 	} else {
264 		fprintf(stderr,
265 		    "Using OpenSSL version %lx\n", SSLeay());
266 	}
267 #endif /* OPENSSL */
268 
269 	/*
270 	 * Process options, initialize host name and timestamp.
271 	 */
272 	gethostname(hostbuf, MAXHOSTNAME);
273 	hostname = hostbuf;
274 #ifdef OPENSSL
275 	trustname = hostbuf;
276 	passwd1 = hostbuf;
277 #endif
278 #ifndef SYS_WINNT
279 	gettimeofday(&tv, 0);
280 #else
281 	gettimeofday(&tv);
282 #endif
283 	epoch = tv.tv_sec;
284 	rval = 0;
285 	while ((temp = getopt(argc, argv,
286 #ifdef OPENSSL
287 	    "c:deGgHIi:Mm:nPp:q:S:s:TV:v:"
288 #else
289 	    "dM"
290 #endif
291 	    )) != -1) {
292 		switch(temp) {
293 
294 #ifdef OPENSSL
295 		/*
296 		 * -c select public certificate type
297 		 */
298 		case 'c':
299 			scheme = optarg;
300 			continue;
301 #endif
302 
303 		/*
304 		 * -d debug
305 		 */
306 		case 'd':
307 			debug++;
308 			continue;
309 
310 #ifdef OPENSSL
311 		/*
312 		 * -e write identity keys
313 		 */
314 		case 'e':
315 			iffsw++;
316 			continue;
317 #endif
318 
319 #ifdef OPENSSL
320 		/*
321 		 * -G generate GQ parameters and keys
322 		 */
323 		case 'G':
324 			gqpar++;
325 			continue;
326 #endif
327 
328 #ifdef OPENSSL
329 		/*
330 		 * -g update GQ keys
331 		 */
332 		case 'g':
333 			gqkey++;
334 			continue;
335 #endif
336 
337 #ifdef OPENSSL
338 		/*
339 		 * -H generate host key (RSA)
340 		 */
341 		case 'H':
342 			hostkey++;
343 			continue;
344 #endif
345 
346 #ifdef OPENSSL
347 		/*
348 		 * -I generate IFF parameters
349 		 */
350 		case 'I':
351 			iffkey++;
352 			continue;
353 #endif
354 
355 #ifdef OPENSSL
356 		/*
357 		 * -i set issuer name
358 		 */
359 		case 'i':
360 			trustname = optarg;
361 			continue;
362 #endif
363 
364 		/*
365 		 * -M generate MD5 keys
366 		 */
367 		case 'M':
368 			md5key++;
369 			continue;
370 
371 #ifdef OPENSSL
372 		/*
373 		 * -m select modulus (256-2048)
374 		 */
375 		case 'm':
376 			if (sscanf(optarg, "%d", &modulus) != 1)
377 				fprintf(stderr,
378 				    "invalid option -m %s\n", optarg);
379 			continue;
380 #endif
381 
382 #ifdef OPENSSL
383 		/*
384 		 * -P generate PC private certificate
385 		 */
386 		case 'P':
387 			exten = EXT_KEY_PRIVATE;
388 			continue;
389 #endif
390 
391 #ifdef OPENSSL
392 		/*
393 		 * -p output private key password
394 		 */
395 		case 'p':
396 			passwd2 = optarg;
397 			continue;
398 #endif
399 
400 #ifdef OPENSSL
401 		/*
402 		 * -q input private key password
403 		 */
404 		case 'q':
405 			passwd1 = optarg;
406 			continue;
407 #endif
408 
409 #ifdef OPENSSL
410 		/*
411 		 * -S generate sign key (RSA or DSA)
412 		 */
413 		case 'S':
414 			sign = optarg;
415 			continue;
416 #endif
417 
418 #ifdef OPENSSL
419 		/*
420 		 * -s set subject name
421 		 */
422 		case 's':
423 			hostname = optarg;
424 			continue;
425 #endif
426 
427 #ifdef OPENSSL
428 		/*
429 		 * -T trusted certificate (TC scheme)
430 		 */
431 		case 'T':
432 			exten = EXT_KEY_TRUST;
433 			continue;
434 #endif
435 
436 #ifdef OPENSSL
437 		/*
438 		 * -V <keys> generate MV parameters
439 		 */
440 		case 'V':
441 			mvpar++;
442 			if (sscanf(optarg, "%d", &nkeys) != 1)
443 				fprintf(stderr,
444 				    "invalid option -V %s\n", optarg);
445 			continue;
446 #endif
447 
448 #ifdef OPENSSL
449 		/*
450 		 * -v <key> update MV keys
451 		 */
452 		case 'v':
453 			mvkey++;
454 			if (sscanf(optarg, "%d", &nkeys) != 1)
455 				fprintf(stderr,
456 				    "invalid option -v %s\n", optarg);
457 			continue;
458 #endif
459 
460 		/*
461 		 * None of the above.
462 		 */
463 		default:
464 			fprintf(stderr, "Option ignored\n");
465 			continue;
466 		}
467 	}
468 
469 	if (passwd1 != NULL && passwd2 == NULL)
470 		passwd2 = passwd1;
471 #ifdef OPENSSL
472 	/*
473 	 * Seed random number generator and grow weeds.
474 	 */
475 	ERR_load_crypto_strings();
476 	OpenSSL_add_all_algorithms();
477 	if (RAND_file_name(pathbuf, MAXFILENAME) == NULL) {
478 		fprintf(stderr, "RAND_file_name %s\n",
479 		    ERR_error_string(ERR_get_error(), NULL));
480 		return (-1);
481 	}
482 	temp = RAND_load_file(pathbuf, -1);
483 	if (temp == 0) {
484 		fprintf(stderr,
485 		    "RAND_load_file %s not found or empty\n", pathbuf);
486 		return (-1);
487 	}
488 	fprintf(stderr,
489 	    "Random seed file %s %u bytes\n", pathbuf, temp);
490 	RAND_add(&epoch, sizeof(epoch), 4.0);
491 #endif
492 
493 	/*
494 	 * Generate new parameters and keys as requested. These replace
495 	 * any values already generated.
496 	 */
497 	if (md5key)
498 		gen_md5("MD5");
499 #ifdef OPENSSL
500 	if (hostkey)
501 		pkey_host = genkey("RSA", "host");
502 	if (sign != NULL)
503 		pkey_sign = genkey(sign, "sign");
504 	if (iffkey)
505 		pkey_iff = gen_iff("iff");
506 	if (gqpar)
507 		pkey_gq = gen_gqpar("gq");
508 	if (mvpar)
509 		pkey_mv = gen_mv("mv");
510 
511 	/*
512 	 * If there is no new host key, look for an existing one. If not
513 	 * found, create it.
514 	 */
515 	while (pkey_host == NULL && rval == 0 && !iffsw) {
516 		sprintf(filename, "ntpkey_host_%s", hostname);
517 		if ((fstr = fopen(filename, "r")) != NULL) {
518 			pkey_host = PEM_read_PrivateKey(fstr, NULL,
519 			    NULL, passwd1);
520 			fclose(fstr);
521 			readlink(filename, filename,  sizeof(filename));
522 			if (pkey_host == NULL) {
523 				fprintf(stderr, "Host key\n%s\n",
524 				    ERR_error_string(ERR_get_error(),
525 				    NULL));
526 				rval = -1;
527 			} else {
528 				fprintf(stderr,
529 				    "Using host key %s\n", filename);
530 			}
531 			break;
532 
533 		} else if ((pkey_host = genkey("RSA", "host")) ==
534 		    NULL) {
535 			rval = -1;
536 			break;
537 		}
538 	}
539 
540 	/*
541 	 * If there is no new sign key, look for an existing one. If not
542 	 * found, use the host key instead.
543 	 */
544 	pkey = pkey_sign;
545 	while (pkey_sign == NULL && rval == 0 && !iffsw) {
546 		sprintf(filename, "ntpkey_sign_%s", hostname);
547 		if ((fstr = fopen(filename, "r")) != NULL) {
548 			pkey_sign = PEM_read_PrivateKey(fstr, NULL,
549 			    NULL, passwd1);
550 			fclose(fstr);
551 			readlink(filename, filename, sizeof(filename));
552 			if (pkey_sign == NULL) {
553 				fprintf(stderr, "Sign key\n%s\n",
554 				    ERR_error_string(ERR_get_error(),
555 				    NULL));
556 				rval = -1;
557 			} else {
558 				fprintf(stderr, "Using sign key %s\n",
559 				    filename);
560 			}
561 			break;
562 		} else {
563 			pkey = pkey_host;
564 			fprintf(stderr, "Using host key as sign key\n");
565 			break;
566 		}
567 	}
568 
569 	/*
570 	 * If there is no new IFF file, look for an existing one.
571 	 */
572 	if (pkey_iff == NULL && rval == 0) {
573 		sprintf(filename, "ntpkey_iff_%s", hostname);
574 		if ((fstr = fopen(filename, "r")) != NULL) {
575 			pkey_iff = PEM_read_PrivateKey(fstr, NULL,
576 			    NULL, passwd1);
577 			fclose(fstr);
578 			readlink(filename, filename, sizeof(filename));
579 			if (pkey_iff == NULL) {
580 				fprintf(stderr, "IFF parameters\n%s\n",
581 				    ERR_error_string(ERR_get_error(),
582 				    NULL));
583 				rval = -1;
584 			} else {
585 				fprintf(stderr,
586 				    "Using IFF parameters %s\n",
587 				    filename);
588 			}
589 		}
590 	}
591 
592 	/*
593 	 * If there is no new GQ file, look for an existing one.
594 	 */
595 	if (pkey_gq == NULL && rval == 0 && !iffsw) {
596 		sprintf(filename, "ntpkey_gq_%s", hostname);
597 		if ((fstr = fopen(filename, "r")) != NULL) {
598 			pkey_gq = PEM_read_PrivateKey(fstr, NULL, NULL,
599 			    passwd1);
600 			fclose(fstr);
601 			readlink(filename, filename, sizeof(filename));
602 			if (pkey_gq == NULL) {
603 				fprintf(stderr, "GQ parameters\n%s\n",
604 				    ERR_error_string(ERR_get_error(),
605 				    NULL));
606 				rval = -1;
607 			} else {
608 				fprintf(stderr,
609 				    "Using GQ parameters %s\n",
610 				    filename);
611 			}
612 		}
613 	}
614 
615 	/*
616 	 * If there is a GQ parameter file, create GQ private/public
617 	 * keys and extract the public key for the certificate.
618 	 */
619 	if (pkey_gq != NULL && rval == 0) {
620 		gen_gqkey("gq", pkey_gq);
621 		grpkey = BN_bn2hex(pkey_gq->pkey.rsa->q);
622 	}
623 
624 	/*
625 	 * Generate a X509v3 certificate.
626 	 */
627 	while (scheme == NULL && rval == 0 && !iffsw) {
628 		sprintf(filename, "ntpkey_cert_%s", hostname);
629 		if ((fstr = fopen(filename, "r")) != NULL) {
630 			cert = PEM_read_X509(fstr, NULL, NULL, NULL);
631 			fclose(fstr);
632 			readlink(filename, filename, sizeof(filename));
633 			if (cert == NULL) {
634 				fprintf(stderr, "Cert \n%s\n",
635 				    ERR_error_string(ERR_get_error(),
636 				    NULL));
637 				rval = -1;
638 			} else {
639 				nid = OBJ_obj2nid(
640 				 cert->cert_info->signature->algorithm);
641 				scheme = OBJ_nid2sn(nid);
642 				fprintf(stderr,
643 				    "Using scheme %s from %s\n", scheme,
644 				     filename);
645 				break;
646 			}
647 		}
648 		scheme = "RSA-MD5";
649 	}
650 	if (pkey != NULL && rval == 0 && !iffsw) {
651 		ectx = EVP_get_digestbyname(scheme);
652 		if (ectx == NULL) {
653 			fprintf(stderr,
654 			    "Invalid digest/signature combination %s\n",
655 			    scheme);
656 			rval = -1;
657 		} else {
658 			x509(pkey, ectx, grpkey, exten);
659 		}
660 	}
661 
662 	/*
663 	 * Write the IFF client parameters and keys as a DSA private key
664 	 * encoded in PEM. Note the private key is obscured.
665 	 */
666 	if (pkey_iff != NULL && rval == 0 && iffsw) {
667 		DSA	*dsa;
668 		char	*sptr;
669 
670 		sptr = strrchr(filename, '.');
671 		sprintf(filename, "ntpkey_IFFkey_%s.%s", trustname,
672 		    ++sptr);
673 		fprintf(stderr, "Writing new IFF key %s\n", filename);
674 		fprintf(stdout, "# %s\n# %s", filename, ctime(&epoch));
675 		dsa = pkey_iff->pkey.dsa;
676 		BN_copy(dsa->priv_key, BN_value_one());
677 		pkey = EVP_PKEY_new();
678 		EVP_PKEY_assign_DSA(pkey, dsa);
679 		PEM_write_PrivateKey(stdout, pkey, passwd2 ?
680 		    EVP_des_cbc() : NULL, NULL, 0, NULL, passwd2);
681 		fclose(stdout);
682 		if (debug)
683 			DSA_print_fp(stdout, dsa, 0);
684 	}
685 
686 	/*
687 	 * Return the marbles.
688 	 */
689 	if (grpkey != NULL)
690 		OPENSSL_free(grpkey);
691 	if (pkey_host != NULL)
692 		EVP_PKEY_free(pkey_host);
693 	if (pkey_sign != NULL)
694 		EVP_PKEY_free(pkey_sign);
695 	if (pkey_iff != NULL)
696 		EVP_PKEY_free(pkey_iff);
697 	if (pkey_gq != NULL)
698 		EVP_PKEY_free(pkey_gq);
699 	if (pkey_mv != NULL)
700 		EVP_PKEY_free(pkey_mv);
701 #endif /* OPENSSL */
702 	return (rval);
703 }
704 
705 
706 #if 0
707 /*
708  * Generate random MD5 key with password.
709  */
710 int
711 gen_md5(
712 	char	*id		/* file name id */
713 	)
714 {
715 	BIGNUM	*key;
716 	BIGNUM	*keyid;
717 	FILE	*str;
718 	u_char	bin[16];
719 
720 	fprintf(stderr, "Generating MD5 keys...\n");
721 	str = fheader("MD5key", hostname);
722 	keyid = BN_new(); key = BN_new();
723 	BN_rand(keyid, 16, -1, 0);
724 	BN_rand(key, 128, -1, 0);
725 	BN_bn2bin(key, bin);
726 	PEM_write_fp(str, MD5, NULL, bin);
727 	fclose(str);
728 	fslink(id, hostname);
729 	return (1);
730 }
731 
732 
733 #else
734 /*
735  * Generate semi-random MD5 keys compatible with NTPv3 and NTPv4
736  */
737 int
738 gen_md5(
739 	char	*id		/* file name id */
740 	)
741 {
742 	u_char	md5key[16];	/* MD5 key */
743 	FILE	*str;
744 	u_int	temp = 0;	/* Initialize to prevent warnings during compile */
745 	int	i, j;
746 
747 	fprintf(stderr, "Generating MD5 keys...\n");
748 	str = fheader("MD5key", hostname);
749 	srandom(epoch);
750 	for (i = 1; i <= MD5KEYS; i++) {
751 		for (j = 0; j < 16; j++) {
752 			while (1) {
753 				temp = random() & 0xff;
754 				if (temp == '#')
755 					continue;
756 				if (temp > 0x20 && temp < 0x7f)
757 					break;
758 			}
759 			md5key[j] = (u_char)temp;
760 		}
761 		md5key[15] = '\0';
762 		fprintf(str, "%2d MD5 %16s	# MD5 key\n", i,
763 		    md5key);
764 	}
765 	fclose(str);
766 	fslink(id, hostname);
767 	return (1);
768 }
769 #endif /* OPENSSL */
770 
771 
772 #ifdef OPENSSL
773 /*
774  * Generate RSA public/private key pair
775  */
776 EVP_PKEY *			/* public/private key pair */
777 gen_rsa(
778 	char	*id		/* file name id */
779 	)
780 {
781 	EVP_PKEY *pkey;		/* private key */
782 	RSA	*rsa;		/* RSA parameters and key pair */
783 	FILE	*str;
784 
785 	fprintf(stderr, "Generating RSA keys (%d bits)...\n", modulus);
786 	rsa = RSA_generate_key(modulus, 3, cb, "RSA");
787 	fprintf(stderr, "\n");
788 	if (rsa == NULL) {
789 		fprintf(stderr, "RSA generate keys fails\n%s\n",
790 		    ERR_error_string(ERR_get_error(), NULL));
791 		rval = -1;
792 		return (NULL);
793 	}
794 
795 	/*
796 	 * For signature encryption it is not necessary that the RSA
797 	 * parameters be strictly groomed and once in a while the
798 	 * modulus turns out to be non-prime. Just for grins, we check
799 	 * the primality.
800 	 */
801 	if (!RSA_check_key(rsa)) {
802 		fprintf(stderr, "Invalid RSA key\n%s\n",
803 		    ERR_error_string(ERR_get_error(), NULL));
804 		RSA_free(rsa);
805 		rval = -1;
806 		return (NULL);
807 	}
808 
809 	/*
810 	 * Write the RSA parameters and keys as a RSA private key
811 	 * encoded in PEM.
812 	 */
813 	str = fheader("RSAkey", hostname);
814 	pkey = EVP_PKEY_new();
815 	EVP_PKEY_assign_RSA(pkey, rsa);
816 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
817 	    NULL, 0, NULL, passwd2);
818 	fclose(str);
819 	if (debug)
820 		RSA_print_fp(stdout, rsa, 0);
821 	fslink(id, hostname);
822 	return (pkey);
823 }
824 
825 
826 /*
827  * Generate DSA public/private key pair
828  */
829 EVP_PKEY *			/* public/private key pair */
830 gen_dsa(
831 	char	*id		/* file name id */
832 	)
833 {
834 	EVP_PKEY *pkey;		/* private key */
835 	DSA	*dsa;		/* DSA parameters */
836 	u_char	seed[20];	/* seed for parameters */
837 	FILE	*str;
838 
839 	/*
840 	 * Generate DSA parameters.
841 	 */
842 	fprintf(stderr,
843 	    "Generating DSA parameters (%d bits)...\n", modulus);
844 	RAND_bytes(seed, sizeof(seed));
845 	dsa = DSA_generate_parameters(modulus, seed, sizeof(seed), NULL,
846 	    NULL, cb, "DSA");
847 	fprintf(stderr, "\n");
848 	if (dsa == NULL) {
849 		fprintf(stderr, "DSA generate parameters fails\n%s\n",
850 		    ERR_error_string(ERR_get_error(), NULL));
851 		rval = -1;
852 		return (NULL);
853 	}
854 
855 	/*
856 	 * Generate DSA keys.
857 	 */
858 	fprintf(stderr, "Generating DSA keys (%d bits)...\n", modulus);
859 	if (!DSA_generate_key(dsa)) {
860 		fprintf(stderr, "DSA generate keys fails\n%s\n",
861 		    ERR_error_string(ERR_get_error(), NULL));
862 		DSA_free(dsa);
863 		rval = -1;
864 		return (NULL);
865 	}
866 
867 	/*
868 	 * Write the DSA parameters and keys as a DSA private key
869 	 * encoded in PEM.
870 	 */
871 	str = fheader("DSAkey", hostname);
872 	pkey = EVP_PKEY_new();
873 	EVP_PKEY_assign_DSA(pkey, dsa);
874 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
875 	    NULL, 0, NULL, passwd2);
876 	fclose(str);
877 	if (debug)
878 		DSA_print_fp(stdout, dsa, 0);
879 	fslink(id, hostname);
880 	return (pkey);
881 }
882 
883 
884 /*
885  * Generate Schnorr (IFF) parameters and keys
886  *
887  * The Schnorr (IFF)identity scheme is intended for use when
888  * certificates are generated by some other trusted certificate
889  * authority and the parameters cannot be conveyed in the certificate
890  * itself. For this purpose, new generations of IFF values must be
891  * securely transmitted to all members of the group before use. There
892  * are two kinds of files: server/client files that include private and
893  * public parameters and client files that include only public
894  * parameters. The scheme is self contained and independent of new
895  * generations of host keys, sign keys and certificates.
896  *
897  * The IFF values hide in a DSA cuckoo structure which uses the same
898  * parameters. The values are used by an identity scheme based on DSA
899  * cryptography and described in Stimson p. 285. The p is a 512-bit
900  * prime, g a generator of Zp* and q a 160-bit prime that divides p - 1
901  * and is a qth root of 1 mod p; that is, g^q = 1 mod p. The TA rolls a
902  * private random group key b (0 < b < q), then computes public
903  * v = g^(q - a). All values except the group key are known to all group
904  * members; the group key is known to the group servers, but not the
905  * group clients. Alice challenges Bob to confirm identity using the
906  * protocol described below.
907  */
908 EVP_PKEY *			/* DSA cuckoo nest */
909 gen_iff(
910 	char	*id		/* file name id */
911 	)
912 {
913 	EVP_PKEY *pkey;		/* private key */
914 	DSA	*dsa;		/* DSA parameters */
915 	u_char	seed[20];	/* seed for parameters */
916 	BN_CTX	*ctx;		/* BN working space */
917 	BIGNUM	*b, *r, *k, *u, *v, *w; /* BN temp */
918 	FILE	*str;
919 	u_int	temp;
920 
921 	/*
922 	 * Generate DSA parameters for use as IFF parameters.
923 	 */
924 	fprintf(stderr, "Generating IFF parameters (%d bits)...\n",
925 	    modulus);
926 	RAND_bytes(seed, sizeof(seed));
927 	dsa = DSA_generate_parameters(modulus, seed, sizeof(seed), NULL,
928 	    NULL, cb, "IFF");
929 	fprintf(stderr, "\n");
930 	if (dsa == NULL) {
931 		fprintf(stderr, "DSA generate parameters fails\n%s\n",
932 		    ERR_error_string(ERR_get_error(), NULL));
933 		rval = -1;
934 		return (NULL);;
935 	}
936 
937 	/*
938 	 * Generate the private and public keys. The DSA parameters and
939 	 * these keys are distributed to all members of the group.
940 	 */
941 	fprintf(stderr, "Generating IFF keys (%d bits)...\n", modulus);
942 	b = BN_new(); r = BN_new(); k = BN_new();
943 	u = BN_new(); v = BN_new(); w = BN_new(); ctx = BN_CTX_new();
944 	BN_rand(b, BN_num_bits(dsa->q), -1, 0);	/* a */
945 	BN_mod(b, b, dsa->q, ctx);
946 	BN_sub(v, dsa->q, b);
947 	BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^(q - b) mod p */
948 	BN_mod_exp(u, dsa->g, b, dsa->p, ctx);	/* g^b mod p */
949 	BN_mod_mul(u, u, v, dsa->p, ctx);
950 	temp = BN_is_one(u);
951 	fprintf(stderr,
952 	    "Confirm g^(q - b) g^b = 1 mod p: %s\n", temp == 1 ?
953 	    "yes" : "no");
954 	if (!temp) {
955 		BN_free(b); BN_free(r); BN_free(k);
956 		BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);
957 		rval = -1;
958 		return (NULL);
959 	}
960 	dsa->priv_key = BN_dup(b);		/* private key */
961 	dsa->pub_key = BN_dup(v);		/* public key */
962 
963 	/*
964 	 * Here is a trial round of the protocol. First, Alice rolls
965 	 * random r (0 < r < q) and sends it to Bob. She needs only
966 	 * modulus q.
967 	 */
968 	BN_rand(r, BN_num_bits(dsa->q), -1, 0);	/* r */
969 	BN_mod(r, r, dsa->q, ctx);
970 
971 	/*
972 	 * Bob rolls random k (0 < k < q), computes y = k + b r mod q
973 	 * and x = g^k mod p, then sends (y, x) to Alice. He needs
974 	 * moduli p, q and the group key b.
975 	 */
976 	BN_rand(k, BN_num_bits(dsa->q), -1, 0);	/* k, 0 < k < q  */
977 	BN_mod(k, k, dsa->q, ctx);
978 	BN_mod_mul(v, dsa->priv_key, r, dsa->q, ctx); /* b r mod q */
979 	BN_add(v, v, k);
980 	BN_mod(v, v, dsa->q, ctx);		/* y = k + b r mod q */
981 	BN_mod_exp(u, dsa->g, k, dsa->p, ctx);	/* x = g^k mod p */
982 
983 	/*
984 	 * Alice computes g^y v^r and verifies the result is equal to x.
985 	 * She needs modulus p, generator g, and the public key v, as
986 	 * well as her original r.
987 	 */
988 	BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^y mod p */
989 	BN_mod_exp(w, dsa->pub_key, r, dsa->p, ctx); /* v^r */
990 	BN_mod_mul(v, w, v, dsa->p, ctx);	/* product mod p */
991 	temp = BN_cmp(u, v);
992 	fprintf(stderr,
993 	    "Confirm g^k = g^(k + b r) g^(q - b) r: %s\n", temp ==
994 	    0 ? "yes" : "no");
995 	BN_free(b); BN_free(r);	BN_free(k);
996 	BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);
997 	if (temp != 0) {
998 		DSA_free(dsa);
999 		rval = -1;
1000 		return (NULL);
1001 	}
1002 
1003 	/*
1004 	 * Write the IFF server parameters and keys as a DSA private key
1005 	 * encoded in PEM.
1006 	 *
1007 	 * p	modulus p
1008 	 * q	modulus q
1009 	 * g	generator g
1010 	 * priv_key b
1011 	 * public_key v
1012 	 */
1013 	str = fheader("IFFpar", trustname);
1014 	pkey = EVP_PKEY_new();
1015 	EVP_PKEY_assign_DSA(pkey, dsa);
1016 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
1017 	    NULL, 0, NULL, passwd2);
1018 	fclose(str);
1019 	if (debug)
1020 		DSA_print_fp(stdout, dsa, 0);
1021 	fslink(id, trustname);
1022 	return (pkey);
1023 }
1024 
1025 
1026 /*
1027  * Generate Guillou-Quisquater (GQ) parameters and keys
1028  *
1029  * The Guillou-Quisquater (GQ) identity scheme is intended for use when
1030  * the parameters, keys and certificates are generated by this program.
1031  * The scheme uses a certificate extension field do convey the public
1032  * key of a particular group identified by a group key known only to
1033  * members of the group. The scheme is self contained and independent of
1034  * new generations of host keys and sign keys.
1035  *
1036  * The GQ parameters hide in a RSA cuckoo structure which uses the same
1037  * parameters. The values are used by an identity scheme based on RSA
1038  * cryptography and described in Stimson p. 300 (with errors). The 512-
1039  * bit public modulus is n = p q, where p and q are secret large primes.
1040  * The TA rolls private random group key b as RSA exponent. These values
1041  * are known to all group members.
1042  *
1043  * When rolling new certificates, a member recomputes the private and
1044  * public keys. The private key u is a random roll, while the public key
1045  * is the inverse obscured by the group key v = (u^-1)^b. These values
1046  * replace the private and public keys normally generated by the RSA
1047  * scheme. Alice challenges Bob to confirm identity using the protocol
1048  * described below.
1049  */
1050 EVP_PKEY *			/* RSA cuckoo nest */
1051 gen_gqpar(
1052 	char	*id		/* file name id */
1053 	)
1054 {
1055 	EVP_PKEY *pkey;		/* private key */
1056 	RSA	*rsa;		/* GQ parameters */
1057 	BN_CTX	*ctx;		/* BN working space */
1058 	FILE	*str;
1059 
1060 	/*
1061 	 * Generate RSA parameters for use as GQ parameters.
1062 	 */
1063 	fprintf(stderr,
1064 	    "Generating GQ parameters (%d bits)...\n", modulus);
1065 	rsa = RSA_generate_key(modulus, 3, cb, "GQ");
1066 	fprintf(stderr, "\n");
1067 	if (rsa == NULL) {
1068 		fprintf(stderr, "RSA generate keys fails\n%s\n",
1069 		    ERR_error_string(ERR_get_error(), NULL));
1070 		rval = -1;
1071 		return (NULL);
1072 	}
1073 
1074 	/*
1075 	 * Generate the group key b, which is saved in the e member of
1076 	 * the RSA structure. These values are distributed to all
1077 	 * members of the group, but shielded from all other groups. We
1078 	 * don't use all the parameters, but set the unused ones to a
1079 	 * small number to minimize the file size.
1080 	 */
1081 	ctx = BN_CTX_new();
1082 	BN_rand(rsa->e, BN_num_bits(rsa->n), -1, 0); /* b */
1083 	BN_mod(rsa->e, rsa->e, rsa->n, ctx);
1084 	BN_copy(rsa->d, BN_value_one());
1085 	BN_copy(rsa->p, BN_value_one());
1086 	BN_copy(rsa->q, BN_value_one());
1087 	BN_copy(rsa->dmp1, BN_value_one());
1088 	BN_copy(rsa->dmq1, BN_value_one());
1089 	BN_copy(rsa->iqmp, BN_value_one());
1090 
1091 	/*
1092 	 * Write the GQ parameters as a RSA private key encoded in PEM.
1093 	 * The public and private keys are filled in later.
1094 	 *
1095 	 * n	modulus n
1096 	 * e	group key b
1097 	 * (remaining values are not used)
1098 	 */
1099 	str = fheader("GQpar", trustname);
1100 	pkey = EVP_PKEY_new();
1101 	EVP_PKEY_assign_RSA(pkey, rsa);
1102 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
1103 	    NULL, 0, NULL, passwd2);
1104 	fclose(str);
1105 	if (debug)
1106 		RSA_print_fp(stdout, rsa, 0);
1107 	fslink(id, trustname);
1108 	return (pkey);
1109 }
1110 
1111 
1112 /*
1113  * Update Guillou-Quisquater (GQ) parameters
1114  */
1115 EVP_PKEY *			/* RSA cuckoo nest */
1116 gen_gqkey(
1117 	char	*id,		/* file name id */
1118 	EVP_PKEY *gqpar		/* GQ parameters */
1119 	)
1120 {
1121 	EVP_PKEY *pkey;		/* private key */
1122 	RSA	*rsa;		/* RSA parameters */
1123 	BN_CTX	*ctx;		/* BN working space */
1124 	BIGNUM	*u, *v, *g, *k, *r, *y; /* BN temps */
1125 	FILE	*str;
1126 	u_int	temp;
1127 
1128 	/*
1129 	 * Generate GQ keys. Note that the group key b is the e member
1130 	 * of
1131 	 * the GQ parameters.
1132 	 */
1133 	fprintf(stderr, "Updating GQ keys (%d bits)...\n", modulus);
1134 	ctx = BN_CTX_new(); u = BN_new(); v = BN_new();
1135 	g = BN_new(); k = BN_new(); r = BN_new(); y = BN_new();
1136 
1137 	/*
1138 	 * When generating his certificate, Bob rolls random private key
1139 	 * u.
1140 	 */
1141 	rsa = gqpar->pkey.rsa;
1142 	BN_rand(u, BN_num_bits(rsa->n), -1, 0); /* u */
1143 	BN_mod(u, u, rsa->n, ctx);
1144 	BN_mod_inverse(v, u, rsa->n, ctx);	/* u^-1 mod n */
1145 	BN_mod_mul(k, v, u, rsa->n, ctx);
1146 
1147 	/*
1148 	 * Bob computes public key v = (u^-1)^b, which is saved in an
1149 	 * extension field on his certificate. We check that u^b v =
1150 	 * 1 mod n.
1151 	 */
1152 	BN_mod_exp(v, v, rsa->e, rsa->n, ctx);
1153 	BN_mod_exp(g, u, rsa->e, rsa->n, ctx); /* u^b */
1154 	BN_mod_mul(g, g, v, rsa->n, ctx); /* u^b (u^-1)^b */
1155 	temp = BN_is_one(g);
1156 	fprintf(stderr,
1157 	    "Confirm u^b (u^-1)^b = 1 mod n: %s\n", temp ? "yes" :
1158 	    "no");
1159 	if (!temp) {
1160 		BN_free(u); BN_free(v);
1161 		BN_free(g); BN_free(k); BN_free(r); BN_free(y);
1162 		BN_CTX_free(ctx);
1163 		RSA_free(rsa);
1164 		rval = -1;
1165 		return (NULL);
1166 	}
1167 	BN_copy(rsa->p, u);			/* private key */
1168 	BN_copy(rsa->q, v);			/* public key */
1169 
1170 	/*
1171 	 * Here is a trial run of the protocol. First, Alice rolls
1172 	 * random r (0 < r < n) and sends it to Bob. She needs only
1173 	 * modulus n from the parameters.
1174 	 */
1175 	BN_rand(r, BN_num_bits(rsa->n), -1, 0);	/* r */
1176 	BN_mod(r, r, rsa->n, ctx);
1177 
1178 	/*
1179 	 * Bob rolls random k (0 < k < n), computes y = k u^r mod n and
1180 	 * g = k^b mod n, then sends (y, g) to Alice. He needs modulus n
1181 	 * from the parameters and his private key u.
1182 	 */
1183 	BN_rand(k, BN_num_bits(rsa->n), -1, 0);	/* k */
1184 	BN_mod(k, k, rsa->n, ctx);
1185 	BN_mod_exp(y, rsa->p, r, rsa->n, ctx);	/* u^r mod n */
1186 	BN_mod_mul(y, k, y, rsa->n, ctx);	/* y = k u^r mod n */
1187 	BN_mod_exp(g, k, rsa->e, rsa->n, ctx); /* g = k^b mod n */
1188 
1189 	/*
1190 	 * Alice computes v^r y^b mod n and verifies the result is equal
1191 	 * to g. She needs modulus n, generator g and group key b from
1192 	 * the parameters and Bob's public key v = (u^-1)^b from his
1193 	 * certificate.
1194 	 */
1195 	BN_mod_exp(v, rsa->q, r, rsa->n, ctx);	/* v^r mod n */
1196 	BN_mod_exp(y, y, rsa->e, rsa->n, ctx); /* y^b mod n */
1197 	BN_mod_mul(y, v, y, rsa->n, ctx);	/* v^r y^b mod n */
1198 	temp = BN_cmp(y, g);
1199 	fprintf(stderr, "Confirm g^k = v^r y^b mod n: %s\n", temp == 0 ?
1200 	    "yes" : "no");
1201 	BN_CTX_free(ctx); BN_free(u); BN_free(v);
1202 	BN_free(g); BN_free(k); BN_free(r); BN_free(y);
1203 	if (temp != 0) {
1204 		RSA_free(rsa);
1205 		rval = -1;
1206 		return (NULL);
1207 	}
1208 
1209 	/*
1210 	 * Write the GQ parameters and keys as a RSA private key encoded
1211 	 * in PEM.
1212 	 *
1213 	 * n	modulus n
1214 	 * e	group key b
1215 	 * p	private key u
1216 	 * q	public key (u^-1)^b
1217 	 * (remaining values are not used)
1218 	 */
1219 	str = fheader("GQpar", trustname);
1220 	pkey = EVP_PKEY_new();
1221 	EVP_PKEY_assign_RSA(pkey, rsa);
1222 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
1223 	    NULL, 0, NULL, passwd2);
1224 	fclose(str);
1225 	if (debug)
1226 		RSA_print_fp(stdout, rsa, 0);
1227 	fslink(id, trustname);
1228 	return (pkey);
1229 }
1230 
1231 
1232 /*
1233  * Generate Mu-Varadharajan (MV) parameters and keys
1234  *
1235  * The Mu-Varadharajan (MV) cryptosystem is useful when servers
1236  * broadcast messages to clients, but clients never send messages to
1237  * servers. There is one encryption key for the server and a separate
1238  * decryption key for each client. It operates something like a
1239  * pay-per-view satellite broadcasting system where the session key is
1240  * encrypted by the broadcaster and the decryption keys are held in a
1241  * tamperproof set-top box. We don't use it this way, but read on.
1242  *
1243  * The MV parameters and private encryption key hide in a DSA cuckoo
1244  * structure which uses the same parameters, but generated in a
1245  * different way. The values are used in an encryption scheme similar to
1246  * El Gamal cryptography and a polynomial formed from the expansion of
1247  * product terms (x - x[j]), as described in Mu, Y., and V.
1248  * Varadharajan: Robust and Secure Broadcasting, Proc. Indocrypt 2001,
1249  * 223-231. The paper has significant errors and serious omissions.
1250  *
1251  * Let q be the product of n distinct primes s'[j] (j = 1...n), where
1252  * each s'[j] has m significant bits. Let p be a prime p = 2 * q + 1, so
1253  * that q and each s'[j] divide p - 1 and p has M = n * m + 1
1254  * significant bits. Let g be a generator of Zp; that is, gcd(g, p - 1)
1255  * = 1 and g^q = 1 mod p. We do modular arithmetic over Zq and then
1256  * project into Zp* as exponents of g. Sometimes we have to compute an
1257  * inverse b^-1 of random b in Zq, but for that purpose we require
1258  * gcd(b, q) = 1. We expect M to be in the 500-bit range and n
1259  * relatively small, like 30. Associated with each s'[j] is an element
1260  * s[j] such that s[j] s'[j] = s'[j] mod q. We find s[j] as the quotient
1261  * (q + s'[j]) / s'[j]. These are the parameters of the scheme and they
1262  * are expensive to compute.
1263  *
1264  * We set up an instance of the scheme as follows. A set of random
1265  * values x[j] mod q (j = 1...n), are generated as the zeros of a
1266  * polynomial of order n. The product terms (x - x[j]) are expanded to
1267  * form coefficients a[i] mod q (i = 0...n) in powers of x. These are
1268  * used as exponents of the generator g mod p to generate the private
1269  * encryption key A. The pair (gbar, ghat) of public server keys and the
1270  * pairs (xbar[j], xhat[j]) (j = 1...n) of private client keys are used
1271  * to construct the decryption keys. The devil is in the details.
1272  *
1273  * This routine generates a private encryption file including the
1274  * private encryption key E and public key (gbar, ghat). It then
1275  * generates decryption files including the private key (xbar[j],
1276  * xhat[j]) for each client. E is a permutation that encrypts a block
1277  * y = E x. The jth client computes the inverse permutation E^-1 =
1278  * gbar^xhat[j] ghat^xbar[j] and decrypts the block x = E^-1 y.
1279  *
1280  * The distinguishing characteristic of this scheme is the capability to
1281  * revoke keys. Included in the calculation of E, gbar and ghat is the
1282  * product s = prod(s'[j]) (j = 1...n) above. If the factor s'[j] is
1283  * subsequently removed from the product and E, gbar and ghat
1284  * recomputed, the jth client will no longer be able to compute E^-1 and
1285  * thus unable to decrypt the block.
1286  */
1287 EVP_PKEY *			/* DSA cuckoo nest */
1288 gen_mv(
1289 	char	*id		/* file name id */
1290 	)
1291 {
1292 	EVP_PKEY *pkey, *pkey1;	/* private key */
1293 	DSA	*dsa;		/* DSA parameters */
1294 	DSA	*sdsa;		/* DSA parameters */
1295 	BN_CTX	*ctx;		/* BN working space */
1296 	BIGNUM	**x;		/* polynomial zeros vector */
1297 	BIGNUM	**a;		/* polynomial coefficient vector */
1298 	BIGNUM	**g;		/* public key vector */
1299 	BIGNUM	**s, **s1;	/* private enabling keys */
1300 	BIGNUM	**xbar, **xhat;	/* private keys vector */
1301 	BIGNUM	*b;		/* group key */
1302 	BIGNUM	*b1;		/* inverse group key */
1303 	BIGNUM	*ss;		/* enabling key */
1304 	BIGNUM	*biga;		/* master encryption key */
1305 	BIGNUM	*bige;		/* session encryption key */
1306 	BIGNUM	*gbar, *ghat;	/* public key */
1307 	BIGNUM	*u, *v, *w;	/* BN scratch */
1308 	int	i, j, n;
1309 	FILE	*str;
1310 	u_int	temp;
1311 	char	ident[20];
1312 
1313 	/*
1314 	 * Generate MV parameters.
1315 	 *
1316 	 * The object is to generate a multiplicative group Zp* modulo a
1317 	 * prime p and a subset Zq mod q, where q is the product of n
1318 	 * distinct primes s'[j] (j = 1...n) and q divides p - 1. We
1319 	 * first generate n distinct primes, which may have to be
1320 	 * regenerated later. As a practical matter, it is tough to find
1321 	 * more than 31 distinct primes for modulus 512 or 61 primes for
1322 	 * modulus 1024. The latter can take several hundred iterations
1323 	 * and several minutes on a Sun Blade 1000.
1324 	 */
1325 	n = nkeys;
1326 	fprintf(stderr,
1327 	    "Generating MV parameters for %d keys (%d bits)...\n", n,
1328 	    modulus / n);
1329 	ctx = BN_CTX_new(); u = BN_new(); v = BN_new(); w = BN_new();
1330 	b = BN_new(); b1 = BN_new();
1331 	dsa = DSA_new();
1332 	dsa->p = BN_new();
1333 	dsa->q = BN_new();
1334 	dsa->g = BN_new();
1335 	s = malloc((n + 1) * sizeof(BIGNUM));
1336 	s1 = malloc((n + 1) * sizeof(BIGNUM));
1337 	for (j = 1; j <= n; j++)
1338 		s1[j] = BN_new();
1339 	temp = 0;
1340 	for (j = 1; j <= n; j++) {
1341 		while (1) {
1342 			fprintf(stderr, "Birthdays %d\r", temp);
1343 			BN_generate_prime(s1[j], modulus / n, 0, NULL,
1344 			    NULL, NULL, NULL);
1345 			for (i = 1; i < j; i++) {
1346 				if (BN_cmp(s1[i], s1[j]) == 0)
1347 					break;
1348 			}
1349 			if (i == j)
1350 				break;
1351 			temp++;
1352 		}
1353 	}
1354 	fprintf(stderr, "Birthday keys rejected %d\n", temp);
1355 
1356 	/*
1357 	 * Compute the modulus q as the product of the primes. Compute
1358 	 * the modulus p as 2 * q + 1 and test p for primality. If p
1359 	 * is composite, replace one of the primes with a new distinct
1360 	 * one and try again. Note that q will hardly be a secret since
1361 	 * we have to reveal p to servers and clients. However,
1362 	 * factoring q to find the primes should be adequately hard, as
1363 	 * this is the same problem considered hard in RSA. Question: is
1364 	 * it as hard to find n small prime factors totalling n bits as
1365 	 * it is to find two large prime factors totalling n bits?
1366 	 * Remember, the bad guy doesn't know n.
1367 	 */
1368 	temp = 0;
1369 	while (1) {
1370 		fprintf(stderr, "Duplicate keys rejected %d\r", ++temp);
1371 		BN_one(dsa->q);
1372 		for (j = 1; j <= n; j++)
1373 			BN_mul(dsa->q, dsa->q, s1[j], ctx);
1374 		BN_copy(dsa->p, dsa->q);
1375 		BN_add(dsa->p, dsa->p, dsa->p);
1376 		BN_add_word(dsa->p, 1);
1377 		if (BN_is_prime(dsa->p, BN_prime_checks, NULL, ctx,
1378 		    NULL))
1379 			break;
1380 
1381 		j = temp % n + 1;
1382 		while (1) {
1383 			BN_generate_prime(u, modulus / n, 0, 0, NULL,
1384 			    NULL, NULL);
1385 			for (i = 1; i <= n; i++) {
1386 				if (BN_cmp(u, s1[i]) == 0)
1387 					break;
1388 			}
1389 			if (i > n)
1390 				break;
1391 		}
1392 		BN_copy(s1[j], u);
1393 	}
1394 	fprintf(stderr, "Duplicate keys rejected %d\n", temp);
1395 
1396 	/*
1397 	 * Compute the generator g using a random roll such that
1398 	 * gcd(g, p - 1) = 1 and g^q = 1. This is a generator of p, not
1399 	 * q.
1400 	 */
1401 	BN_copy(v, dsa->p);
1402 	BN_sub_word(v, 1);
1403 	while (1) {
1404 		BN_rand(dsa->g, BN_num_bits(dsa->p) - 1, 0, 0);
1405 		BN_mod(dsa->g, dsa->g, dsa->p, ctx);
1406 		BN_gcd(u, dsa->g, v, ctx);
1407 		if (!BN_is_one(u))
1408 			continue;
1409 
1410 		BN_mod_exp(u, dsa->g, dsa->q, dsa->p, ctx);
1411 		if (BN_is_one(u))
1412 			break;
1413 	}
1414 
1415 	/*
1416 	 * Compute s[j] such that s[j] * s'[j] = s'[j] for all j. The
1417 	 * easy way to do this is to compute q + s'[j] and divide the
1418 	 * result by s'[j]. Exercise for the student: prove the
1419 	 * remainder is always zero.
1420 	 */
1421 	for (j = 1; j <= n; j++) {
1422 		s[j] = BN_new();
1423 		BN_add(s[j], dsa->q, s1[j]);
1424 		BN_div(s[j], u, s[j], s1[j], ctx);
1425 	}
1426 
1427 	/*
1428 	 * Setup is now complete. Roll random polynomial roots x[j]
1429 	 * (0 < x[j] < q) for all j. While it may not be strictly
1430 	 * necessary, Make sure each root has no factors in common with
1431 	 * q.
1432 	 */
1433 	fprintf(stderr,
1434 	    "Generating polynomial coefficients for %d roots (%d bits)\n",
1435 	    n, BN_num_bits(dsa->q));
1436 	x = malloc((n + 1) * sizeof(BIGNUM));
1437 	for (j = 1; j <= n; j++) {
1438 		x[j] = BN_new();
1439 		while (1) {
1440 			BN_rand(x[j], BN_num_bits(dsa->q), 0, 0);
1441 			BN_mod(x[j], x[j], dsa->q, ctx);
1442 			BN_gcd(u, x[j], dsa->q, ctx);
1443 			if (BN_is_one(u))
1444 				break;
1445 		}
1446 	}
1447 
1448 	/*
1449 	 * Generate polynomial coefficients a[i] (i = 0...n) from the
1450 	 * expansion of root products (x - x[j]) mod q for all j. The
1451 	 * method is a present from Charlie Boncelet.
1452 	 */
1453 	a = malloc((n + 1) * sizeof(BIGNUM));
1454 	for (i = 0; i <= n; i++) {
1455 		a[i] = BN_new();
1456 		BN_one(a[i]);
1457 	}
1458 	for (j = 1; j <= n; j++) {
1459 		BN_zero(w);
1460 		for (i = 0; i < j; i++) {
1461 			BN_copy(u, dsa->q);
1462 			BN_mod_mul(v, a[i], x[j], dsa->q, ctx);
1463 			BN_sub(u, u, v);
1464 			BN_add(u, u, w);
1465 			BN_copy(w, a[i]);
1466 			BN_mod(a[i], u, dsa->q, ctx);
1467 		}
1468 	}
1469 
1470 	/*
1471 	 * Generate g[i] = g^a[i] mod p for all i and the generator g.
1472 	 */
1473 	fprintf(stderr, "Generating g[i] parameters\n");
1474 	g = malloc((n + 1) * sizeof(BIGNUM));
1475 	for (i = 0; i <= n; i++) {
1476 		g[i] = BN_new();
1477 		BN_mod_exp(g[i], dsa->g, a[i], dsa->p, ctx);
1478 	}
1479 
1480 	/*
1481 	 * Verify prod(g[i]^(a[i] x[j]^i)) = 1 for all i, j; otherwise,
1482 	 * exit. Note the a[i] x[j]^i exponent is computed mod q, but
1483 	 * the g[i] is computed mod p. also note the expression given in
1484 	 * the paper is incorrect.
1485 	 */
1486 	temp = 1;
1487 	for (j = 1; j <= n; j++) {
1488 		BN_one(u);
1489 		for (i = 0; i <= n; i++) {
1490 			BN_set_word(v, i);
1491 			BN_mod_exp(v, x[j], v, dsa->q, ctx);
1492 			BN_mod_mul(v, v, a[i], dsa->q, ctx);
1493 			BN_mod_exp(v, dsa->g, v, dsa->p, ctx);
1494 			BN_mod_mul(u, u, v, dsa->p, ctx);
1495 		}
1496 		if (!BN_is_one(u))
1497 			temp = 0;
1498 	}
1499 	fprintf(stderr,
1500 	    "Confirm prod(g[i]^(x[j]^i)) = 1 for all i, j: %s\n", temp ?
1501 	    "yes" : "no");
1502 	if (!temp) {
1503 		rval = -1;
1504 		return (NULL);
1505 	}
1506 
1507 	/*
1508 	 * Make private encryption key A. Keep it around for awhile,
1509 	 * since it is expensive to compute.
1510 	 */
1511 	biga = BN_new();
1512 	BN_one(biga);
1513 	for (j = 1; j <= n; j++) {
1514 		for (i = 0; i < n; i++) {
1515 			BN_set_word(v, i);
1516 			BN_mod_exp(v, x[j], v, dsa->q, ctx);
1517 			BN_mod_exp(v, g[i], v, dsa->p, ctx);
1518 			BN_mod_mul(biga, biga, v, dsa->p, ctx);
1519 		}
1520 	}
1521 
1522 	/*
1523 	 * Roll private random group key b mod q (0 < b < q), where
1524 	 * gcd(b, q) = 1 to guarantee b^1 exists, then compute b^-1
1525 	 * mod q. If b is changed, the client keys must be recomputed.
1526 	 */
1527 	while (1) {
1528 		BN_rand(b, BN_num_bits(dsa->q), 0, 0);
1529 		BN_mod(b, b, dsa->q, ctx);
1530 		BN_gcd(u, b, dsa->q, ctx);
1531 		if (BN_is_one(u))
1532 			break;
1533 	}
1534 	BN_mod_inverse(b1, b, dsa->q, ctx);
1535 
1536 	/*
1537 	 * Make private client keys (xbar[j], xhat[j]) for all j. Note
1538 	 * that the keys for the jth client involve s[j], but not s'[j]
1539 	 * or the product s = prod(s'[j]) mod q, which is the enabling
1540 	 * key.
1541 	 */
1542 	xbar = malloc((n + 1) * sizeof(BIGNUM));
1543 	xhat = malloc((n + 1) * sizeof(BIGNUM));
1544 	for (j = 1; j <= n; j++) {
1545 		xbar[j] = BN_new(); xhat[j] = BN_new();
1546 		BN_zero(xbar[j]);
1547 		BN_set_word(v, n);
1548 		for (i = 1; i <= n; i++) {
1549 			if (i == j)
1550 				continue;
1551 			BN_mod_exp(u, x[i], v, dsa->q, ctx);
1552 			BN_add(xbar[j], xbar[j], u);
1553 		}
1554 		BN_mod_mul(xbar[j], xbar[j], b1, dsa->q, ctx);
1555 		BN_mod_exp(xhat[j], x[j], v, dsa->q, ctx);
1556 		BN_mod_mul(xhat[j], xhat[j], s[j], dsa->q, ctx);
1557 	}
1558 
1559 	/*
1560 	 * The enabling key is initially q by construction. We can
1561 	 * revoke client j by dividing q by s'[j]. The quotient becomes
1562 	 * the enabling key s. Note we always have to revoke one key;
1563 	 * otherwise, the plaintext and cryptotext would be identical.
1564 	 */
1565 	ss = BN_new();
1566 	BN_copy(ss, dsa->q);
1567 	BN_div(ss, u, dsa->q, s1[n], ctx);
1568 
1569 	/*
1570 	 * Make private server encryption key E = A^s and public server
1571 	 * keys gbar = g^s mod p and ghat = g^(s b) mod p. The (gbar,
1572 	 * ghat) is the public key provided to the server, which uses it
1573 	 * to compute the session encryption key and public key included
1574 	 * in its messages. These values must be regenerated if the
1575 	 * enabling key is changed.
1576 	 */
1577 	bige = BN_new(); gbar = BN_new(); ghat = BN_new();
1578 	BN_mod_exp(bige, biga, ss, dsa->p, ctx);
1579 	BN_mod_exp(gbar, dsa->g, ss, dsa->p, ctx);
1580 	BN_mod_mul(v, ss, b, dsa->q, ctx);
1581 	BN_mod_exp(ghat, dsa->g, v, dsa->p, ctx);
1582 
1583 	/*
1584 	 * We produce the key media in three steps. The first step is to
1585 	 * generate the private values that do not depend on the
1586 	 * enabling key. These include the server values p, q, g, b, A
1587 	 * and the client values s'[j], xbar[j] and xhat[j] for each j.
1588 	 * The p, xbar[j] and xhat[j] values are encoded in private
1589 	 * files which are distributed to respective clients. The p, q,
1590 	 * g, A and s'[j] values (will be) written to a secret file to
1591 	 * be read back later.
1592 	 *
1593 	 * The secret file (will be) read back at some later time to
1594 	 * enable/disable individual keys and generate/regenerate the
1595 	 * enabling key s. The p, q, E, gbar and ghat values are written
1596 	 * to a secret file to be read back later by the server.
1597 	 *
1598 	 * The server reads the secret file and rolls the session key
1599 	 * k, which is used only once, then computes E^k, gbar^k and
1600 	 * ghat^k. The E^k is the session encryption key. The encrypted
1601 	 * data, gbar^k and ghat^k are transmtted to clients in an
1602 	 * extension field. The client receives the message and computes
1603 	 * x = (gbar^k)^xbar[j] (ghat^k)^xhat[j], finds the session
1604 	 * encryption key E^k as the inverse x^-1 and decrypts the data.
1605 	 */
1606 	BN_copy(dsa->g, bige);
1607 	dsa->priv_key = BN_dup(gbar);
1608 	dsa->pub_key = BN_dup(ghat);
1609 
1610 	/*
1611 	 * Write the MV server parameters and keys as a DSA private key
1612 	 * encoded in PEM.
1613 	 *
1614 	 * p	modulus p
1615 	 * q	modulus q (used only to generate k)
1616 	 * g	E mod p
1617 	 * priv_key gbar mod p
1618 	 * pub_key ghat mod p
1619 	 */
1620 	str = fheader("MVpar", trustname);
1621 	pkey = EVP_PKEY_new();
1622 	EVP_PKEY_assign_DSA(pkey, dsa);
1623 	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,
1624 	    NULL, 0, NULL, passwd2);
1625 	fclose(str);
1626 	if (debug)
1627 		DSA_print_fp(stdout, dsa, 0);
1628 	fslink(id, trustname);
1629 
1630 	/*
1631 	 * Write the parameters and private key (xbar[j], xhat[j]) for
1632 	 * all j as a DSA private key encoded in PEM. It is used only by
1633 	 * the designated recipient(s) who pay a suitably outrageous fee
1634 	 * for its use.
1635 	 */
1636 	sdsa = DSA_new();
1637 	sdsa->p = BN_dup(dsa->p);
1638 	sdsa->q = BN_dup(BN_value_one());
1639 	sdsa->g = BN_dup(BN_value_one());
1640 	sdsa->priv_key = BN_new();
1641 	sdsa->pub_key = BN_new();
1642 	for (j = 1; j <= n; j++) {
1643 		BN_copy(sdsa->priv_key, xbar[j]);
1644 		BN_copy(sdsa->pub_key, xhat[j]);
1645 		BN_mod_exp(v, dsa->priv_key, sdsa->pub_key, dsa->p,
1646 		    ctx);
1647 		BN_mod_exp(u, dsa->pub_key, sdsa->priv_key, dsa->p,
1648 		    ctx);
1649 		BN_mod_mul(u, u, v, dsa->p, ctx);
1650 		BN_mod_mul(u, u, dsa->g, dsa->p, ctx);
1651 		BN_free(xbar[j]); BN_free(xhat[j]);
1652 		BN_free(x[j]); BN_free(s[j]); BN_free(s1[j]);
1653 		if (!BN_is_one(u)) {
1654 			fprintf(stderr, "Revoke key %d\n", j);
1655 			continue;
1656 		}
1657 
1658 		/*
1659 		 * Write the client parameters as a DSA private key
1660 		 * encoded in PEM. We don't make links for these.
1661 		 *
1662 		 * p	modulus p
1663 		 * priv_key xbar[j] mod q
1664 		 * pub_key xhat[j] mod q
1665 		 * (remaining values are not used)
1666 		 */
1667 		sprintf(ident, "MVkey%d", j);
1668 		str = fheader(ident, trustname);
1669 		pkey1 = EVP_PKEY_new();
1670 		EVP_PKEY_set1_DSA(pkey1, sdsa);
1671 		PEM_write_PrivateKey(str, pkey1, passwd2 ?
1672 		    EVP_des_cbc() : NULL, NULL, 0, NULL, passwd2);
1673 		fclose(str);
1674 		fprintf(stderr, "ntpkey_%s_%s.%lu\n", ident, trustname,
1675 		    epoch + JAN_1970);
1676 		if (debug)
1677 			DSA_print_fp(stdout, sdsa, 0);
1678 		EVP_PKEY_free(pkey1);
1679 	}
1680 
1681 	/*
1682 	 * Free the countries.
1683 	 */
1684 	for (i = 0; i <= n; i++) {
1685 		BN_free(a[i]);
1686 		BN_free(g[i]);
1687 	}
1688 	BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);
1689 	BN_free(b); BN_free(b1); BN_free(biga); BN_free(bige);
1690 	BN_free(ss); BN_free(gbar); BN_free(ghat);
1691 	DSA_free(sdsa);
1692 
1693 	/*
1694 	 * Free the world.
1695 	 */
1696 	free(x); free(a); free(g); free(s); free(s1);
1697 	free(xbar); free(xhat);
1698 	return (pkey);
1699 }
1700 
1701 
1702 /*
1703  * Generate X509v3 scertificate.
1704  *
1705  * The certificate consists of the version number, serial number,
1706  * validity interval, issuer name, subject name and public key. For a
1707  * self-signed certificate, the issuer name is the same as the subject
1708  * name and these items are signed using the subject private key. The
1709  * validity interval extends from the current time to the same time one
1710  * year hence. For NTP purposes, it is convenient to use the NTP seconds
1711  * of the current time as the serial number.
1712  */
1713 int
1714 x509	(
1715 	EVP_PKEY *pkey,		/* generic signature algorithm */
1716 	const EVP_MD *md,	/* generic digest algorithm */
1717 	char	*gqpub,		/* identity extension (hex string) */
1718 	char	*exten		/* private cert extension */
1719 	)
1720 {
1721 	X509	*cert;		/* X509 certificate */
1722 	X509_NAME *subj;	/* distinguished (common) name */
1723 	X509_EXTENSION *ex;	/* X509v3 extension */
1724 	FILE	*str;		/* file handle */
1725 	ASN1_INTEGER *serial;	/* serial number */
1726 	const char *id;		/* digest/signature scheme name */
1727 	char	pathbuf[MAXFILENAME + 1];
1728 
1729 	/*
1730 	 * Generate X509 self-signed certificate.
1731 	 *
1732 	 * Set the certificate serial to the NTP seconds for grins. Set
1733 	 * the version to 3. Set the subject name and issuer name to the
1734 	 * subject name in the request. Set the initial validity to the
1735 	 * current time and the final validity one year hence.
1736 	 */
1737 	id = OBJ_nid2sn(md->pkey_type);
1738 	fprintf(stderr, "Generating certificate %s\n", id);
1739 	cert = X509_new();
1740 	X509_set_version(cert, 2L);
1741 	serial = ASN1_INTEGER_new();
1742 	ASN1_INTEGER_set(serial, epoch + JAN_1970);
1743 	X509_set_serialNumber(cert, serial);
1744 	ASN1_INTEGER_free(serial);
1745 	X509_gmtime_adj(X509_get_notBefore(cert), 0L);
1746 	X509_gmtime_adj(X509_get_notAfter(cert), YEAR);
1747 	subj = X509_get_subject_name(cert);
1748 	X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
1749 	    (unsigned char *) hostname, strlen(hostname), -1, 0);
1750 	subj = X509_get_issuer_name(cert);
1751 	X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
1752 	    (unsigned char *) trustname, strlen(trustname), -1, 0);
1753 	if (!X509_set_pubkey(cert, pkey)) {
1754 		fprintf(stderr, "Assign key fails\n%s\n",
1755 		    ERR_error_string(ERR_get_error(), NULL));
1756 		X509_free(cert);
1757 		rval = -1;
1758 		return (0);
1759 	}
1760 
1761 	/*
1762 	 * Add X509v3 extensions if present. These represent the minimum
1763 	 * set defined in RFC3280 less the certificate_policy extension,
1764 	 * which is seriously obfuscated in OpenSSL.
1765 	 */
1766 	/*
1767 	 * The basic_constraints extension CA:TRUE allows servers to
1768 	 * sign client certficitates.
1769 	 */
1770 	fprintf(stderr, "%s: %s\n", LN_basic_constraints,
1771 	    BASIC_CONSTRAINTS);
1772 	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,
1773 	    BASIC_CONSTRAINTS);
1774 	if (!X509_add_ext(cert, ex, -1)) {
1775 		fprintf(stderr, "Add extension field fails\n%s\n",
1776 		    ERR_error_string(ERR_get_error(), NULL));
1777 		rval = -1;
1778 		return (0);
1779 	}
1780 	X509_EXTENSION_free(ex);
1781 
1782 	/*
1783 	 * The key_usage extension designates the purposes the key can
1784 	 * be used for.
1785 	 */
1786 	fprintf(stderr, "%s: %s\n", LN_key_usage, KEY_USAGE);
1787 	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, KEY_USAGE);
1788 	if (!X509_add_ext(cert, ex, -1)) {
1789 		fprintf(stderr, "Add extension field fails\n%s\n",
1790 		    ERR_error_string(ERR_get_error(), NULL));
1791 		rval = -1;
1792 		return (0);
1793 	}
1794 	X509_EXTENSION_free(ex);
1795 	/*
1796 	 * The subject_key_identifier is used for the GQ public key.
1797 	 * This should not be controversial.
1798 	 */
1799 	if (gqpub != NULL) {
1800 		fprintf(stderr, "%s\n", LN_subject_key_identifier);
1801 		ex = X509V3_EXT_conf_nid(NULL, NULL,
1802 		    NID_subject_key_identifier, gqpub);
1803 		if (!X509_add_ext(cert, ex, -1)) {
1804 			fprintf(stderr,
1805 			    "Add extension field fails\n%s\n",
1806 			    ERR_error_string(ERR_get_error(), NULL));
1807 			rval = -1;
1808 			return (0);
1809 		}
1810 		X509_EXTENSION_free(ex);
1811 	}
1812 
1813 	/*
1814 	 * The extended key usage extension is used for special purpose
1815 	 * here. The semantics probably do not conform to the designer's
1816 	 * intent and will likely change in future.
1817 	 *
1818 	 * "trustRoot" designates a root authority
1819 	 * "private" designates a private certificate
1820 	 */
1821 	if (exten != NULL) {
1822 		fprintf(stderr, "%s: %s\n", LN_ext_key_usage, exten);
1823 		ex = X509V3_EXT_conf_nid(NULL, NULL,
1824 		    NID_ext_key_usage, exten);
1825 		if (!X509_add_ext(cert, ex, -1)) {
1826 			fprintf(stderr,
1827 			    "Add extension field fails\n%s\n",
1828 			    ERR_error_string(ERR_get_error(), NULL));
1829 			rval = -1;
1830 			return (0);
1831 		}
1832 		X509_EXTENSION_free(ex);
1833 	}
1834 
1835 	/*
1836 	 * Sign and verify.
1837 	 */
1838 	X509_sign(cert, pkey, md);
1839 	if (!X509_verify(cert, pkey)) {
1840 		fprintf(stderr, "Verify %s certificate fails\n%s\n", id,
1841 		    ERR_error_string(ERR_get_error(), NULL));
1842 		X509_free(cert);
1843 		rval = -1;
1844 		return (0);
1845 	}
1846 
1847 	/*
1848 	 * Write the certificate encoded in PEM.
1849 	 */
1850 	sprintf(pathbuf, "%scert", id);
1851 	str = fheader(pathbuf, hostname);
1852 	PEM_write_X509(str, cert);
1853 	fclose(str);
1854 	if (debug)
1855 		X509_print_fp(stdout, cert);
1856 	X509_free(cert);
1857 	fslink("cert", hostname);
1858 	return (1);
1859 }
1860 
1861 #if 0	/* asn2ntp is not used */
1862 /*
1863  * asn2ntp - convert ASN1_TIME time structure to NTP time
1864  */
1865 u_long
1866 asn2ntp	(
1867 	ASN1_TIME *asn1time	/* pointer to ASN1_TIME structure */
1868 	)
1869 {
1870 	char	*v;		/* pointer to ASN1_TIME string */
1871 	struct	tm tm;		/* time decode structure time */
1872 
1873 	/*
1874 	 * Extract time string YYMMDDHHMMSSZ from ASN.1 time structure.
1875 	 * Note that the YY, MM, DD fields start with one, the HH, MM,
1876 	 * SS fiels start with zero and the Z character should be 'Z'
1877 	 * for UTC. Also note that years less than 50 map to years
1878 	 * greater than 100. Dontcha love ASN.1?
1879 	 */
1880 	if (asn1time->length > 13)
1881 		return (-1);
1882 	v = (char *)asn1time->data;
1883 	tm.tm_year = (v[0] - '0') * 10 + v[1] - '0';
1884 	if (tm.tm_year < 50)
1885 		tm.tm_year += 100;
1886 	tm.tm_mon = (v[2] - '0') * 10 + v[3] - '0' - 1;
1887 	tm.tm_mday = (v[4] - '0') * 10 + v[5] - '0';
1888 	tm.tm_hour = (v[6] - '0') * 10 + v[7] - '0';
1889 	tm.tm_min = (v[8] - '0') * 10 + v[9] - '0';
1890 	tm.tm_sec = (v[10] - '0') * 10 + v[11] - '0';
1891 	tm.tm_wday = 0;
1892 	tm.tm_yday = 0;
1893 	tm.tm_isdst = 0;
1894 	return (mktime(&tm) + JAN_1970);
1895 }
1896 #endif
1897 
1898 /*
1899  * Callback routine
1900  */
1901 void
1902 cb	(
1903 	int	n1,		/* arg 1 */
1904 	int	n2,		/* arg 2 */
1905 	void	*chr		/* arg 3 */
1906 	)
1907 {
1908 	switch (n1) {
1909 	case 0:
1910 		d0++;
1911 		fprintf(stderr, "%s %d %d %lu\r", (char *)chr, n1, n2,
1912 		    d0);
1913 		break;
1914 	case 1:
1915 		d1++;
1916 		fprintf(stderr, "%s\t\t%d %d %lu\r", (char *)chr, n1,
1917 		    n2, d1);
1918 		break;
1919 	case 2:
1920 		d2++;
1921 		fprintf(stderr, "%s\t\t\t\t%d %d %lu\r", (char *)chr,
1922 		    n1, n2, d2);
1923 		break;
1924 	case 3:
1925 		d3++;
1926 		fprintf(stderr, "%s\t\t\t\t\t\t%d %d %lu\r",
1927 		    (char *)chr, n1, n2, d3);
1928 		break;
1929 	}
1930 }
1931 
1932 
1933 /*
1934  * Generate key
1935  */
1936 EVP_PKEY *			/* public/private key pair */
1937 genkey(
1938 	char	*type,		/* key type (RSA or DSA) */
1939 	char	*id		/* file name id */
1940 	)
1941 {
1942 	if (type == NULL)
1943 		return (NULL);
1944 	if (strcmp(type, "RSA") == 0)
1945 		return (gen_rsa(id));
1946 
1947 	else if (strcmp(type, "DSA") == 0)
1948 		return (gen_dsa(id));
1949 
1950 	fprintf(stderr, "Invalid %s key type %s\n", id, type);
1951 	rval = -1;
1952 	return (NULL);
1953 }
1954 #endif /* OPENSSL */
1955 
1956 
1957 /*
1958  * Generate file header
1959  */
1960 FILE *
1961 fheader	(
1962 	const char *id,		/* file name id */
1963 	const char *name	/* owner name */
1964 	)
1965 {
1966 	FILE	*str;		/* file handle */
1967 
1968 	sprintf(filename, "ntpkey_%s_%s.%lu", id, name, epoch +
1969 	    JAN_1970);
1970 	if ((str = fopen(filename, "w")) == NULL) {
1971 		perror("Write");
1972 		exit (-1);
1973 	}
1974 	fprintf(str, "# %s\n# %s", filename, ctime(&epoch));
1975 	return (str);
1976 }
1977 
1978 
1979 /*
1980  * Generate symbolic links
1981  */
1982 void
1983 fslink(
1984 	const char *id,		/* file name id */
1985 	const char *name	/* owner name */
1986 	)
1987 {
1988 	char	linkname[MAXFILENAME]; /* link name */
1989 	int	temp;
1990 
1991 	sprintf(linkname, "ntpkey_%s_%s", id, name);
1992 	remove(linkname);
1993 	temp = symlink(filename, linkname);
1994 	if (temp < 0)
1995 		perror(id);
1996 	fprintf(stderr, "Generating new %s file and link\n", id);
1997 	fprintf(stderr, "%s->%s\n", linkname, filename);
1998 }
1999