PageRenderTime 60ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/ntp/util/ntp-keygen.c

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