⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntp-keygen.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 4 页
字号:
		BN_one(u);		for (i = 0; i <= n; i++) {			BN_set_word(v, i);			BN_mod_exp(v, x[j], v, dsa->q, ctx);			BN_mod_mul(v, v, a[i], dsa->q, ctx);			BN_mod_exp(v, dsa->g, v, dsa->p, ctx);			BN_mod_mul(u, u, v, dsa->p, ctx);		}		if (!BN_is_one(u))			temp = 0;	}	fprintf(stderr,	    "Confirm prod(g[i]^(x[j]^i)) = 1 for all i, j: %s\n", temp ?	    "yes" : "no");	if (!temp) {		rval = -1;		return (NULL);	}	/*	 * Make private encryption key A. Keep it around for awhile,	 * since it is expensive to compute.	 */	biga = BN_new();	BN_one(biga);	for (j = 1; j <= n; j++) {		for (i = 0; i < n; i++) {			BN_set_word(v, i);			BN_mod_exp(v, x[j], v, dsa->q, ctx);			BN_mod_exp(v, g[i], v, dsa->p, ctx);			BN_mod_mul(biga, biga, v, dsa->p, ctx);		}	}	/*	 * Roll private random group key b mod q (0 < b < q), where	 * gcd(b, q) = 1 to guarantee b^1 exists, then compute b^-1	 * mod q. If b is changed, the client keys must be recomputed.	 */	while (1) {		BN_rand(b, BN_num_bits(dsa->q), 0, 0);		BN_mod(b, b, dsa->q, ctx);		BN_gcd(u, b, dsa->q, ctx);		if (BN_is_one(u))			break;	}	BN_mod_inverse(b1, b, dsa->q, ctx);	/*	 * Make private client keys (xbar[j], xhat[j]) for all j. Note	 * that the keys for the jth client involve s[j], but not s'[j]	 * or the product s = prod(s'[j]) mod q, which is the enabling	 * key.	 */	xbar = malloc((n + 1) * sizeof(BIGNUM));	xhat = malloc((n + 1) * sizeof(BIGNUM));	for (j = 1; j <= n; j++) {		xbar[j] = BN_new(); xhat[j] = BN_new();		BN_zero(xbar[j]);		BN_set_word(v, n);		for (i = 1; i <= n; i++) {			if (i == j)				continue;			BN_mod_exp(u, x[i], v, dsa->q, ctx);			BN_add(xbar[j], xbar[j], u);		}		BN_mod_mul(xbar[j], xbar[j], b1, dsa->q, ctx);		BN_mod_exp(xhat[j], x[j], v, dsa->q, ctx);		BN_mod_mul(xhat[j], xhat[j], s[j], dsa->q, ctx);	}	/*	 * The enabling key is initially q by construction. We can	 * revoke client j by dividing q by s'[j]. The quotient becomes	 * the enabling key s. Note we always have to revoke one key;	 * otherwise, the plaintext and cryptotext would be identical.	 */	ss = BN_new();	BN_copy(ss, dsa->q);	BN_div(ss, u, dsa->q, s1[n], ctx);	/*	 * Make private server encryption key E = A^s and public server	 * keys gbar = g^s mod p and ghat = g^(s b) mod p. The (gbar,	 * ghat) is the public key provided to the server, which uses it	 * to compute the session encryption key and public key included	 * in its messages. These values must be regenerated if the	 * enabling key is changed.	 */	bige = BN_new(); gbar = BN_new(); ghat = BN_new();	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);	BN_mod_exp(ghat, dsa->g, v, dsa->p, ctx);	/*	 * We produce the key media in three steps. The first step is to	 * generate the private values that do not depend on the	 * enabling key. These include the server values p, q, g, b, A	 * and the client values s'[j], xbar[j] and xhat[j] for each j.	 * The p, xbar[j] and xhat[j] values are encoded in private	 * files which are distributed to respective clients. The p, q,	 * g, A and s'[j] values (will be) written to a secret file to	 * be read back later.	 *	 * The secret file (will be) read back at some later time to	 * enable/disable individual keys and generate/regenerate the	 * enabling key s. The p, q, E, gbar and ghat values are written	 * to a secret file to be read back later by the server.	 *	 * The server reads the secret file and rolls the session key	 * k, which is used only once, then computes E^k, gbar^k and	 * ghat^k. The E^k is the session encryption key. The encrypted	 * data, gbar^k and ghat^k are transmtted to clients in an	 * extension field. The client receives the message and computes	 * x = (gbar^k)^xbar[j] (ghat^k)^xhat[j], finds the session	 * encryption key E^k as the inverse x^-1 and decrypts the data.	 */	BN_copy(dsa->g, bige);	dsa->priv_key = BN_dup(gbar);	dsa->pub_key = BN_dup(ghat);	/*	 * Write the MV server parameters and keys as a DSA private key	 * encoded in PEM.	 *	 * p	modulus p	 * q	modulus q (used only to generate k)	 * g	E mod p	 * priv_key gbar mod p	 * pub_key ghat mod p	 */	str = fheader("MVpar", trustname);	pkey = EVP_PKEY_new();	EVP_PKEY_assign_DSA(pkey, dsa);	PEM_write_PrivateKey(str, pkey, passwd2 ? EVP_des_cbc() : NULL,	    NULL, 0, NULL, passwd2);	fclose(str);	if (debug)		DSA_print_fp(stdout, dsa, 0);	fslink(id, trustname);	/*	 * Write the parameters and private key (xbar[j], xhat[j]) for	 * all j as a DSA private key encoded in PEM. It is used only by	 * the designated recipient(s) who pay a suitably outrageous fee	 * for its use.	 */	sdsa = DSA_new();	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();	sdsa->pub_key = BN_new();	for (j = 1; j <= n; j++) {		BN_copy(sdsa->priv_key, xbar[j]);		BN_copy(sdsa->pub_key, xhat[j]);		BN_mod_exp(v, dsa->priv_key, sdsa->pub_key, dsa->p,		    ctx);		BN_mod_exp(u, dsa->pub_key, sdsa->priv_key, dsa->p,		    ctx);		BN_mod_mul(u, u, v, dsa->p, ctx);		BN_mod_mul(u, u, dsa->g, dsa->p, ctx);		BN_free(xbar[j]); BN_free(xhat[j]);		BN_free(x[j]); BN_free(s[j]); BN_free(s1[j]);		if (!BN_is_one(u)) {			fprintf(stderr, "Revoke key %d\n", j);			continue;		}		/*		 * Write the client parameters as a DSA private key		 * encoded in PEM. We don't make links for these.		 *		 * p	modulus p		 * priv_key xbar[j] mod q		 * pub_key xhat[j] mod q		 * (remaining values are not used)		 */		sprintf(ident, "MVkey%d", j);		str = fheader(ident, trustname);		pkey1 = EVP_PKEY_new();		EVP_PKEY_set1_DSA(pkey1, sdsa);		PEM_write_PrivateKey(str, pkey1, passwd2 ?		    EVP_des_cbc() : NULL, NULL, 0, NULL, passwd2);		fclose(str);		fprintf(stderr, "ntpkey_%s_%s.%lu\n", ident, trustname,		    epoch + JAN_1970);		if (debug)			DSA_print_fp(stdout, sdsa, 0);		EVP_PKEY_free(pkey1);	}	/*	 * Free the countries.	 */	for (i = 0; i <= n; i++) {		BN_free(a[i]);		BN_free(g[i]);	}	BN_free(u); BN_free(v); BN_free(w); BN_CTX_free(ctx);	BN_free(b); BN_free(b1); BN_free(biga); BN_free(bige);	BN_free(ss); BN_free(gbar); BN_free(ghat);	DSA_free(sdsa);	/*	 * Free the world.	 */	free(x); free(a); free(g); free(s); free(s1);	free(xbar); free(xhat);	return (pkey);}/* * Generate X509v3 scertificate. * * The certificate consists of the version number, serial number, * validity interval, issuer name, subject name and public key. For a * self-signed certificate, the issuer name is the same as the subject * name and these items are signed using the subject private key. The * validity interval extends from the current time to the same time one * year hence. For NTP purposes, it is convenient to use the NTP seconds * of the current time as the serial number. */intx509	(	EVP_PKEY *pkey,		/* generic signature algorithm */	const EVP_MD *md,	/* generic digest algorithm */	char	*gqpub,		/* identity extension (hex string) */	char	*exten		/* private cert extension */	){	X509	*cert;		/* X509 certificate */	X509_NAME *subj;	/* distinguished (common) name */	X509_EXTENSION *ex;	/* X509v3 extension */	FILE	*str;		/* file handle */	ASN1_INTEGER *serial;	/* serial number */	const char *id;		/* digest/signature scheme name */	char	pathbuf[MAXFILENAME + 1];	/*	 * Generate X509 self-signed certificate.	 *	 * Set the certificate serial to the NTP seconds for grins. Set	 * the version to 3. Set the subject name and issuer name to the	 * subject name in the request. Set the initial validity to the	 * current time and the final validity one year hence. 	 */	id = OBJ_nid2sn(md->pkey_type);	fprintf(stderr, "Generating certificate %s\n", id);	cert = X509_new();	X509_set_version(cert, 2L);	serial = ASN1_INTEGER_new();	ASN1_INTEGER_set(serial, epoch + JAN_1970);	X509_set_serialNumber(cert, serial);	ASN1_INTEGER_free(serial);	X509_time_adj(X509_get_notBefore(cert), 0L, &epoch);	X509_time_adj(X509_get_notAfter(cert), YEAR, &epoch);	subj = X509_get_subject_name(cert);	X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,	    (unsigned char *) hostname, strlen(hostname), -1, 0);	subj = X509_get_issuer_name(cert);	X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,	    (unsigned char *) trustname, strlen(trustname), -1, 0);	if (!X509_set_pubkey(cert, pkey)) {		fprintf(stderr, "Assign key fails\n%s\n",		    ERR_error_string(ERR_get_error(), NULL));		X509_free(cert);		rval = -1;		return (0);	}	/*	 * Add X509v3 extensions if present. These represent the minimum	 * set defined in RFC3280 less the certificate_policy extension,	 * which is seriously obfuscated in OpenSSL.	 */	/*	 * The basic_constraints extension CA:TRUE allows servers to	 * sign client certficitates.	 */	fprintf(stderr, "%s: %s\n", LN_basic_constraints,	    BASIC_CONSTRAINTS);	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,	    BASIC_CONSTRAINTS);	if (!X509_add_ext(cert, ex, -1)) {		fprintf(stderr, "Add extension field fails\n%s\n",		    ERR_error_string(ERR_get_error(), NULL));		rval = -1;		return (0);	}	X509_EXTENSION_free(ex);	/*	 * The key_usage extension designates the purposes the key can	 * be used for.	 */	fprintf(stderr, "%s: %s\n", LN_key_usage, KEY_USAGE);	ex = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, KEY_USAGE);	if (!X509_add_ext(cert, ex, -1)) {		fprintf(stderr, "Add extension field fails\n%s\n",		    ERR_error_string(ERR_get_error(), NULL));		rval = -1;		return (0);	}	X509_EXTENSION_free(ex);	/*	 * The subject_key_identifier is used for the GQ public key.	 * This should not be controversial.	 */	if (gqpub != NULL) {		fprintf(stderr, "%s\n", LN_subject_key_identifier);		ex = X509V3_EXT_conf_nid(NULL, NULL,		    NID_subject_key_identifier, gqpub);		if (!X509_add_ext(cert, ex, -1)) {			fprintf(stderr,			    "Add extension field fails\n%s\n",			    ERR_error_string(ERR_get_error(), NULL));			rval = -1;			return (0);		}		X509_EXTENSION_free(ex);	}	/*	 * The extended key usage extension is used for special purpose	 * here. The semantics probably do not conform to the designer's	 * intent and will likely change in future.	 * 	 * "trustRoot" designates a root authority	 * "private" designates a private certificate	 */	if (exten != NULL) {		fprintf(stderr, "%s: %s\n", LN_ext_key_usage, exten);		ex = X509V3_EXT_conf_nid(NULL, NULL,		    NID_ext_key_usage, exten);		if (!X509_add_ext(cert, ex, -1)) {			fprintf(stderr,			    "Add extension field fails\n%s\n",			    ERR_error_string(ERR_get_error(), NULL));			rval = -1;			return (0);		}		X509_EXTENSION_free(ex);	}	/*	 * Sign and verify.	 */	X509_sign(cert, pkey, md);	if (!X509_verify(cert, pkey)) {		fprintf(stderr, "Verify %s certificate fails\n%s\n", id,		    ERR_error_string(ERR_get_error(), NULL));		X509_free(cert);		rval = -1;		return (0);	}	/*	 * Write the certificate encoded in PEM.	 */	sprintf(pathbuf, "%scert", id);	str = fheader(pathbuf, hostname);	PEM_write_X509(str, cert);	fclose(str);	if (debug)		X509_print_fp(stdout, cert);	X509_free(cert);	fslink("cert", hostname);	return (1);}#if 0	/* asn2ntp is not used *//* * asn2ntp - convert ASN1_TIME time structure to NTP time */u_longasn2ntp	(	ASN1_TIME *asn1time	/* pointer to ASN1_TIME structure */	){	char	*v;		/* pointer to ASN1_TIME string */	struct	tm tm;		/* time decode structure time */	/*	 * Extract time string YYMMDDHHMMSSZ from ASN.1 time structure.	 * Note that the YY, MM, DD fields start with one, the HH, MM,	 * SS fiels start with zero and the Z character should be 'Z'	 * for UTC. Also note that years less than 50 map to years	 * greater than 100. Dontcha love ASN.1?	 */	if (asn1time->length > 13)		return (-1);	v = (char *)asn1time->data;	tm.tm_year = (v[0] - '0') * 10 + v[1] - '0';	if (tm.tm_year < 50)		tm.tm_year += 100;	tm.tm_mon = (v[2] - '0') * 10 + v[3] - '0' - 1;	tm.tm_mday = (v[4] - '0') * 10 + v[5] - '0';	tm.tm_hour = (v[6] - '0') * 10 + v[7] - '0';	tm.tm_min = (v[8] - '0') * 10 + v[9] - '0';	tm.tm_sec = (v[10] - '0') * 10 + v[11] - '0';	tm.tm_wday = 0;	tm.tm_yday = 0;	tm.tm_isdst = 0;	return (mktime(&tm) + JAN_1970);}#endif/* * Callback routine */voidcb	(	int	n1,		/* arg 1 */	int	n2,		/* arg 2 */	void	*chr		/* arg 3 */	){	switch (n1) {	case 0:		d0++;		fprintf(stderr, "%s %d %d %lu\r", (char *)chr, n1, n2,		    d0);		break;	case 1:		d1++;		fprintf(stderr, "%s\t\t%d %d %lu\r", (char *)chr, n1,		    n2, d1);		break;	case 2:		d2++;		fprintf(stderr, "%s\t\t\t\t%d %d %lu\r", (char *)chr,		    n1, n2, d2);		break;	case 3:		d3++;		fprintf(stderr, "%s\t\t\t\t\t\t%d %d %lu\r",		    (char *)chr, n1, n2, d3);		break;	}}/* * Generate key */EVP_PKEY *			/* public/private key pair */genkey(	char	*type,		/* key type (RSA or DSA) */	char	*id		/* file name id */	){	if (type == NULL)		return (NULL);	if (strcmp(type, "RSA") == 0)		return (gen_rsa(id));	else if (strcmp(type, "DSA") == 0)		return (gen_dsa(id));	fprintf(stderr, "Invalid %s key type %s\n", id, type);	rval = -1;	return (NULL);}#endif /* OPENSSL *//* * Generate file header */FILE *fheader	(	const char *id,		/* file name id */	const char *name	/* owner name */	){	FILE	*str;		/* file handle */	sprintf(filename, "ntpkey_%s_%s.%lu", id, name, epoch +	    JAN_1970);	if ((str = fopen(filename, "w")) == NULL) {		perror("Write");		exit (-1);	}	fprintf(str, "# %s\n# %s", filename, ctime(&epoch));	return (str);}/* * Generate symbolic links */voidfslink(	const char *id,		/* file name id */	const char *name	/* owner name */	){	char	linkname[MAXFILENAME]; /* link name */	int	temp;	sprintf(linkname, "ntpkey_%s_%s", id, name);	remove(linkname);	temp = symlink(filename, linkname);	if (temp < 0)		perror(id);	fprintf(stderr, "Generating new %s file and link\n", id);	fprintf(stderr, "%s->%s\n", linkname, filename);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -