]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Crypto cleanup from Dave Mills.\n[Bug 897] Check RAND_status() - we may not need...
authorHarlan Stenn <stenn@ntp.org>
Sat, 15 Sep 2007 20:40:14 +0000 (16:40 -0400)
committerHarlan Stenn <stenn@ntp.org>
Sat, 15 Sep 2007 20:40:14 +0000 (16:40 -0400)
bk: 46ec432ej15KovG6qPKdzU5S_bXxHg

ChangeLog
ntpd/ntp_control.c
ntpd/ntp_crypto.c
util/ntp-keygen.c

index acc9a99d43838d7febad823ac57b16a51276644f..285ce55c408d0d357306e382817d77970ac9392e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* [Bug 897] Check RAND_status() - we may not need a .rnd file.
+* Crypto cleanup from Dave Mills.
 * [Bug 911] Fix error message in cmd_args.c.
 * [Bug 895] Log assertion failures via syslog(), not stderr.
 * Documentation updates from Dave Mills.
index a9a0e84c6b26b671ce369630fc8c1e03e74ee0ed..986bea10e7f923a978859ae7e47ad0c6ef43dbda 100644 (file)
@@ -217,7 +217,7 @@ static struct ctl_var peer_var[] = {
        { CP_OUT,       RO, "out" },            /* 39 */
 #ifdef OPENSSL
        { CP_FLAGS,     RO, "flags" },          /* 40 */
-       { CP_HOST,      RO, "group" },          /* 41 */
+       { CP_HOST,      RO, "host" },           /* 41 */
        { CP_VALID,     RO, "valid" },          /* 42 */
        { CP_INITSEQ,   RO, "initsequence" },   /* 43 */
        { CP_INITKEY,   RO, "initkey" },        /* 44 */
@@ -1429,7 +1429,7 @@ ctl_putsys(
 
            case CS_GROUP:
                if (sys_groupname != NULL)
-                       ctl_putstr(sys_var[CS_HOST].text, sys_groupname,
+                       ctl_putstr(sys_var[CS_GROUP].text, sys_groupname,
                            strlen(sys_groupname));
                break;
 
index 7e7ca3d5ece820f25e459fec783af46a26e3876b..2c26cddbc1e9365b705018feb74b0d122d4791bc 100644 (file)
@@ -122,6 +122,7 @@ char        *sys_groupname = NULL;  /* group name */
  * Global cryptodata in network byte order
  */
 struct cert_info *cinfo = NULL;        /* certificate info/value cache */
+struct cert_info *cert_host = NULL; /* host certificate */
 struct pkey_info *pkinfo = NULL; /* key info/value cache */
 struct value hostval;          /* host value */
 struct value pubkey;           /* public key */
@@ -167,7 +168,7 @@ static      int     cert_sign       (struct exten *, struct value *);
 static int     cert_valid      (struct cert_info *, EVP_PKEY *);
 static struct cert_info *cert_install (struct exten *, struct peer *);
 static void    cert_free       (struct cert_info *);
-static struct pkey_info *crypto_key (char *);
+static struct pkey_info *crypto_key (char *, char *);
 static void    bighash         (BIGNUM *, BIGNUM *);
 static struct cert_info *crypto_cert (char *);
 
@@ -1248,16 +1249,29 @@ crypto_xmit(
                break;
 
        /*
-        * Send certificate response or sign request. Use the values
-        * from the certificate cache. If the request contains no
-        * subject name, assume the name of this host. This is for
-        * backwards compatibility. Private certificates are never sent.
-        *
-        * If a sign request, send the host certificate, which is self-
-        * signed and may or may not be trusted. If a certificate
-        * response, do not send the host certificate.
+        * Send sign request. Use the host certificate, which is self-
+        * signed and may or may not be trusted.
         */
        case CRYPTO_SIGN:
+               if (tstamp < cert_host->first || tstamp >
+                   cert_host->last)
+                       rval = XEVNT_SRV;
+               else
+                       rval = crypto_send(fp, &cert_host->cert, &len);
+               break;
+
+       /*
+        * Send certificate response. Use the name in the extension
+        * field to find the certificate in the cache. If the request
+        * contains no subject name, assume the name of this host. This
+        * is for backwards compatibility. Private certificates are
+        * never sent.
+        *
+        * There may be several certificates matching the request. First
+        * choice is a self-signed trusted certificate; second choice is
+        * any certificate signed by another host. There is no third
+        * choice. 
+        */
        case CRYPTO_CERT | CRYPTO_RESP:
                vallen = ntohl(ep->vallen);
                if (vallen == 8) {
@@ -1740,21 +1754,21 @@ crypto_ident(
        if (peer->crypto & CRYPTO_FLAG_IFF) {
                snprintf(filename, MAXFILENAME, "ntpkey_iffpar_%s",
                    peer->issuer);
-               peer->ident_pkey = crypto_key(filename);
+               peer->ident_pkey = crypto_key(filename, NULL);
                if (peer->ident_pkey != NULL)
                        return (CRYPTO_IFF);
        }
        if (peer->crypto & CRYPTO_FLAG_GQ) {
                snprintf(filename, MAXFILENAME, "ntpkey_gqpar_%s",
                    peer->issuer);
-               peer->ident_pkey = crypto_key(filename);
+               peer->ident_pkey = crypto_key(filename, NULL);
                if (peer->ident_pkey != NULL)
                        return (CRYPTO_GQ);
        }
        if (peer->crypto & CRYPTO_FLAG_MV) {
                snprintf(filename, MAXFILENAME, "ntpkey_mvpar_%s",
                    peer->issuer);
-               peer->ident_pkey = crypto_key(filename);
+               peer->ident_pkey = crypto_key(filename, NULL);
                if (peer->ident_pkey != NULL)
                        return (CRYPTO_MV);
        }
@@ -2256,6 +2270,10 @@ crypto_bob(
        sdsa->s = BN_dup(bk);
        BN_CTX_free(bctx);
        BN_free(r); BN_free(bn); BN_free(bk);
+#ifdef DEBUG
+       if (debug > 1)
+               DSA_print_fp(stdout, dsa, 0);
+#endif
 
        /*
         * Encode the values in ASN.1 and sign. The filestamp is from
@@ -2549,6 +2567,10 @@ crypto_bob2(
        sdsa->s = BN_dup(g);
        BN_CTX_free(bctx);
        BN_free(r); BN_free(k); BN_free(g); BN_free(y);
+#ifdef DEBUG
+       if (debug > 1)
+               RSA_print_fp(stdout, rsa, 0);
+#endif
  
        /*
         * Encode the values in ASN.1 and sign. The filestamp is from
@@ -2648,6 +2670,10 @@ crypto_gq(
        /*
         * Compute v^r y^b mod n.
         */
+       if (peer->grpkey == NULL) {
+               msyslog(LOG_INFO, "crypto_gq: missing group key");
+               return (XEVNT_ID);
+       }
        BN_mod_exp(v, peer->grpkey, peer->iffval, rsa->n, bctx);
                                                /* v^r mod n */
        BN_mod_exp(y, sdsa->r, rsa->e, rsa->n, bctx); /* y^b mod n */
@@ -2872,6 +2898,10 @@ crypto_bob3(
        BN_mod_exp(sdsa->q, dsa->priv_key, k, dsa->p, bctx); /* gbar */
        BN_mod_exp(sdsa->g, dsa->pub_key, k, dsa->p, bctx); /* ghat */
        BN_CTX_free(bctx); BN_free(k); BN_free(r); BN_free(u);
+#ifdef DEBUG
+       if (debug > 1)
+               DSA_print_fp(stdout, dsa, 0);
+#endif
 
        /*
         * Encode the values in ASN.1 and sign. The filestamp is from
@@ -3249,7 +3279,7 @@ cert_install(
                         * so, X signs Y.
                         */
                        if (strcmp(yp->issuer, xp->subject) != 0 ||
-                               xp->flags & CERT_ERROR)
+                           xp->flags & CERT_ERROR)
                                continue;
 
                        if (cert_valid(yp, xp->pkey) != XEVNT_OK) {
@@ -3293,7 +3323,7 @@ cert_install(
                        if (strcmp(yp->subject, peer->subject) != 0)
                                continue;
 
-                       peer->grpkey = yp->grpkey;
+                       peer->grpkey = xp->grpkey;
                        peer->crypto |= CRYPTO_FLAG_VALID;
 
                        /*
@@ -3349,11 +3379,20 @@ cert_parse(
        const char *ptr;
        int     temp, cnt, i;
 
+#if 0
+u_char *pta;
+
+pta = asn1cert;
+for (i = 0; i < len; i++)
+printf("%02x:", 0xff & *pta++);
+printf("\n%x %ld\n", asn1cert, len);
+#endif
+
        /*
         * Decode ASN.1 objects and construct certificate structure.
         */
        uptr = asn1cert;
-       if ((cert = d2i_X509(NULL, &uptr, len)) == NULL) {
+       if ((cert = d2i_X509(NULL, (u_char **)&uptr, len)) == NULL) {
                msyslog(LOG_ERR, "cert_parse: %s",
                    ERR_error_string(ERR_get_error(), NULL));
                return (NULL);
@@ -3549,7 +3588,8 @@ cert_free(
  */
 static struct pkey_info *
 crypto_key(
-       char    *cp             /* file name */
+       char    *cp,            /* file name */
+       char    *passwd1        /* password */
        )
 {
        FILE    *str;           /* file handle */
@@ -3608,7 +3648,7 @@ crypto_key(
         * Read and decrypt PEM-encoded private key. If it fails to
         * decrypt, game over.
         */
-       pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd);
+       pkey = PEM_read_PrivateKey(str, NULL, NULL, passwd1);
        fclose(str);
        if (pkey == NULL) {
                msyslog(LOG_ERR, "crypto_key: %s",
@@ -3726,13 +3766,13 @@ crypto_cert(
                fclose(str);
                return (NULL);
        }
+       fclose(str);
        free(header);
        if (strcmp(name, "CERTIFICATE") != 0) {
                msyslog(LOG_INFO, "crypto_cert: wrong PEM type %s",
                    name);
                free(name);
                free(data);
-               fclose(str);
                return (NULL);
        }
        free(name);
@@ -3741,9 +3781,8 @@ crypto_cert(
         * Parse certificate and generate info/value structure. The
         * pointer and copy nonsense is due something broken in Solaris.
         */
-       free(data);
        ret = cert_parse(data, len, fstamp);
-       fclose(str);
+       free(data);
        if (ret == NULL)
                return (NULL);
 
@@ -3799,47 +3838,44 @@ crypto_setup(void)
                    OPENSSL_VERSION_NUMBER, SSLeay());
                 exit (-1);
         }
+       ERR_load_crypto_strings();
+       OpenSSL_add_all_algorithms();
 
        /*
         * Load required random seed file and seed the random number
-        * generator. Be default, it is found in the user home
+        * generator. Be default, it is found as .rnd in the user home
         * directory. The root home directory may be / or /root,
         * depending on the system. Wiggle the contents a bit and write
         * it back so the sequence does not repeat when we next restart.
         */
-       ERR_load_crypto_strings();
-       if (rand_file == NULL) {
-               if ((RAND_file_name(filename, MAXFILENAME)) != NULL) {
-                       rand_file = emalloc(strlen(filename) + 1);
-                       strcpy(rand_file, filename);
+       if (!RAND_status()) {
+               if (rand_file == NULL)
+                       RAND_file_name(filename, MAXFILENAME);
+               else if (*rand_file == '/')
+                       strcpy(filename, rand_file);
+               else
+                       snprintf(filename, MAXFILENAME, "%s/%s",
+                           keysdir, rand_file);
+               if (filename == NULL) {
+                       msyslog(LOG_ERR,
+                           "crypto_setup: seed file unknown name");
+                       exit (-1);
                }
-       } else if (*rand_file != '/') {
-               snprintf(filename, MAXFILENAME, "%s/%s", keysdir,
-                   rand_file);
-               free(rand_file);
-               rand_file = emalloc(strlen(filename) + 1);
-               strcpy(rand_file, filename);
-       }
-       if (rand_file == NULL) {
-               msyslog(LOG_ERR,
-                   "crypto_setup: random seed file unknown name");
-               exit (-1);
-       }
-       if ((bytes = RAND_load_file(rand_file, -1)) == 0) {
-               msyslog(LOG_ERR,
-                   "crypto_setup: random seed file %s missing",
-                   rand_file);
-               exit (-1);
-       }
-       get_systime(&seed);
-       RAND_seed(&seed, sizeof(l_fp));
-       RAND_write_file(rand_file);
-       OpenSSL_add_all_algorithms();
+               if ((bytes = RAND_load_file(filename, -1)) == 0) {
+                       msyslog(LOG_ERR,
+                           "crypto_setup: random seed file %s missing",
+                           filename);
+                       exit (-1);
+               }
+               get_systime(&seed);
+               RAND_seed(&seed, sizeof(l_fp));
+               RAND_write_file(filename);
 #ifdef DEBUG
-       if (debug)
-               printf(
-                   "crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n",
-                   SSLeay(), rand_file, bytes);
+               if (debug)
+                       printf(
+                           "crypto_setup: OpenSSL version %lx random seed file %s bytes read %d\n",
+                           SSLeay(), filename, bytes);
+       }
 #endif
 
        /*
@@ -3865,21 +3901,21 @@ crypto_setup(void)
         * sign key. 
         */
        snprintf(filename, MAXFILENAME, "ntpkey_host_%s", sys_hostname);
-       pinfo = crypto_key(filename);
+       pinfo = crypto_key(filename, passwd);
        if (pinfo == NULL) {
                msyslog(LOG_ERR,
                    "crypto_setup: host key file %s not found or corrupt",
                    filename);
                exit (-1);
        }
-       host_pkey = pinfo->pkey;
-       sign_pkey = host_pkey;
-       hostval.fstamp = htonl(pinfo->fstamp);
-       if (host_pkey->type != EVP_PKEY_RSA) {
+       if (pinfo->pkey->type != EVP_PKEY_RSA) {
                msyslog(LOG_ERR,
                    "crypto_setup: host key is not RSA key type");
                exit (-1);
        }
+       host_pkey = pinfo->pkey;
+       sign_pkey = host_pkey;
+       hostval.fstamp = htonl(pinfo->fstamp);
        hostval.vallen = htonl(strlen(sys_hostname));
        hostval.ptr = (u_char *)sys_hostname;
        
@@ -3890,8 +3926,8 @@ crypto_setup(void)
        ptr = emalloc(len);
        pubkey.ptr = ptr;
        i2d_PublicKey(host_pkey, &ptr);
-       pubkey.vallen = htonl(len);
        pubkey.fstamp = hostval.fstamp;
+       pubkey.vallen = htonl(len);
 
        /*
         * Load optional sign key from file "ntpkey_sign_<hostname>". If
@@ -3900,7 +3936,7 @@ crypto_setup(void)
        if (sign_file != NULL) {
                snprintf(filename, MAXFILENAME, "ntpkey_sign_%s",
                    sign_file);
-               pinfo = crypto_key(filename);
+               pinfo = crypto_key(filename, passwd);
                if (pinfo != NULL)
                        sign_pkey = pinfo->pkey;
        }
@@ -3913,7 +3949,7 @@ crypto_setup(void)
        cinfo = crypto_cert(filename);
        if (cinfo == NULL) {
                msyslog(LOG_ERR,
-           "crypto_setup: certificate file %s not found or corrupt",
+                   "crypto_setup: certificate file %s not found or corrupt",
                    filename);
                exit (-1);
        }
@@ -3929,7 +3965,6 @@ crypto_setup(void)
                msyslog(LOG_ERR,
                    "crypto_setup: certificate %s not for this host %s",
                    filename, sys_hostname);
-               cert_free(cinfo);
                exit (-1);
        }
 
@@ -3940,7 +3975,6 @@ crypto_setup(void)
                msyslog(LOG_ERR,
                    "crypto_setup: certificate %s is not self-signed",
                    filename);
-               cert_free(cinfo);
                exit (-1);
        }
 
@@ -3952,17 +3986,16 @@ crypto_setup(void)
                        msyslog(LOG_ERR,
                            "crypto_setup: trusted host %s missing group name",
                            cinfo->subject);
-                       cert_free(cinfo);
                        exit (-1);
                }
                if (strcmp(cinfo->subject, sys_groupname) != 0) {
                        msyslog(LOG_ERR,
                            "crypto_setup: trusted host %s name and group name %s mismatch",
                            cinfo->subject, sys_groupname);
-                       cert_free(cinfo);
                        exit (-1);
                }
        }
+       cert_host = cinfo;
        if (sys_groupname != NULL) {
 
                /*
@@ -3971,7 +4004,7 @@ crypto_setup(void)
                 */
                snprintf(filename, MAXFILENAME, "ntpkey_iffkey_%s",
                    sys_groupname);
-               iffkey_info = crypto_key(filename);
+               iffkey_info = crypto_key(filename, passwd);
                if (iffkey_info != NULL)
                        crypto_flags |= CRYPTO_FLAG_IFF;
 
@@ -3981,7 +4014,7 @@ crypto_setup(void)
                 */
                snprintf(filename, MAXFILENAME, "ntpkey_gqkey_%s",
                    sys_groupname);
-               gqkey_info = crypto_key(filename);
+               gqkey_info = crypto_key(filename, passwd);
                if (gqkey_info != NULL)
                        crypto_flags |= CRYPTO_FLAG_GQ;
 
@@ -3991,14 +4024,13 @@ crypto_setup(void)
                 */
                snprintf(filename, MAXFILENAME, "ntpkey_mvkey_%s",
                    sys_groupname);
-               mvkey_info = crypto_key(filename);
+               mvkey_info = crypto_key(filename, passwd);
                if (mvkey_info != NULL)
                        crypto_flags |= CRYPTO_FLAG_MV;
        }
 
        /*
-        * We have survived tedious and careful checking; now strike up
-        * the dance.
+        * We met the enemy and he is us. Now strike up the dance.
         */
        crypto_flags |= CRYPTO_FLAG_ENAB | (cinfo->nid << 16);
 #ifdef DEBUG
index 66ea1e103a951a6c041c131c229e90f21605ec0f..8cdb6631728782e881c9ffecb797402ccada2b4a 100644 (file)
  *
  * ntpkey_IFFkey_<trustname>.<filestamp>
  * ntpkey_iffkey_<trustname>
- * ntpkey_IFFpar_<trustname>.<filestamp>
- * ntpkey_iffpar_<trustname>
  *     Schnorr (IFF) identity parameters and keys
  *
  * ntpkey_GQkey_<trustname>.<filestamp>,
  * ntpkey_gqkey_<trustname>
- * ntpkey_GQpar_<trustname>.<filestamp>,
- * ntpkey_gqpar_<trustname>
  *     Guillou-Quisquater (GQ) identity parameters and keys
  *
  * ntpkey_MVkeyX_<trustname>.<filestamp>,
  * ntpkey_mvkey_<hostname>
- * ntpkey_MVparX_<trustname>.<filestamp>,
- * ntpkey_mvpar_<trustname>
  *     Mu-Varadharajan (MV) identity parameters and keys
  *
  * Note: Once in a while because of some statistical fluke this program
@@ -146,9 +140,8 @@ int gen_md5         (char *);
 #ifdef OPENSSL
 EVP_PKEY *gen_rsa      (char *);
 EVP_PKEY *gen_dsa      (char *);
-EVP_PKEY *gen_iff      (char *);
-EVP_PKEY *gen_gqpar    (char *);
-EVP_PKEY *gen_gqkey    (char *, EVP_PKEY *);
+EVP_PKEY *gen_iffkey   (char *);
+EVP_PKEY *gen_gqkey    (char *);
 EVP_PKEY *gen_mv       (char *);
 int    x509            (EVP_PKEY *, const EVP_MD *, char *, char *);
 void   cb              (int, int, void *);
@@ -226,14 +219,13 @@ main(
        X509    *cert = NULL;   /* X509 certificate */
        EVP_PKEY *pkey_host = NULL; /* host key */
        EVP_PKEY *pkey_sign = NULL; /* sign key */
-       EVP_PKEY *pkey_iffkey = NULL; /* IFF keys and parameters */
-       EVP_PKEY *pkey_gqpar = NULL; /* GQ parameters */
-       EVP_PKEY *pkey_gqkey = NULL; /* GQ keys */
+       EVP_PKEY *pkey_iffkey = NULL; /* IFF keys */
+       EVP_PKEY *pkey_gqkey = NULL; /* GQ parameters */
        EVP_PKEY *pkey_mv = NULL; /* MV parameters */
        int     hostkey = 0;    /* generate RSA keys */
-       int     iffkey = 0;     /* generate IFF keys and parameters */
-       int     gqpar = 0;      /* generate GQ parameters */
-       int     gqkey = 0;      /* update GQ keys */
+       int     iffkey = 0;     /* generate IFF keys */
+       int     gqpar = 0;      /* generate GQ keys */
+       int     gqkey = 0;      /* not used */
        int     mvpar = 0;      /* generate MV parameters */
        int     mvkey = 0;      /* update MV keys */
        char    *sign = NULL;   /* sign key */
@@ -245,7 +237,6 @@ main(
        char    *grpkey = NULL; /* identity extension */
        int     nid;            /* X509 digest/signature scheme */
        FILE    *fstr = NULL;   /* file handle */
-       u_int   temp;
 #define iffsw   HAVE_OPT(ID_KEY)
 #endif /* OPENSSL */
        char    hostbuf[MAXHOSTNAME + 1];
@@ -309,7 +300,7 @@ main(
            gqpar++;
 
        if (HAVE_OPT( GQ_KEYS ))
-           gqkey++;
+           gqkey++;                    /* not used */
 
        if (HAVE_OPT( HOST_KEY ))
            hostkey++;
@@ -366,32 +357,38 @@ main(
         */
        ERR_load_crypto_strings();
        OpenSSL_add_all_algorithms();
-       if (RAND_file_name(pathbuf, MAXFILENAME) == NULL) {
-               fprintf(stderr, "RAND_file_name %s\n",
-                   ERR_error_string(ERR_get_error(), NULL));
-               exit (-1);
-       }
-       temp = RAND_load_file(pathbuf, -1);
-       if (temp == 0) {
+       if (!RAND_status()) {
+               u_int   temp;
+
+               if (RAND_file_name(pathbuf, MAXFILENAME) == NULL) {
+                       fprintf(stderr, "RAND_file_name %s\n",
+                           ERR_error_string(ERR_get_error(), NULL));
+                       exit (-1);
+               }
+               temp = RAND_load_file(pathbuf, -1);
+               if (temp == 0) {
+                       fprintf(stderr,
+                           "RAND_load_file %s not found or empty\n",
+                           pathbuf);
+                       exit (-1);
+               }
                fprintf(stderr,
-                   "RAND_load_file %s not found or empty\n", pathbuf);
-               exit (-1);
+                   "Random seed file %s %u bytes\n", pathbuf, temp);
+               RAND_add(&epoch, sizeof(epoch), 4.0);
        }
-       fprintf(stderr,
-           "Random seed file %s %u bytes\n", pathbuf, temp);
-       RAND_add(&epoch, sizeof(epoch), 4.0);
 #endif
 
        /*
-        * Generate new parameters and keys as requested. These replace
-        * any values already generated.
+        * Generate new MD5 keys if requested. These replace any
+        * keysalready generated.
         */
        if (md5key)
                gen_md5("MD5");
 #ifdef OPENSSL
        /*
-        * Create new host keys if requested; otherwise, look for
-        * existing host keys. If not found, create a new host RSA
+        * Create a new encrypted RSA host key file if requested;
+        * otherwise, look for an existing host key file. If not found,
+        * create a new encrypted RSA host key file containing a
         * public/private key pair.
         */
        if (hostkey)
@@ -414,9 +411,9 @@ main(
        }
 
        /*
-        * Create new sign keys if requested; otherwise, look for
-        * existing sign keys. If not found, use the host keys instead.
-        * Either RSA or DSA keys can be selected by option.
+        * Create new encrypted RSA or DSA sign key file if requested;
+        * otherwise, look for an existing sign key file. If not found,
+        * use the host keys instead.
         */
        if (sign != NULL)
                pkey_sign = genkey(sign, "sign");
@@ -434,78 +431,79 @@ main(
        }
 
        /*
-        * Create new GQ parameters if requested; otherwise, look for
-        * existing GQ parameters. The parameters are instantiated in
-        * all group hosts. The keys are generated separately by each
-        * host.
+        * Create new encrypted GQ parameter file if requested;
+        * otherwise, look for an exisiting file. If found, fetch the
+        * public key for the certificate.
         */
-       if (gqpar) {
-               pkey_gqpar = gen_gqpar("gqpar");
-               if (pkey_gqpar != NULL)
-                       gqkey++;
-       }
-       if (pkey_gqpar == NULL) {
-               sprintf(filename, "ntpkey_gqpar_%s", trustname);
-               pkey_gqpar = readkey(filename, passwd1, &fstamp);
-               if (pkey_gqpar != NULL) {
+       if (gqpar)
+               pkey_gqkey = gen_gqkey("gqkey");
+       if (pkey_gqkey == NULL) {
+               sprintf(filename, "ntpkey_gqkey_%s", trustname);
+               pkey_gqkey = readkey(filename, passwd1, &fstamp);
+               if (pkey_gqkey != NULL) {
                        readlink(filename, filename, sizeof(filename));
                        fprintf(stderr, "Using GQ parameters %s\n",
                            filename);
                }
        }
+       if (pkey_gqkey != NULL)
+               grpkey = BN_bn2hex(pkey_gqkey->pkey.rsa->q);
 
        /*
-        * Write the GQ parameters to the stdout stream redirected to a
-        * file. Ordinarily, the file is copied to another machine and
-        * installed under the name in the file header.
+        * Write the nonencrypted GQ parameters to the stdout stream.
+        * The parameer file is the keys file with the private key
+        * obscured.
         */
-       if (pkey_gqpar != NULL && strcmp(passwd1, passwd2) != 0) {
+       if (pkey_gqkey != NULL && HAVE_OPT(ID_KEY)) {
                RSA     *rsa;
 
                epoch = fstamp - JAN_1970;
-               sprintf(filename, "ntpkey_GQpar_%s.%u", trustname,
+               sprintf(filename, "ntpkey_gqpar_%s.%u", trustname,
                    fstamp);
-               fprintf(stderr,
-                   "Writing GQ parameters %s to stdout\n", filename);
+               fprintf(stderr, "Writing GQ parameters %s to stdout\n",
+                   filename);
                fprintf(stdout, "# %s\n# %s\n", filename,
                    ctime(&epoch));
-               rsa = pkey_gqpar->pkey.rsa;
+               rsa = pkey_gqkey->pkey.rsa;
+               BN_copy(rsa->p, BN_value_one());
+               BN_copy(rsa->q, BN_value_one());
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_RSA(pkey, rsa);
-               PEM_write_PrivateKey(stdout, pkey, EVP_des_cbc(), NULL,
-                   0, NULL, passwd2);
+               PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL,
+                   NULL);
                fclose(stdout);
                if (debug)
                        RSA_print_fp(stderr, rsa, 0);
        }
 
        /*
-        * Create new GQ keys if requested. Otherwise, look for
-        * exisiting GQ keys and fetch the public key for the
-        * certificate..
+        * Write the encrypted GQ keys to the stdout stream.
         */
-       if (pkey_gqpar != NULL && gqkey)
-               pkey_gqkey = gen_gqkey("gqkey", pkey_gqpar);
-       if (pkey_gqkey == NULL) {
-               sprintf(filename, "ntpkey_gqkey_%s", trustname);
-               pkey_gqkey = readkey(filename, passwd1, &fstamp);
-               if (pkey_gqkey != NULL) {
-                       readlink(filename, filename, sizeof(filename));
-                       fprintf(stderr, "Using GQ keys %s\n",
-                           filename);
-               }
+       if (pkey_gqkey != NULL && strcmp(passwd1, passwd2) != 0) {
+               RSA     *rsa;
+
+               sprintf(filename, "ntpkey_GQkey_%s.%u", trustname,
+                   fstamp);
+               fprintf(stderr, "Writing GQ keys %s to stdout\n",
+                   filename);
+               fprintf(stdout, "# %s\n# %s\n", filename,
+                   ctime(&epoch));
+               rsa = pkey_gqkey->pkey.rsa;
+               pkey = EVP_PKEY_new();
+               EVP_PKEY_assign_RSA(pkey, rsa);
+               PEM_write_PrivateKey(stdout, pkey,
+                   EVP_des_cbc(), NULL, 0, NULL, passwd2);
+               fclose(stdout);
+               if (debug)
+                       RSA_print_fp(stderr, rsa, 0);
        }
-       if (pkey_gqkey != NULL)
-               grpkey = BN_bn2hex(pkey_gqkey->pkey.rsa->q);
 
        /*
-        * Create new IFF keys if requested; otherwise, look for
-        * existing IFF keys. In the IFF scheme the keys include the
-        * parameters, which are not generated separately as in the GQ
-        * scheme.
+        * Create new encrypted IFF keys file if requested; otherwise,
+        * look for existing keys file.
         */
        if (iffkey)
-               pkey_iffkey = gen_iff("iffkey");
+               pkey_iffkey = gen_iffkey("iffkey");
        if (pkey_iffkey == NULL) {
                sprintf(filename, "ntpkey_iffkey_%s", trustname);
                pkey_iffkey = readkey(filename, passwd1, &fstamp);
@@ -517,24 +515,45 @@ main(
        }
 
        /*
-        * Write the IFF parameters to the stdout stream redirected to a
-        * file. Ordinarily, the file is copied to another machine and
-        * installed under the name in the file header. Then, a soft
-        * link is installed to it from "ntpkey_iffkey_<hostname>".
+        * Write the nonencrypted IFF parameters to the stdout stream.
+        * The parameer file is the keys file with the private key
+        * obscured.
+        */
+       if (pkey_iffkey != NULL && HAVE_OPT(ID_KEY)) {
+               DSA     *dsa;
+
+               epoch = fstamp - JAN_1970;
+               sprintf(filename, "ntpkey_iffpar_%s.%u", trustname,
+                   fstamp);
+               fprintf(stderr, "Writing IFF parameters %s to stdout\n",
+                   filename);
+               fprintf(stdout, "# %s\n# %s\n", filename,
+                   ctime(&epoch));
+               dsa = pkey_iffkey->pkey.dsa;
+               BN_copy(dsa->priv_key, BN_value_one());
+               pkey = EVP_PKEY_new();
+               EVP_PKEY_assign_DSA(pkey, dsa);
+               PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL,
+                   NULL);
+               fclose(stdout);
+               if (debug)
+                       DSA_print_fp(stderr, dsa, 0);
+       }
+
+       /*
+        * Write the encrypted IFF keys to the stdout stream.
         */
        if (pkey_iffkey != NULL && strcmp(passwd1, passwd2) != 0) {
                DSA     *dsa;
 
                epoch = fstamp - JAN_1970;
-               sprintf(filename, "ntpkey_IFFpar_%s.%u", trustname,
+               sprintf(filename, "ntpkey_IFFkey_%s.%u", trustname,
                    fstamp);
-               fprintf(stderr,
-                   "Writing IFF client key %s to stdout\n", filename);
+               fprintf(stderr, "Writing IFF keys %s to stdout\n",
+                   filename);
                fprintf(stdout, "# %s\n# %s\n", filename,
                    ctime(&epoch));
                dsa = pkey_iffkey->pkey.dsa;
-               if (HAVE_OPT(ID_KEY))
-                       BN_copy(dsa->priv_key, BN_value_one());
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_DSA(pkey, dsa);
                PEM_write_PrivateKey(stdout, pkey, EVP_des_cbc(), NULL,
@@ -550,7 +569,7 @@ main(
         */
        if (mvpar)
                pkey_mv = gen_mv("mv");
-       if (strcmp(passwd1, passwd2) != 0)
+       if (strcmp(passwd1, passwd2) != 0 || HAVE_OPT(ID_KEY))
                exit (0);
 
        /*
@@ -609,8 +628,6 @@ gen_md5(
        fprintf(stderr, "Generating MD5 keys...\n");
        str = fheader("MD5key", trustname);
        keyid = BN_new(); key = BN_new();
-       NTP_INSIST(keyid != NULL);
-       NTP_INSIST(key != NULL);
        BN_rand(keyid, 16, -1, 0);
        BN_rand(key, 128, -1, 0);
        BN_bn2bin(key, bin);
@@ -767,9 +784,8 @@ gen_rsa(
         * Write the RSA parameters and keys as a RSA private key
         * encoded in PEM.
         */
-       str = fheader("RSAkey", hostname);
+       str = fheader("RSApar", hostname);
        pkey = EVP_PKEY_new();
-       NTP_INSIST(pkey != NULL);
        EVP_PKEY_assign_RSA(pkey, rsa);
        PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
            passwd2);
@@ -826,7 +842,6 @@ gen_dsa(
         */
        str = fheader("DSAkey", hostname);
        pkey = EVP_PKEY_new();
-       NTP_INSIST(pkey != NULL);
        EVP_PKEY_assign_DSA(pkey, dsa);
        PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
            passwd2);
@@ -862,8 +877,11 @@ gen_dsa(
  * group clients. Alice challenges Bob to confirm identity using the
  * protocol described below.
  */
+/*
+ * Generate Schnorr (IFF) keys.
+ */
 EVP_PKEY *                     /* DSA cuckoo nest */
-gen_iff(
+gen_iffkey(
        char    *id             /* file name id */
        )
 {
@@ -895,21 +913,13 @@ gen_iff(
         * these keys are distributed to all members of the group.
         */
        b = BN_new(); r = BN_new(); k = BN_new();
-       NTP_INSIST(b != NULL);
-       NTP_INSIST(r != NULL);
-       NTP_INSIST(k != NULL);
        u = BN_new(); v = BN_new(); w = BN_new(); ctx = BN_CTX_new();
-       NTP_INSIST(u != NULL);
-       NTP_INSIST(v != NULL);
-       NTP_INSIST(w != NULL);
-       NTP_INSIST(ctx != NULL);
        BN_rand(b, BN_num_bits(dsa->q), -1, 0); /* a */
        BN_mod(b, b, dsa->q, ctx);
        BN_sub(v, dsa->q, b);
        BN_mod_exp(v, dsa->g, v, dsa->p, ctx); /* g^(q - b) mod p */
        BN_mod_exp(u, dsa->g, b, dsa->p, ctx);  /* g^b mod p */
        BN_mod_mul(u, u, v, dsa->p, ctx);
-       NTP_INSIST(u->d != NULL);
        temp = BN_is_one(u);
        fprintf(stderr,
            "Confirm g^(q - b) g^b = 1 mod p: %s\n", temp == 1 ?
@@ -962,14 +972,16 @@ gen_iff(
        }
 
        /*
-        * Write the IFF server parameters and keys as a DSA private key
-        * encoded in PEM.
+        * Write the IFF keys as an encrypted DSA private key encoded in
+        * PEM.
         *
         * p    modulus p
         * q    modulus q
         * g    generator g
         * priv_key b
         * public_key v
+        * kinv not used
+        * r    not used
         */
        str = fheader("IFFkey", trustname);
        pkey = EVP_PKEY_new();
@@ -983,7 +995,6 @@ gen_iff(
        return (pkey);
 }
 
-
 /*
  * Generate Guillou-Quisquater (GQ) parameters and keys
  *
@@ -1008,21 +1019,27 @@ gen_iff(
  * scheme. Alice challenges Bob to confirm identity using the protocol
  * described below.
  */
+/*
+ * Generate Guillou-Quisquater (GQ) parameters file.
+ */
 EVP_PKEY *                     /* RSA cuckoo nest */
-gen_gqpar(
+gen_gqkey(
        char    *id             /* file name id */
        )
 {
        EVP_PKEY *pkey;         /* private key */
-       RSA     *rsa;           /* GQ parameters */
+       RSA     *rsa;           /* RSA parameters */
        BN_CTX  *ctx;           /* BN working space */
+       BIGNUM  *u, *v, *g, *k, *r, *y; /* BN temps */
        FILE    *str;
+       u_int   temp;
 
        /*
         * Generate RSA parameters for use as GQ parameters.
         */
        fprintf(stderr,
-           "Generating GQ parameters (%d bits)...\n", modulus);
+           "Generating GQ parameters (%d bits)...\n",
+            modulus);
        rsa = RSA_generate_key(modulus, 3, cb, "GQ");
        fprintf(stderr, "\n");
        if (rsa == NULL) {
@@ -1030,74 +1047,22 @@ gen_gqpar(
                    ERR_error_string(ERR_get_error(), NULL));
                return (NULL);
        }
+       ctx = BN_CTX_new(); u = BN_new(); v = BN_new();
+       g = BN_new(); k = BN_new(); r = BN_new(); y = BN_new();
 
        /*
         * Generate the group key b, which is saved in the e member of
-        * the RSA structure. These values are distributed to all
-        * members of the group, but shielded from all other groups. We
-        * don't use all the parameters, but set the unused ones to a
-        * small number to minimize the file size.
+        * the RSA structure. The group key is transmitted to each group
+        * member encrypted by the member private key.
         */
        ctx = BN_CTX_new();
        BN_rand(rsa->e, BN_num_bits(rsa->n), -1, 0); /* b */
        BN_mod(rsa->e, rsa->e, rsa->n, ctx);
-       BN_copy(rsa->d, BN_value_one());
-       BN_copy(rsa->p, BN_value_one());
-       BN_copy(rsa->q, BN_value_one());
-       BN_copy(rsa->dmp1, BN_value_one());
-       BN_copy(rsa->dmq1, BN_value_one());
-       BN_copy(rsa->iqmp, BN_value_one());
-
-       /*
-        * Write the GQ parameters as a RSA private key encoded in PEM.
-        * The public and private keys are filled in later.
-        *
-        * n    modulus n
-        * e    group key b
-        * (remaining values are not used)
-        */
-       str = fheader("GQpar", trustname);
-       pkey = EVP_PKEY_new();
-       EVP_PKEY_assign_RSA(pkey, rsa);
-       PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
-            passwd2);
-       fclose(str);
-       if (debug)
-               RSA_print_fp(stderr, rsa, 0);
-       fslink(id, trustname);
-       return (pkey);
-}
-
-
-/*
- * Update Guillou-Quisquater (GQ) parameters
- */
-EVP_PKEY *                     /* RSA cuckoo nest */
-gen_gqkey(
-       char    *id,            /* file name id */
-       EVP_PKEY *gqpar         /* GQ parameters */
-       )
-{
-       EVP_PKEY *pkey;         /* private key */
-       RSA     *rsa;           /* RSA parameters */
-       BN_CTX  *ctx;           /* BN working space */
-       BIGNUM  *u, *v, *g, *k, *r, *y; /* BN temps */
-       FILE    *str;
-       u_int   temp;
-
-       /*
-        * Generate GQ keys. Note that the group key b is the e member
-        * of the GQ parameters.
-        */
-       fprintf(stderr, "Updating GQ keys (%d bits)...\n", modulus);
-       ctx = BN_CTX_new(); u = BN_new(); v = BN_new();
-       g = BN_new(); k = BN_new(); r = BN_new(); y = BN_new();
 
        /*
         * When generating his certificate, Bob rolls random private key
         * u. 
         */
-       rsa = gqpar->pkey.rsa;
        BN_rand(u, BN_num_bits(rsa->n), -1, 0); /* u */
        BN_mod(u, u, rsa->n, ctx);
        BN_mod_inverse(v, u, rsa->n, ctx);      /* u^-1 mod n */
@@ -1164,15 +1129,22 @@ gen_gqkey(
        }
 
        /*
-        * Write the GQ parameters and keys as a RSA private key encoded
-        * in PEM.
+        * Write the GQ parameter file as an encrypted RSA private key
+        * encoded in PEM.
         *
         * n    modulus n
         * e    group key b
+        * d    not used
         * p    private key u
         * q    public key (u^-1)^b
-        * (remaining values are not used)
+        * dmp1 not used
+        * dmq1 not used
+        * iqmp not used
         */
+       BN_copy(rsa->d, BN_value_one());
+       BN_copy(rsa->dmp1, BN_value_one());
+       BN_copy(rsa->dmq1, BN_value_one());
+       BN_copy(rsa->iqmp, BN_value_one());
        str = fheader("GQkey", trustname);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
@@ -1284,27 +1256,15 @@ gen_mv(
            "Generating MV parameters for %d keys (%d bits)...\n", n,
            modulus / n);
        ctx = BN_CTX_new(); u = BN_new(); v = BN_new(); w = BN_new();
-       NTP_INSIST(ctx != NULL);
-       NTP_INSIST(u != NULL);
-       NTP_INSIST(v != NULL);
-       NTP_INSIST(w != NULL);
        b = BN_new(); b1 = BN_new();
-       NTP_INSIST(b != NULL);
-       NTP_INSIST(b1 != NULL);
        dsa = DSA_new();
-       NTP_INSIST(dsa != NULL);
        dsa->p = BN_new();
-       NTP_INSIST(dsa->p != NULL);
        dsa->q = BN_new();
-       NTP_INSIST(dsa->q != NULL);
        dsa->g = BN_new();
-       NTP_INSIST(dsa->g != NULL);
        s = malloc((n + 1) * sizeof(BIGNUM));
        s1 = malloc((n + 1) * sizeof(BIGNUM));
-       for (j = 1; j <= n; j++) {
+       for (j = 1; j <= n; j++)
                s1[j] = BN_new();
-               NTP_INSIST(s1[j] != NULL);
-               }
        temp = 0;
        for (j = 1; j <= n; j++) {
                while (1) {
@@ -1373,7 +1333,6 @@ gen_mv(
                BN_rand(dsa->g, BN_num_bits(dsa->p) - 1, 0, 0);
                BN_mod(dsa->g, dsa->g, dsa->p, ctx);
                BN_gcd(u, dsa->g, v, ctx);
-               NTP_INSIST(u->d != NULL);
                if (!BN_is_one(u))
                        continue;
 
@@ -1390,7 +1349,6 @@ gen_mv(
         */
        for (j = 1; j <= n; j++) {
                s[j] = BN_new();
-               NTP_INSIST(s[j] != NULL);
                BN_add(s[j], dsa->q, s1[j]);
                BN_div(s[j], u, s[j], s1[j], ctx);
        }
@@ -1407,7 +1365,6 @@ gen_mv(
        x = malloc((n + 1) * sizeof(BIGNUM));
        for (j = 1; j <= n; j++) {
                x[j] = BN_new();
-               NTP_INSIST(x[j] != NULL);
                while (1) {
                        BN_rand(x[j], BN_num_bits(dsa->q), 0, 0);
                        BN_mod(x[j], x[j], dsa->q, ctx);
@@ -1425,7 +1382,6 @@ gen_mv(
        a = malloc((n + 1) * sizeof(BIGNUM));
        for (i = 0; i <= n; i++) {
                a[i] = BN_new();
-               NTP_INSIST(a[i] != NULL);
                BN_one(a[i]);
        }
        for (j = 1; j <= n; j++) {
@@ -1447,7 +1403,6 @@ gen_mv(
        g = malloc((n + 1) * sizeof(BIGNUM));
        for (i = 0; i <= n; i++) {
                g[i] = BN_new();
-               NTP_INSIST(g[i] != NULL);
                BN_mod_exp(g[i], dsa->g, a[i], dsa->p, ctx);
        }
 
@@ -1482,7 +1437,6 @@ gen_mv(
         * since it is expensive to compute.
         */
        biga = BN_new();
-       NTP_INSIST(biga != NULL);
        BN_one(biga);
        for (j = 1; j <= n; j++) {
                for (i = 0; i < n; i++) {
@@ -1517,8 +1471,6 @@ gen_mv(
        xhat = malloc((n + 1) * sizeof(BIGNUM));
        for (j = 1; j <= n; j++) {
                xbar[j] = BN_new(); xhat[j] = BN_new();
-               NTP_INSIST(xbar[j] != NULL);
-               NTP_INSIST(xhat[j] != NULL);
                BN_zero(xbar[j]);
                BN_set_word(v, n);
                for (i = 1; i <= n; i++) {
@@ -1539,7 +1491,6 @@ gen_mv(
         * otherwise, the plaintext and cryptotext would be identical.
         */
        ss = BN_new();
-       NTP_INSIST(ss != NULL);
        BN_copy(ss, dsa->q);
        BN_div(ss, u, dsa->q, s1[n], ctx);
 
@@ -1552,9 +1503,6 @@ gen_mv(
         * enabling key is changed.
         */
        bige = BN_new(); gbar = BN_new(); ghat = BN_new();
-       NTP_INSIST(bige != NULL);
-       NTP_INSIST(gbar != NULL);
-       NTP_INSIST(ghat != NULL);
        BN_mod_exp(bige, biga, ss, dsa->p, ctx);
        BN_mod_exp(gbar, dsa->g, ss, dsa->p, ctx);
        BN_mod_mul(v, ss, b, dsa->q, ctx);
@@ -1599,7 +1547,6 @@ gen_mv(
         */
        str = fheader("MVpar", trustname);
        pkey = EVP_PKEY_new();
-       NTP_INSIST(pkey != NULL);
        EVP_PKEY_assign_DSA(pkey, dsa);
        PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
            passwd2);
@@ -1615,14 +1562,11 @@ gen_mv(
         * for its use.
         */
        sdsa = DSA_new();
-       NTP_INSIST(sdsa != NULL);
        sdsa->p = BN_dup(dsa->p);
        sdsa->q = BN_dup(BN_value_one());
        sdsa->g = BN_dup(BN_value_one());
        sdsa->priv_key = BN_new();
-       NTP_INSIST(sdsa->priv_key != NULL);
        sdsa->pub_key = BN_new();
-       NTP_INSIST(sdsa->pub_key != NULL);
        for (j = 1; j <= n; j++) {
                BN_copy(sdsa->priv_key, xbar[j]);
                BN_copy(sdsa->pub_key, xhat[j]);
@@ -1651,7 +1595,6 @@ gen_mv(
                sprintf(ident, "MVkey%d", j);
                str = fheader(ident, trustname);
                pkey1 = EVP_PKEY_new();
-               NTP_INSIST(pkey1 != NULL);
                EVP_PKEY_set1_DSA(pkey1, sdsa);
                PEM_write_PrivateKey(str, pkey1, EVP_des_cbc(), NULL, 0,
                    NULL, passwd2);
@@ -1685,7 +1628,7 @@ gen_mv(
 
 
 /*
- * Generate X509v3 scertificate.
+ * Generate X509v3 certificate.
  *
  * The certificate consists of the version number, serial number,
  * validity interval, issuer name, subject name and public key. For a
@@ -1722,10 +1665,8 @@ x509     (
        id = OBJ_nid2sn(md->pkey_type);
        fprintf(stderr, "Generating certificate %s\n", id);
        cert = X509_new();
-       NTP_INSIST(cert != NULL);
        X509_set_version(cert, 2L);
        serial = ASN1_INTEGER_new();
-       NTP_INSIST(serial != NULL);
        ASN1_INTEGER_set(serial, epoch + JAN_1970);
        X509_set_serialNumber(cert, serial);
        ASN1_INTEGER_free(serial);