* 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 */
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 *);
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) {
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);
}
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
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
/*
* 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 */
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
* 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) {
if (strcmp(yp->subject, peer->subject) != 0)
continue;
- peer->grpkey = yp->grpkey;
+ peer->grpkey = xp->grpkey;
peer->crypto |= CRYPTO_FLAG_VALID;
/*
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);
*/
static struct pkey_info *
crypto_key(
- char *cp /* file name */
+ char *cp, /* file name */
+ char *passwd1 /* password */
)
{
FILE *str; /* file handle */
* 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",
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);
* 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);
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
/*
* 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;
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
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;
}
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);
}
msyslog(LOG_ERR,
"crypto_setup: certificate %s not for this host %s",
filename, sys_hostname);
- cert_free(cinfo);
exit (-1);
}
msyslog(LOG_ERR,
"crypto_setup: certificate %s is not self-signed",
filename);
- cert_free(cinfo);
exit (-1);
}
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) {
/*
*/
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;
*/
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;
*/
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
*
* 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
#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 *);
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 */
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];
gqpar++;
if (HAVE_OPT( GQ_KEYS ))
- gqkey++;
+ gqkey++; /* not used */
if (HAVE_OPT( HOST_KEY ))
hostkey++;
*/
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)
}
/*
- * 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");
}
/*
- * 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);
}
/*
- * 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,
*/
if (mvpar)
pkey_mv = gen_mv("mv");
- if (strcmp(passwd1, passwd2) != 0)
+ if (strcmp(passwd1, passwd2) != 0 || HAVE_OPT(ID_KEY))
exit (0);
/*
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);
* 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);
*/
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);
* 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 */
)
{
* 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 ?
}
/*
- * 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();
return (pkey);
}
-
/*
* Generate Guillou-Quisquater (GQ) parameters and keys
*
* 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) {
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 */
}
/*
- * 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);
"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) {
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;
*/
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);
}
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);
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++) {
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);
}
* 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++) {
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++) {
* 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);
* 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);
*/
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);
* 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]);
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);
/*
- * 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
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);