aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/xntpd/lib/authusekey.c
blob: c268c4d2455c87cadf7ad656632031bf9cb6493e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* authusekey.c,v 3.1 1993/07/06 01:07:58 jbj Exp
 * authusekey - decode a key from ascii and use it
 */
#include <stdio.h>
#include <ctype.h>

#include "ntp_types.h"
#include "ntp_string.h"
#include "ntp_stdlib.h"

/*
 * Types of ascii representations for keys.  "Standard" means a 64 bit
 * hex number in NBS format, i.e. with the low order bit of each byte
 * a parity bit.  "NTP" means a 64 bit key in NTP format, with the
 * high order bit of each byte a parity bit.  "Ascii" means a 1-to-8
 * character string whose ascii representation is used as the key.
 */
#ifdef	DES
#define	KEY_TYPE_STD	1
#define	KEY_TYPE_NTP	2
#define	KEY_TYPE_ASCII	3

#define	STD_PARITY_BITS	0x01010101

#endif

#ifdef	MD5
#define	KEY_TYPE_MD5	4
#endif

int
authusekey(keyno, keytype, str)
	U_LONG keyno;
	int keytype;
	const char *str;
{
	U_LONG key[2];
	u_char keybytes[8];
	const char *cp;
	char *xdigit;
	int len;
	int i;
	static char *hex = "0123456789abcdef";

	cp = str;
	len = strlen(cp);
	if (len == 0)
		return 0;

	switch(keytype) {
#ifdef	DES
	case KEY_TYPE_STD:
	case KEY_TYPE_NTP:
		if (len != 16)		/* Lazy.  Should define constant */
			return 0;
		/*
		 * Decode hex key.
		 */
		key[0] = 0;
		key[1] = 0;
		for (i = 0; i < 16; i++) {
			if (!isascii(*cp))
				return 0;
			xdigit = strchr(hex, isupper(*cp) ? tolower(*cp) : *cp);
			cp++;
			if (xdigit == 0)
				return 0;
			key[i>>3] <<= 4;
			key[i>>3] |= (U_LONG)(xdigit - hex) & 0xf;
		}

		/*
		 * If this is an NTP format key, put it into NBS format
		 */
		if (keytype == KEY_TYPE_NTP) {
			for (i = 0; i < 2; i++)
				key[i] = ((key[i] << 1) & ~STD_PARITY_BITS)
				    | ((key[i] >> 7) & STD_PARITY_BITS);
		}

		/*
		 * Check the parity, reject the key if the check fails
		 */
		if (!DESauth_parity(key)) {
			return 0;
		}
		
		/*
		 * We can't find a good reason not to use this key.
		 * So use it.
		 */
		DESauth_setkey(keyno, key);
		break;
	
	case KEY_TYPE_ASCII:
		/*
		 * Make up key from ascii representation
		 */
		memset((char *) keybytes, 0, sizeof(keybytes));
		for (i = 0; i < 8 && i < len; i++)
			keybytes[i] = *cp++ << 1;
		key[0] = (U_LONG)keybytes[0] << 24 | (U_LONG)keybytes[1] << 16
		    | (U_LONG)keybytes[2] << 8 | (U_LONG)keybytes[3];
		key[1] = (U_LONG)keybytes[4] << 24 | (U_LONG)keybytes[5] << 16
		    | (U_LONG)keybytes[6] << 8 | (U_LONG)keybytes[7];
		
		/*
		 * Set parity on key
		 */
		(void)DESauth_parity(key);

		/*
		 * Now set key in.
		 */
		DESauth_setkey(keyno, key);
		break;
#endif

#ifdef	MD5
	case KEY_TYPE_MD5:
	/* XXX FIXME: MD5auth_setkey() casts arg2 back to (char *) */
		MD5auth_setkey(keyno, (U_LONG *)str);
		break;
#endif

	default:
		/* Oh, well */
		return 0;
	}

	return 1;
}