summaryrefslogtreecommitdiff
path: root/sys/include/authsrv.h
blob: 5c0b368e77a4a5782af79057f8f07c8654074734 (plain)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#pragma	src	"/sys/src/libauthsrv"
#pragma	lib	"libauthsrv.a"

/*
 * Interface for talking to authentication server.
 */
typedef struct	Ticket		Ticket;
typedef struct	Ticketreq	Ticketreq;
typedef struct	Authenticator	Authenticator;
typedef struct	Nvrsafe		Nvrsafe;
typedef struct	Passwordreq	Passwordreq;
typedef struct	OChapreply	OChapreply;
typedef struct	OMSchapreply	OMSchapreply;

typedef struct	Authkey		Authkey;

enum
{
	ANAMELEN=	28,	/* name max size in previous proto */
	AERRLEN=	64,	/* errstr max size in previous proto */
	DOMLEN=		48,	/* authentication domain name length */
	DESKEYLEN=	7,	/* encrypt/decrypt des key length */
	AESKEYLEN=	16,	/* encrypt/decrypt aes key length */

	CHALLEN=	8,	/* plan9 sk1 challenge length */
	NETCHLEN=	16,	/* max network challenge length (used in AS protocol) */
	CONFIGLEN=	14,
	SECRETLEN=	32,	/* secret max size */
	PASSWDLEN=	28,	/* password max size */

	NONCELEN=	32,

	KEYDBOFF=	8,	/* bytes of random data at key file's start */
	OKEYDBLEN=	ANAMELEN+DESKEYLEN+4+2,	/* old key file entry length */
	KEYDBLEN=	OKEYDBLEN+SECRETLEN,	/* key file entry length */
	OMD5LEN=	16,

	/* AuthPAK constants */
	PAKKEYLEN=	32,
	PAKSLEN=	(448+7)/8,	/* ed448 scalar */
	PAKPLEN=	4*PAKSLEN,	/* point in extended format X,Y,Z,T */
	PAKHASHLEN=	2*PAKPLEN,	/* hashed points PM,PN */
	PAKXLEN=	PAKSLEN,	/* random scalar secret key */ 
	PAKYLEN=	PAKSLEN,	/* decaf encoded public key */
};

/* encryption numberings (anti-replay) */
enum
{
	AuthTreq=1,	/* ticket request */
	AuthChal=2,	/* challenge box request */
	AuthPass=3,	/* change password */
	AuthOK=4,	/* fixed length reply follows */
	AuthErr=5,	/* error follows */
	AuthMod=6,	/* modify user */
	AuthApop=7,	/* apop authentication for pop3 */
	AuthOKvar=9,	/* variable length reply follows */
	AuthChap=10,	/* chap authentication for ppp */
	AuthMSchap=11,	/* MS chap authentication for ppp */
	AuthCram=12,	/* CRAM verification for IMAP (RFC2195 & rfc2104) */
	AuthHttp=13,	/* http domain login */
	AuthVNC=14,	/* VNC server login (deprecated) */
	AuthPAK=19,	/* authenticated diffie hellman key agreement */
	AuthMSchapv2=21,/* MS chap v2 authentication for ppp */
	AuthTs=64,	/* ticket encrypted with server's key */
	AuthTc,		/* ticket encrypted with client's key */
	AuthAs,		/* server generated authenticator */
	AuthAc,		/* client generated authenticator */
	AuthTp,		/* ticket encrypted with client's key for password change */
	AuthHr,		/* http reply */
};

struct Ticketreq
{
	char	type;
	char	authid[ANAMELEN];	/* server's encryption id */
	char	authdom[DOMLEN];	/* server's authentication domain */
	char	chal[CHALLEN];		/* challenge from server */
	char	hostid[ANAMELEN];	/* host's encryption id */
	char	uid[ANAMELEN];		/* uid of requesting user on host */
};
#define	TICKREQLEN	(3*ANAMELEN+CHALLEN+DOMLEN+1)

struct Ticket
{
	char	num;			/* replay protection */
	char	chal[CHALLEN];		/* server challenge */
	char	cuid[ANAMELEN];		/* uid on client */
	char	suid[ANAMELEN];		/* uid on server */
	uchar	key[NONCELEN];		/* nonce key */

	char	form;			/* (not transmitted) format (0 = des, 1 = ccpoly) */
};
#define	MAXTICKETLEN	(12+CHALLEN+2*ANAMELEN+NONCELEN+16)

struct Authenticator
{
	char	num;			/* replay protection */
	char	chal[CHALLEN];		/* server/client challenge */
	uchar	rand[NONCELEN];		/* server/client nonce */
};
#define	MAXAUTHENTLEN	(12+CHALLEN+NONCELEN+16)

struct Passwordreq
{
	char	num;
	char	old[PASSWDLEN];
	char	new[PASSWDLEN];
	char	changesecret;
	char	secret[SECRETLEN];	/* new secret */
};
#define	MAXPASSREQLEN	(12+2*PASSWDLEN+1+SECRETLEN+16)

struct	OChapreply
{
	uchar	id;
	char	uid[ANAMELEN];
	char	resp[OMD5LEN];
};
#define OCHAPREPLYLEN	(1+ANAMELEN+OMD5LEN)

struct	OMSchapreply
{
	char	uid[ANAMELEN];
	char	LMresp[24];		/* Lan Manager response */
	char	NTresp[24];		/* NT response */
};
#define OMSCHAPREPLYLEN	(ANAMELEN+24+24)

struct	Authkey
{
	char	des[DESKEYLEN];		/* DES key from password */
	uchar	aes[AESKEYLEN];		/* AES key from password */
	uchar	pakkey[PAKKEYLEN];	/* shared key from AuthPAK exchange (see authpak_finish()) */
	uchar	pakhash[PAKHASHLEN];	/* secret hash from AES key and user name (see authpak_hash()) */
};

/*
 *  convert to/from wire format
 */
extern	int	convT2M(Ticket*, char*, int, Authkey*);
extern	int	convM2T(char*, int, Ticket*, Authkey*);
extern	int	convA2M(Authenticator*, char*, int, Ticket*);
extern	int	convM2A(char*, int, Authenticator*, Ticket*);
extern	int	convTR2M(Ticketreq*, char*, int);
extern	int	convM2TR(char*, int, Ticketreq*);
extern	int	convPR2M(Passwordreq*, char*, int, Ticket*);
extern	int	convM2PR(char*, int, Passwordreq*, Ticket*);

/*
 *  convert ascii password to auth key
 */
extern	void	passtokey(Authkey*, char*);

extern	void	passtodeskey(char key[DESKEYLEN], char *p);
extern	void	passtoaeskey(uchar key[AESKEYLEN], char *p);

/*
 *  Nvram interface
 */
enum {
	NVread		= 0,	/* just read */
	NVwrite		= 1<<0,	/* always prompt and rewrite nvram */
	NVwriteonerr	= 1<<1,	/* prompt and rewrite nvram when corrupt */
	NVwritemem	= 1<<2,	/* don't prompt, write nvram from argument */
};

/* storage layout */
struct Nvrsafe
{
	char	machkey[DESKEYLEN];	/* file server's authid's des key */
	uchar	machsum;
	char	authkey[DESKEYLEN];	/* authid's des key from password */
	uchar	authsum;
	/*
	 * file server config string of device holding full configuration;
	 * secstore key on non-file-servers.
	 */
	char	config[CONFIGLEN];
	uchar	configsum;
	char	authid[ANAMELEN];	/* auth userid, e.g., bootes */
	uchar	authidsum;
	char	authdom[DOMLEN];	/* auth domain, e.g., cs.bell-labs.com */
	uchar	authdomsum;

	uchar	aesmachkey[AESKEYLEN];
	uchar	aesmachsum;
};

extern	uchar	nvcsum(void*, int);
extern	int	readnvram(Nvrsafe*, int);
extern	char*	readcons(char*, char*, int);

/*
 *  call up auth server
 */
extern	int	authdial(char *netroot, char *authdom);

/*
 *  exchange messages with auth server
 */
extern	int	_asgetpakkey(int, Ticketreq*, Authkey*);
extern	int	_asgetticket(int, Ticketreq*, char*, int);
extern	int	_asrequest(int, Ticketreq*);
extern	int	_asgetresp(int, Ticket*, Authenticator*, Authkey *);
extern	int	_asrdresp(int, char*, int);

/*
 *  AuthPAK protocol
 */
typedef struct PAKpriv PAKpriv;
struct PAKpriv
{
	int	isclient;
	uchar	x[PAKXLEN];
	uchar	y[PAKYLEN];
};

extern	void	authpak_hash(Authkey *k, char *u);
extern	void	authpak_new(PAKpriv *p, Authkey *k, uchar y[PAKYLEN], int isclient);
extern	int	authpak_finish(PAKpriv *p, Authkey *k, uchar y[PAKYLEN]);