Exemple #1
0
TEST(ssl_init, SHA1KeyTypeWithDigestLength) {
	size_t digestLength;
	size_t expected = TEST_SHA1_DIGEST_LENGTH;

	TEST_ASSERT_EQUAL(NID_sha, keytype_from_text("SHA", &digestLength));
	TEST_ASSERT_EQUAL(expected, digestLength);
}
Exemple #2
0
void
test_VerifySHA1(void)
{
#ifdef OPENSSL

	const char* PKT_DATA =
	    "sometestdata"				/* Data */
	    "\0\0\0\0"					/* Key-ID (unused) */
	    "\xad\x07\xde\x36\x39\xa6\x77\xfa\x5b\xce"	/* MAC */
	    "\x2d\x8a\x7d\x06\x96\xe6\x0c\xbc\xed\xe1";
	const int PKT_LEN = 12;

	struct key sha1;
	sha1.next = NULL;
	sha1.key_id = 0;
	sha1.key_len = 7;
	memcpy(&sha1.key_seq, "sha1key", sha1.key_len);
	strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));	
	sha1.typei = keytype_from_text(sha1.typen, NULL);

	TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, SHA1_LENGTH, &sha1));
	
#else
	
	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
	
#endif	/* OPENSSL */
}
Exemple #3
0
TEST(ssl_init, MD5KeyTypeWithDigestLength) {
	size_t digestLength;
	size_t expected = TEST_MD5_DIGEST_LENGTH;

	TEST_ASSERT_EQUAL(KEY_TYPE_MD5, keytype_from_text("MD5", &digestLength));
	TEST_ASSERT_EQUAL(expected, digestLength);
}
Exemple #4
0
TEST_F(ssl_initTest, MD5KeyTypeWithDigestLength) {
    size_t digestLength;
    size_t expected = TEST_MD5_DIGEST_LENGTH;

    EXPECT_EQ(KEY_TYPE_MD5, keytype_from_text("MD5", &digestLength));
    EXPECT_EQ(expected, digestLength);
}
Exemple #5
0
TEST_F(ssl_initTest, SHA1KeyTypeWithDigestLength) {
    size_t digestLength;
    size_t expected = TEST_SHA1_DIGEST_LENGTH;

    EXPECT_EQ(NID_sha, keytype_from_text("SHA", &digestLength));
    EXPECT_EQ(expected, digestLength);
}
Exemple #6
0
void
test_MakeSHA1Mac(void)
{
#ifdef OPENSSL

	const char* PKT_DATA = "abcdefgh0123";
	const int PKT_LEN = strlen(PKT_DATA);
	const char* EXPECTED_DIGEST =
		"\x17\xaa\x82\x97\xc7\x17\x13\x6a\x9b\xa9"
		"\x63\x85\xb4\xce\xbe\x94\xa0\x97\x16\x1d";
	char actual[SHA1_LENGTH];

	struct key sha1;
	sha1.next = NULL;
	sha1.key_id = 20;
	sha1.key_len = 7;
	memcpy(&sha1.key_seq, "sha1seq", sha1.key_len);
	strlcpy(sha1.typen, "SHA1", sizeof(sha1.typen));
	sha1.typei = keytype_from_text(sha1.typen, NULL);

	TEST_ASSERT_EQUAL(SHA1_LENGTH,
			  make_mac(PKT_DATA, PKT_LEN, SHA1_LENGTH, &sha1, actual));

	TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, SHA1_LENGTH);
	
#else
	
	TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
	
#endif	/* OPENSSL */
}
Exemple #7
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;
	}
Exemple #8
0
void test_SHA1KeyTypeWithDigestLength() {
#ifdef OPENSSL
	size_t digestLength;
	size_t expected = TEST_SHA1_DIGEST_LENGTH;

	TEST_ASSERT_EQUAL(NID_sha, keytype_from_text("SHA", &digestLength));
	TEST_ASSERT_EQUAL(expected, digestLength);
	/* OPENSSL */
#else 
	TEST_IGNORE_MESSAGE("Skipping because OPENSSL isn't defined");
#endif
}
Exemple #9
0
void
test_PacketSizeNotMultipleOfFourBytes(void)
{
	const char* PKT_DATA = "123456";
	const int PKT_LEN = 6;
	char actual[MD5_LENGTH];

	struct key md5;
	md5.next = NULL;
	md5.key_id = 10;
	md5.key_len = 6;
	memcpy(&md5.key_seq, "md5seq", md5.key_len);
	strlcpy(md5.typen, "MD5", sizeof(md5.typen));
	md5.typei = keytype_from_text(md5.typen, NULL);

	TEST_ASSERT_EQUAL(0, make_mac(PKT_DATA, PKT_LEN, MD5_LENGTH, &md5, actual));
}
Exemple #10
0
void
test_VerifyCorrectMD5(void)
{
	const char* PKT_DATA =
	    "sometestdata"			/* Data */
	    "\0\0\0\0"				/* Key-ID (unused) */
	    "\xc7\x58\x99\xdd\x99\x32\x0f\x71"	/* MAC */
	    "\x2b\x7b\xfe\x4f\xa2\x32\xcf\xac";
	const int PKT_LEN = 12;

	struct key md5;
	md5.next = NULL;
	md5.key_id = 0;
	md5.key_len = 6;
	memcpy(&md5.key_seq, "md5key", md5.key_len);
	strlcpy(md5.typen, "MD5", sizeof(md5.typen));
	md5.typei = keytype_from_text(md5.typen, NULL);

	TEST_ASSERT_TRUE(auth_md5(PKT_DATA, PKT_LEN, MD5_LENGTH, &md5));
}
void
test_GenerateAuthenticatedPacket(void)
{
	static const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_MD5_LEN;
	
	struct key	testkey;
	struct pkt	testpkt;
	struct timeval	xmt;
	l_fp		expected_xmt, actual_xmt;
	char 		expected_mac[MAX_MD5_LEN];
	
	testkey.next = NULL;
	testkey.key_id = 30;
	testkey.key_len = 9;
	memcpy(testkey.key_seq, "123456789", testkey.key_len);
	strlcpy(testkey.typen, "MD5", sizeof(testkey.typen));
	testkey.typei = keytype_from_text(testkey.typen, NULL);

	GETTIMEOFDAY(&xmt, NULL);
	xmt.tv_sec += JAN_1970;

	TEST_ASSERT_EQUAL(EXPECTED_PKTLEN,
			  generate_pkt(&testpkt, &xmt, testkey.key_id, &testkey));

	TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
	TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
	TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));

	TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
	TEST_ASSERT_EQUAL(8, testpkt.ppoll);

	TVTOTS(&xmt, &expected_xmt);
	NTOHL_FP(&testpkt.xmt, &actual_xmt);
	TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));

	TEST_ASSERT_EQUAL(testkey.key_id, ntohl(testpkt.exten[0]));
	
	TEST_ASSERT_EQUAL(MAX_MD5_LEN - 4, /* Remove the key_id, only keep the mac. */
			  make_mac(&testpkt, LEN_PKT_NOMAC, MAX_MD5_LEN-4, &testkey, expected_mac));
	TEST_ASSERT_EQUAL_MEMORY(expected_mac, (char*)&testpkt.exten[1], MAX_MD5_LEN -4);
}
Exemple #12
0
void
test_MakeMd5Mac(void)
{
	const char* PKT_DATA = "abcdefgh0123";
	const int PKT_LEN = strlen(PKT_DATA);
	const char* EXPECTED_DIGEST =
		"\x52\x6c\xb8\x38\xaf\x06\x5a\xfb\x6c\x98\xbb\xc0\x9b\x0a\x7a\x1b";
	char actual[MD5_LENGTH];

	struct key md5;
	md5.next = NULL;
	md5.key_id = 10;
	md5.key_len = 6;
	memcpy(&md5.key_seq, "md5seq", md5.key_len);
	strlcpy(md5.typen, "MD5", sizeof(md5.typen));
	md5.typei = keytype_from_text(md5.typen, NULL);
	
	TEST_ASSERT_EQUAL(MD5_LENGTH,
			  make_mac(PKT_DATA, PKT_LEN, MD5_LENGTH, &md5, actual));

	TEST_ASSERT_TRUE(memcmp(EXPECTED_DIGEST, actual, MD5_LENGTH) == 0);
}
Exemple #13
0
void
test_VerifyFailure(void)
{
	/* We use a copy of the MD5 verification code, but modify the
	 * last bit to make sure verification fails.
	 */
	const char* PKT_DATA =
	    "sometestdata"			/* Data */
	    "\0\0\0\0"				/* Key-ID (unused) */
	    "\xc7\x58\x99\xdd\x99\x32\x0f\x71"	/* MAC */
	    "\x2b\x7b\xfe\x4f\xa2\x32\xcf\x00"; /* Last byte is wrong! */
	const int PKT_LEN = 12;

	struct key md5;
	md5.next = NULL;
	md5.key_id = 0;
	md5.key_len = 6;
	memcpy(&md5.key_seq, "md5key", md5.key_len);
	strlcpy(md5.typen, "MD5", sizeof(md5.typen));
	md5.typei = keytype_from_text(md5.typen, NULL);

	TEST_ASSERT_FALSE(auth_md5(PKT_DATA, PKT_LEN, MD5_LENGTH, &md5));
}
Exemple #14
0
// keytype_from_text()
TEST(ssl_init, MD5KeyTypeWithoutDigestLength) {
	TEST_ASSERT_EQUAL(KEY_TYPE_MD5, keytype_from_text("MD5", NULL));
}
Exemple #15
0
/*
 * authreadkeys - (re)read keys from a file.
 */
int
authreadkeys(
	const char *file
	)
{
	FILE	*fp;
	char	*line;
	char	*token;
	keyid_t	keyno;
	int	keytype;
	char	buf[512];		/* lots of room for line */
	u_char	keystr[20];
	size_t	len;
	size_t	j;

	/*
	 * Open file.  Complain and return if it can't be opened.
	 */
	fp = fopen(file, "r");
	if (fp == NULL) {
		msyslog(LOG_ERR, "authreadkeys: file %s: %m",
		    file);
		return (0);
	}
	INIT_SSL();

	/*
	 * Remove all existing keys
	 */
	auth_delkeys();

	/*
	 * Now read lines from the file, looking for key entries
	 */
	while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
		token = nexttok(&line);
		if (token == NULL)
			continue;
		
		/*
		 * First is key number.  See if it is okay.
		 */
		keyno = atoi(token);
		if (keyno == 0) {
			msyslog(LOG_ERR,
			    "authreadkeys: cannot change key %s", token);
			continue;
		}

		if (keyno > NTP_MAXKEY) {
			msyslog(LOG_ERR,
			    "authreadkeys: key %s > %d reserved for Autokey",
			    token, NTP_MAXKEY);
			continue;
		}

		/*
		 * Next is keytype. See if that is all right.
		 */
		token = nexttok(&line);
		if (token == NULL) {
			msyslog(LOG_ERR,
			    "authreadkeys: no key type for key %d", keyno);
			continue;
		}
#ifdef OPENSSL
		/*
		 * The key type is the NID used by the message digest 
		 * algorithm. There are a number of inconsistencies in
		 * the OpenSSL database. We attempt to discover them
		 * here and prevent use of inconsistent data later.
		 */
		keytype = keytype_from_text(token, NULL);
		if (keytype == 0) {
			msyslog(LOG_ERR,
			    "authreadkeys: invalid type for key %d", keyno);
			continue;
		}
		if (EVP_get_digestbynid(keytype) == NULL) {
			msyslog(LOG_ERR,
			    "authreadkeys: no algorithm for key %d", keyno);
			continue;
		}
#else	/* !OPENSSL follows */

		/*
		 * The key type is unused, but is required to be 'M' or
		 * 'm' for compatibility.
		 */
		if (!(*token == 'M' || *token == 'm')) {
			msyslog(LOG_ERR,
			    "authreadkeys: invalid type for key %d", keyno);
			continue;
		}
		keytype = KEY_TYPE_MD5;
#endif	/* !OPENSSL */

		/*
		 * Finally, get key and insert it. If it is longer than 20
		 * characters, it is a binary string encoded in hex;
		 * otherwise, it is a text string of printable ASCII
		 * characters.
		 */
		token = nexttok(&line);
		if (token == NULL) {
			msyslog(LOG_ERR,
			    "authreadkeys: no key for key %d", keyno);
			continue;
		}
		len = strlen(token);
		if (len <= sizeof(keystr)) {
			MD5auth_setkey(keyno, keytype, (u_char *)token, len);
		} else {
			char	hex[] = "0123456789abcdef";
			u_char	temp;
			char	*ptr;
			size_t	jlim;

			jlim = min(len, 2 * sizeof(keystr));
			for (j = 0; j < jlim; j++) {
				ptr = strchr(hex, tolower((unsigned char)token[j]));
				if (ptr == NULL)
					break;	/* abort decoding */
				temp = (u_char)(ptr - hex);
				if (j & 1)
					keystr[j / 2] |= temp;
				else
					keystr[j / 2] = temp << 4;
			}
			if (j < jlim) {
				msyslog(LOG_ERR,
					"authreadkeys: invalid hex digit for key %d", keyno);
				continue;
			}
			MD5auth_setkey(keyno, keytype, keystr, jlim / 2);
		}
	}
	fclose(fp);
	return (1);
}
Exemple #16
0
// keytype_from_text()
TEST_F(ssl_initTest, MD5KeyTypeWithoutDigestLength) {
    ASSERT_EQ(KEY_TYPE_MD5, keytype_from_text("MD5", NULL));
}
Exemple #17
0
/*
 * authreadkeys - (re)read keys from a file.
 */
int
authreadkeys(
	const char *file
	)
{
	FILE	*fp;
	char	*line;
	char	*token;
	keyid_t	keyno;
	int	keytype;
	char	buf[512];		/* lots of room for line */
	u_char	keystr[32];		/* Bug 2537 */
	size_t	len;
	size_t	j;
	u_int   nerr;
	KeyDataT *list = NULL;
	KeyDataT *next = NULL;
	/*
	 * Open file.  Complain and return if it can't be opened.
	 */
	fp = fopen(file, "r");
	if (fp == NULL) {
		msyslog(LOG_ERR, "authreadkeys: file '%s': %m",
		    file);
		goto onerror;
	}
	INIT_SSL();

	/*
	 * Now read lines from the file, looking for key entries. Put
	 * the data into temporary store for later propagation to avoid
	 * two-pass processing.
	 */
	nerr = 0;
	while ((line = fgets(buf, sizeof buf, fp)) != NULL) {
		if (nerr > nerr_maxlimit)
			break;
		token = nexttok(&line);
		if (token == NULL)
			continue;
		
		/*
		 * First is key number.  See if it is okay.
		 */
		keyno = atoi(token);
		if (keyno == 0) {
			log_maybe(&nerr,
				  "authreadkeys: cannot change key %s",
				  token);
			continue;
		}

		if (keyno > NTP_MAXKEY) {
			log_maybe(&nerr,
				  "authreadkeys: key %s > %d reserved for Autokey",
				  token, NTP_MAXKEY);
			continue;
		}

		/*
		 * Next is keytype. See if that is all right.
		 */
		token = nexttok(&line);
		if (token == NULL) {
			log_maybe(&nerr,
				  "authreadkeys: no key type for key %d",
				  keyno);
			continue;
		}
#ifdef OPENSSL
		/*
		 * The key type is the NID used by the message digest 
		 * algorithm. There are a number of inconsistencies in
		 * the OpenSSL database. We attempt to discover them
		 * here and prevent use of inconsistent data later.
		 */
		keytype = keytype_from_text(token, NULL);
		if (keytype == 0) {
			log_maybe(&nerr,
				  "authreadkeys: invalid type for key %d",
				  keyno);
			continue;
		}
		if (EVP_get_digestbynid(keytype) == NULL) {
			log_maybe(&nerr,
				  "authreadkeys: no algorithm for key %d",
				  keyno);
			continue;
		}
#else	/* !OPENSSL follows */

		/*
		 * The key type is unused, but is required to be 'M' or
		 * 'm' for compatibility.
		 */
		if (!(*token == 'M' || *token == 'm')) {
			log_maybe(&nerr,
				  "authreadkeys: invalid type for key %d",
				  keyno);
			continue;
		}
		keytype = KEY_TYPE_MD5;
#endif	/* !OPENSSL */

		/*
		 * Finally, get key and insert it. If it is longer than 20
		 * characters, it is a binary string encoded in hex;
		 * otherwise, it is a text string of printable ASCII
		 * characters.
		 */
		token = nexttok(&line);
		if (token == NULL) {
			log_maybe(&nerr,
				  "authreadkeys: no key for key %d", keyno);
			continue;
		}
		next = NULL;
		len = strlen(token);
		if (len <= 20) {	/* Bug 2537 */
			next = emalloc(sizeof(KeyDataT) + len);
			next->keyacclist = NULL;
			next->keyid   = keyno;
			next->keytype = keytype;
			next->seclen  = len;
			memcpy(next->secbuf, token, len);
		} else {
			static const char hex[] = "0123456789abcdef";
			u_char	temp;
			char	*ptr;
			size_t	jlim;

			jlim = min(len, 2 * sizeof(keystr));
			for (j = 0; j < jlim; j++) {
				ptr = strchr(hex, tolower((unsigned char)token[j]));
				if (ptr == NULL)
					break;	/* abort decoding */
				temp = (u_char)(ptr - hex);
				if (j & 1)
					keystr[j / 2] |= temp;
				else
					keystr[j / 2] = temp << 4;
			}
			if (j < jlim) {
				log_maybe(&nerr,
					  "authreadkeys: invalid hex digit for key %d",
					  keyno);
				continue;
			}
			len = jlim/2; /* hmmmm.... what about odd length?!? */
			next = emalloc(sizeof(KeyDataT) + len);
			next->keyacclist = NULL;
			next->keyid   = keyno;
			next->keytype = keytype;
			next->seclen  = len;
			memcpy(next->secbuf, keystr, len);
		}

		token = nexttok(&line);
DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL"));
		if (token != NULL) {	/* A comma-separated IP access list */
			char *tp = token;

			while (tp) {
				char *i;
				KeyAccT ka;

				i = strchr(tp, (int)',');
				if (i)
					*i = '\0';
DPRINTF(0, ("authreadkeys: access list:  <%s>\n", tp));

				if (is_ip_address(tp, AF_UNSPEC, &ka.addr)) {
					KeyAccT *kap;

					kap = emalloc(sizeof(KeyAccT));
					memcpy(kap, &ka, sizeof ka);
					kap->next = next->keyacclist;
					next->keyacclist = kap;
				} else {
					log_maybe(&nerr,
						  "authreadkeys: invalid IP address <%s> for key %d",
						  tp, keyno);
				}

				if (i) {
					tp = i + 1;
				} else {
					tp = 0;
				}
			}
		}

		INSIST(NULL != next);
		next->next = list;
		list = next;
	}
	fclose(fp);
	if (nerr > nerr_maxlimit) {
		msyslog(LOG_ERR,
			"authreadkeys: rejecting file '%s' after %u errors (emergency break)",
			file, nerr);
		goto onerror;
	}
	if (nerr > 0) {
		msyslog(LOG_ERR,
			"authreadkeys: rejecting file '%s' after %u error(s)",
			file, nerr);
		goto onerror;
	}

	/* first remove old file-based keys */
	auth_delkeys();
	/* insert the new key material */
	while (NULL != (next = list)) {
		list = next->next;
		MD5auth_setkey(next->keyid, next->keytype,
			       next->secbuf, next->seclen, next->keyacclist);
		/* purge secrets from memory before free()ing it */
		memset(next, 0, sizeof(*next) + next->seclen);
		free(next);
	}
	return (1);

  onerror:
	/* Mop up temporary storage before bailing out. */
	while (NULL != (next = list)) {
		list = next->next;

		while (next->keyacclist) {
			KeyAccT *kap = next->keyacclist;

			next->keyacclist = kap->next;
			free(kap);
		}

		/* purge secrets from memory before free()ing it */
		memset(next, 0, sizeof(*next) + next->seclen);
		free(next);
	}
	return (0);
}
Exemple #18
0
// keytype_from_text()
void test_MD5KeyTypeWithoutDigestLength() {
	TEST_ASSERT_EQUAL(KEY_TYPE_MD5, keytype_from_text("MD5", NULL));
}