Пример #1
0
/*
 * keytype_from_text	returns OpenSSL NID for digest by name, and
 *			optionally the associated digest length.
 *
 * Used by ntpd authreadkeys(), ntpq keytype()
 */
int
keytype_from_text(
	const char *text,
	size_t *pdigest_len
	)
{
	int		key_type;
	u_int		digest_len;
#ifdef HAVE_OPENSSL
	const u_long	max_digest_len = MAX_MAC_LEN - sizeof(keyid_t);
	uint8_t		digest[EVP_MAX_MD_SIZE];
	char *		upcased;
	char *		pch;
	EVP_MD_CTX	ctx;

	/*
	 * OpenSSL digest short names are capitalized, so uppercase the
	 * digest name before passing to OBJ_sn2nid().  If it is not
	 * recognized but begins with 'M' use NID_md5 to be consistent
	 * with past behavior.
	 */
	INIT_SSL();
	LIB_GETBUF(upcased);
	strlcpy(upcased, text, LIB_BUFLENGTH);
	for (pch = upcased; '\0' != *pch; pch++)
		*pch = (char)toupper((unsigned char)*pch);
	key_type = OBJ_sn2nid(upcased);
#else
	key_type = 0;
#endif

	if (!key_type && 'm' == tolower((unsigned char)text[0]))
		key_type = NID_md5;

	if (!key_type)
		return 0;

	if (NULL != pdigest_len) {
#ifdef HAVE_OPENSSL
		EVP_DigestInit(&ctx, EVP_get_digestbynid(key_type));
		EVP_DigestFinal(&ctx, digest, &digest_len);
		if (digest_len > max_digest_len) {
			fprintf(stderr,
				"key type %s %u octet digests are too big, max %lu\n",
				keytype_name(key_type), digest_len,
				max_digest_len);
			msyslog(LOG_ERR,
				"key type %s %u octet digests are too big, max %lu",
				keytype_name(key_type), digest_len,
				max_digest_len);
			return 0;
		}
#else
		digest_len = 16;
#endif
		*pdigest_len = digest_len;
	}

	return key_type;
}
Пример #2
0
void test_SHA1KeyName() {
#ifdef OPENSSL
	TEST_ASSERT_EQUAL_STRING("SHA", keytype_name(NID_sha));
#else
	TEST_IGNORE_MESSAGE("Skipping because OPENSSL isn't defined");
#endif	/* OPENSSL */
}
Пример #3
0
/*
 * keytype - get type of key to use for authenticating requests
 */
static void
keytype(
	struct parse *pcmd,
	FILE *fp
	)
{
	const char *	digest_name;
	size_t		digest_len;
	int		key_type;

	if (!pcmd->nargs) {
		fprintf(fp, "keytype is %s with %lu octet digests\n",
			keytype_name(info_auth_keytype),
			(u_long)info_auth_hashlen);
		return;
	}

	digest_name = pcmd->argval[0].string;
	digest_len = 0;
	key_type = keytype_from_text(digest_name, &digest_len);

	if (!key_type) {
		fprintf(fp, "keytype must be 'md5'%s\n",
#ifdef OPENSSL
			" or a digest type provided by OpenSSL");
#else
			"");
#endif
		return;
	}
Пример #4
0
/*
 * getpass_keytype() -- shared between ntpq and ntpdc, only vaguely
 *			related to the rest of ssl_init.c.
 */
char *
getpass_keytype(
	int	keytype
	)
{
	char	pass_prompt[64 + 11 + 1]; /* 11 for " Password: "******"%.64s Password: ", keytype_name(keytype));

	return getpass(pass_prompt);
}
Пример #5
0
TEST(ssl_init, SHA1KeyName) {
	TEST_ASSERT_EQUAL_STRING("SHA", keytype_name(NID_sha));
}
Пример #6
0
// keytype_name()
TEST(ssl_init, MD5KeyName) {
	TEST_ASSERT_EQUAL_STRING("MD5", keytype_name(KEY_TYPE_MD5));
}
Пример #7
0
// keytype_name()
void test_MD5KeyName() {
	TEST_ASSERT_EQUAL_STRING("MD5", keytype_name(KEY_TYPE_MD5));
}
Пример #8
0
TEST_F(ssl_initTest, SHA1KeyName) {
    EXPECT_STREQ("SHA", keytype_name(NID_sha));
}
Пример #9
0
// keytype_name()
TEST_F(ssl_initTest, MD5KeyName) {
    EXPECT_STREQ("MD5", keytype_name(KEY_TYPE_MD5));
}
Пример #10
0
/*
 * sendrequest - format and send a request packet
 *
 * Historically, ntpdc has used a fixed-size request packet regardless
 * of the actual payload size.  When authenticating, the timestamp, key
 * ID, and digest have been placed just before the end of the packet.
 * With the introduction in late 2009 of support for authenticated
 * ntpdc requests using larger 20-octet digests (vs. 16 for MD5), we
 * come up four bytes short.
 *
 * To maintain interop while allowing for larger digests, the behavior
 * is unchanged when using 16-octet digests.  For larger digests, the
 * timestamp, key ID, and digest are placed immediately following the
 * request payload, with the overall packet size variable.  ntpd can
 * distinguish 16-octet digests by the overall request size being
 * REQ_LEN_NOMAC + 4 + 16 with the auth bit enabled.  When using a
 * longer digest, that request size should be avoided.
 *
 * With the form used with 20-octet and larger digests, the timestamp,
 * key ID, and digest are located by ntpd relative to the start of the
 * packet, and the size of the digest is then implied by the packet
 * size.
 */
static int
sendrequest(
	int implcode,
	int reqcode,
	int auth,
	u_int qitems,
	size_t qsize,
	char *qdata
	)
{
	struct req_pkt qpkt;
	size_t	datasize;
	size_t	reqsize;
	u_long	key_id;
	l_fp	ts;
	l_fp *	ptstamp;
	int	maclen;
	char	pass_prompt[32];
	char *	pass;

	memset(&qpkt, 0, sizeof(qpkt));

	qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
	qpkt.implementation = (u_char)implcode;
	qpkt.request = (u_char)reqcode;

	datasize = qitems * qsize;
	if (datasize && qdata != NULL) {
		memcpy(qpkt.data, qdata, datasize);
		qpkt.err_nitems = ERR_NITEMS(0, qitems);
		qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);
	} else {
		qpkt.err_nitems = ERR_NITEMS(0, 0);
		qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);  /* allow for optional first item */
	}

	if (!auth || (keyid_entered && info_auth_keyid == 0)) {
		qpkt.auth_seq = AUTH_SEQ(0, 0);
		return sendpkt(&qpkt, req_pkt_size);
	}

	if (info_auth_keyid == 0) {
		key_id = getkeyid("Keyid: ");
		if (!key_id) {
			fprintf(stderr, "Invalid key identifier\n");
			return 1;
		}
		info_auth_keyid = key_id;
	}
	if (!authistrusted(info_auth_keyid)) {
		snprintf(pass_prompt, sizeof(pass_prompt),
			 "%s Password: "******"Invalid password\n");
			return 1;
		}
		authusekey(info_auth_keyid, info_auth_keytype,
			   (u_char *)pass);
		authtrust(info_auth_keyid, 1);
	}
	qpkt.auth_seq = AUTH_SEQ(1, 0);
	if (info_auth_hashlen > 16) {
		/*
		 * Only ntpd which expects REQ_LEN_NOMAC plus maclen
		 * octets in an authenticated request using a 16 octet
		 * digest (that is, a newer ntpd) will handle digests
		 * larger than 16 octets, so for longer digests, do
		 * not attempt to shorten the requests for downlevel
		 * ntpd compatibility.
		 */
		if (REQ_LEN_NOMAC != req_pkt_size)
			return 1;
		reqsize = REQ_LEN_HDR + datasize + sizeof(*ptstamp);
		/* align to 32 bits */
		reqsize = (reqsize + 3) & ~3;
	} else
		reqsize = req_pkt_size;
	ptstamp = (void *)((char *)&qpkt + reqsize);
	ptstamp--;
	get_systime(&ts);
	L_ADD(&ts, &delay_time);
	HTONL_FP(&ts, ptstamp);
	maclen = authencrypt(info_auth_keyid, (void *)&qpkt, reqsize);
	if (!maclen) {  
		fprintf(stderr, "Key not found\n");
		return 1;
	} else if (maclen != (info_auth_hashlen + sizeof(keyid_t))) {
		fprintf(stderr,
			"%d octet MAC, %u expected with %u octet digest\n",
			maclen, (info_auth_hashlen + sizeof(keyid_t)),
			info_auth_hashlen);
		return 1;
	}
	return sendpkt(&qpkt, reqsize + maclen);
}