Blame


1 0fc65b37 2004-03-21 devnull #include <u.h>
2 0fc65b37 2004-03-21 devnull #include <libc.h>
3 0fc65b37 2004-03-21 devnull #include <bio.h>
4 0fc65b37 2004-03-21 devnull #include <auth.h>
5 0fc65b37 2004-03-21 devnull #include <mp.h>
6 0fc65b37 2004-03-21 devnull #include <libsec.h>
7 0fc65b37 2004-03-21 devnull
8 0fc65b37 2004-03-21 devnull // The main groups of functions are:
9 0fc65b37 2004-03-21 devnull // client/server - main handshake protocol definition
10 0fc65b37 2004-03-21 devnull // message functions - formating handshake messages
11 0fc65b37 2004-03-21 devnull // cipher choices - catalog of digest and encrypt algorithms
12 0fc65b37 2004-03-21 devnull // security functions - PKCS#1, sslHMAC, session keygen
13 0fc65b37 2004-03-21 devnull // general utility functions - malloc, serialization
14 0fc65b37 2004-03-21 devnull // The handshake protocol builds on the TLS/SSL3 record layer protocol,
15 0fc65b37 2004-03-21 devnull // which is implemented in kernel device #a. See also /lib/rfc/rfc2246.
16 0fc65b37 2004-03-21 devnull
17 0fc65b37 2004-03-21 devnull enum {
18 0fc65b37 2004-03-21 devnull TLSFinishedLen = 12,
19 0fc65b37 2004-03-21 devnull SSL3FinishedLen = MD5dlen+SHA1dlen,
20 0fc65b37 2004-03-21 devnull MaxKeyData = 104, // amount of secret we may need
21 0fc65b37 2004-03-21 devnull MaxChunk = 1<<14,
22 0fc65b37 2004-03-21 devnull RandomSize = 32,
23 0fc65b37 2004-03-21 devnull SidSize = 32,
24 0fc65b37 2004-03-21 devnull MasterSecretSize = 48,
25 0fc65b37 2004-03-21 devnull AQueue = 0,
26 0fc65b37 2004-03-21 devnull AFlush = 1,
27 0fc65b37 2004-03-21 devnull };
28 0fc65b37 2004-03-21 devnull
29 0fc65b37 2004-03-21 devnull typedef struct TlsSec TlsSec;
30 0fc65b37 2004-03-21 devnull
31 0fc65b37 2004-03-21 devnull typedef struct Bytes{
32 0fc65b37 2004-03-21 devnull int len;
33 0fc65b37 2004-03-21 devnull uchar data[1]; // [len]
34 0fc65b37 2004-03-21 devnull } Bytes;
35 0fc65b37 2004-03-21 devnull
36 0fc65b37 2004-03-21 devnull typedef struct Ints{
37 0fc65b37 2004-03-21 devnull int len;
38 0fc65b37 2004-03-21 devnull int data[1]; // [len]
39 0fc65b37 2004-03-21 devnull } Ints;
40 0fc65b37 2004-03-21 devnull
41 0fc65b37 2004-03-21 devnull typedef struct Algs{
42 0fc65b37 2004-03-21 devnull char *enc;
43 0fc65b37 2004-03-21 devnull char *digest;
44 0fc65b37 2004-03-21 devnull int nsecret;
45 0fc65b37 2004-03-21 devnull int tlsid;
46 0fc65b37 2004-03-21 devnull int ok;
47 0fc65b37 2004-03-21 devnull } Algs;
48 0fc65b37 2004-03-21 devnull
49 0fc65b37 2004-03-21 devnull typedef struct Finished{
50 0fc65b37 2004-03-21 devnull uchar verify[SSL3FinishedLen];
51 0fc65b37 2004-03-21 devnull int n;
52 0fc65b37 2004-03-21 devnull } Finished;
53 0fc65b37 2004-03-21 devnull
54 0fc65b37 2004-03-21 devnull typedef struct TlsConnection{
55 0fc65b37 2004-03-21 devnull TlsSec *sec; // security management goo
56 0fc65b37 2004-03-21 devnull int hand, ctl; // record layer file descriptors
57 0fc65b37 2004-03-21 devnull int erred; // set when tlsError called
58 0fc65b37 2004-03-21 devnull int (*trace)(char*fmt, ...); // for debugging
59 0fc65b37 2004-03-21 devnull int version; // protocol we are speaking
60 0fc65b37 2004-03-21 devnull int verset; // version has been set
61 0fc65b37 2004-03-21 devnull int ver2hi; // server got a version 2 hello
62 0fc65b37 2004-03-21 devnull int isClient; // is this the client or server?
63 0fc65b37 2004-03-21 devnull Bytes *sid; // SessionID
64 0fc65b37 2004-03-21 devnull Bytes *cert; // only last - no chain
65 0fc65b37 2004-03-21 devnull
66 0fc65b37 2004-03-21 devnull Lock statelk;
67 0fc65b37 2004-03-21 devnull int state; // must be set using setstate
68 0fc65b37 2004-03-21 devnull
69 0fc65b37 2004-03-21 devnull // input buffer for handshake messages
70 0fc65b37 2004-03-21 devnull uchar buf[MaxChunk+2048];
71 0fc65b37 2004-03-21 devnull uchar *rp, *ep;
72 0fc65b37 2004-03-21 devnull
73 0fc65b37 2004-03-21 devnull uchar crandom[RandomSize]; // client random
74 0fc65b37 2004-03-21 devnull uchar srandom[RandomSize]; // server random
75 0fc65b37 2004-03-21 devnull int clientVersion; // version in ClientHello
76 0fc65b37 2004-03-21 devnull char *digest; // name of digest algorithm to use
77 0fc65b37 2004-03-21 devnull char *enc; // name of encryption algorithm to use
78 0fc65b37 2004-03-21 devnull int nsecret; // amount of secret data to init keys
79 0fc65b37 2004-03-21 devnull
80 0fc65b37 2004-03-21 devnull // for finished messages
81 0fc65b37 2004-03-21 devnull MD5state hsmd5; // handshake hash
82 0fc65b37 2004-03-21 devnull SHAstate hssha1; // handshake hash
83 0fc65b37 2004-03-21 devnull Finished finished;
84 0fc65b37 2004-03-21 devnull } TlsConnection;
85 0fc65b37 2004-03-21 devnull
86 0fc65b37 2004-03-21 devnull typedef struct Msg{
87 0fc65b37 2004-03-21 devnull int tag;
88 0fc65b37 2004-03-21 devnull union {
89 0fc65b37 2004-03-21 devnull struct {
90 0fc65b37 2004-03-21 devnull int version;
91 0fc65b37 2004-03-21 devnull uchar random[RandomSize];
92 0fc65b37 2004-03-21 devnull Bytes* sid;
93 0fc65b37 2004-03-21 devnull Ints* ciphers;
94 0fc65b37 2004-03-21 devnull Bytes* compressors;
95 0fc65b37 2004-03-21 devnull } clientHello;
96 0fc65b37 2004-03-21 devnull struct {
97 0fc65b37 2004-03-21 devnull int version;
98 0fc65b37 2004-03-21 devnull uchar random[RandomSize];
99 0fc65b37 2004-03-21 devnull Bytes* sid;
100 0fc65b37 2004-03-21 devnull int cipher;
101 0fc65b37 2004-03-21 devnull int compressor;
102 0fc65b37 2004-03-21 devnull } serverHello;
103 0fc65b37 2004-03-21 devnull struct {
104 0fc65b37 2004-03-21 devnull int ncert;
105 0fc65b37 2004-03-21 devnull Bytes **certs;
106 0fc65b37 2004-03-21 devnull } certificate;
107 0fc65b37 2004-03-21 devnull struct {
108 0fc65b37 2004-03-21 devnull Bytes *types;
109 0fc65b37 2004-03-21 devnull int nca;
110 0fc65b37 2004-03-21 devnull Bytes **cas;
111 0fc65b37 2004-03-21 devnull } certificateRequest;
112 0fc65b37 2004-03-21 devnull struct {
113 0fc65b37 2004-03-21 devnull Bytes *key;
114 0fc65b37 2004-03-21 devnull } clientKeyExchange;
115 0fc65b37 2004-03-21 devnull Finished finished;
116 0fc65b37 2004-03-21 devnull } u;
117 0fc65b37 2004-03-21 devnull } Msg;
118 0fc65b37 2004-03-21 devnull
119 0fc65b37 2004-03-21 devnull struct TlsSec{
120 0fc65b37 2004-03-21 devnull char *server; // name of remote; nil for server
121 0fc65b37 2004-03-21 devnull int ok; // <0 killed; ==0 in progress; >0 reusable
122 0fc65b37 2004-03-21 devnull RSApub *rsapub;
123 0fc65b37 2004-03-21 devnull AuthRpc *rpc; // factotum for rsa private key
124 0fc65b37 2004-03-21 devnull uchar sec[MasterSecretSize]; // master secret
125 0fc65b37 2004-03-21 devnull uchar crandom[RandomSize]; // client random
126 0fc65b37 2004-03-21 devnull uchar srandom[RandomSize]; // server random
127 0fc65b37 2004-03-21 devnull int clientVers; // version in ClientHello
128 0fc65b37 2004-03-21 devnull int vers; // final version
129 0fc65b37 2004-03-21 devnull // byte generation and handshake checksum
130 0fc65b37 2004-03-21 devnull void (*prf)(uchar*, int, uchar*, int, char*, uchar*, int, uchar*, int);
131 0fc65b37 2004-03-21 devnull void (*setFinished)(TlsSec*, MD5state, SHAstate, uchar*, int);
132 0fc65b37 2004-03-21 devnull int nfin;
133 0fc65b37 2004-03-21 devnull };
134 0fc65b37 2004-03-21 devnull
135 0fc65b37 2004-03-21 devnull
136 0fc65b37 2004-03-21 devnull enum {
137 0fc65b37 2004-03-21 devnull TLSVersion = 0x0301,
138 0fc65b37 2004-03-21 devnull SSL3Version = 0x0300,
139 0fc65b37 2004-03-21 devnull ProtocolVersion = 0x0301, // maximum version we speak
140 0fc65b37 2004-03-21 devnull MinProtoVersion = 0x0300, // limits on version we accept
141 0fc65b37 2004-03-21 devnull MaxProtoVersion = 0x03ff,
142 0fc65b37 2004-03-21 devnull };
143 0fc65b37 2004-03-21 devnull
144 0fc65b37 2004-03-21 devnull // handshake type
145 0fc65b37 2004-03-21 devnull enum {
146 0fc65b37 2004-03-21 devnull HHelloRequest,
147 0fc65b37 2004-03-21 devnull HClientHello,
148 0fc65b37 2004-03-21 devnull HServerHello,
149 0fc65b37 2004-03-21 devnull HSSL2ClientHello = 9, /* local convention; see devtls.c */
150 0fc65b37 2004-03-21 devnull HCertificate = 11,
151 0fc65b37 2004-03-21 devnull HServerKeyExchange,
152 0fc65b37 2004-03-21 devnull HCertificateRequest,
153 0fc65b37 2004-03-21 devnull HServerHelloDone,
154 0fc65b37 2004-03-21 devnull HCertificateVerify,
155 0fc65b37 2004-03-21 devnull HClientKeyExchange,
156 0fc65b37 2004-03-21 devnull HFinished = 20,
157 0fc65b37 2004-03-21 devnull HMax
158 0fc65b37 2004-03-21 devnull };
159 0fc65b37 2004-03-21 devnull
160 0fc65b37 2004-03-21 devnull // alerts
161 0fc65b37 2004-03-21 devnull enum {
162 0fc65b37 2004-03-21 devnull ECloseNotify = 0,
163 0fc65b37 2004-03-21 devnull EUnexpectedMessage = 10,
164 0fc65b37 2004-03-21 devnull EBadRecordMac = 20,
165 0fc65b37 2004-03-21 devnull EDecryptionFailed = 21,
166 0fc65b37 2004-03-21 devnull ERecordOverflow = 22,
167 0fc65b37 2004-03-21 devnull EDecompressionFailure = 30,
168 0fc65b37 2004-03-21 devnull EHandshakeFailure = 40,
169 0fc65b37 2004-03-21 devnull ENoCertificate = 41,
170 0fc65b37 2004-03-21 devnull EBadCertificate = 42,
171 0fc65b37 2004-03-21 devnull EUnsupportedCertificate = 43,
172 0fc65b37 2004-03-21 devnull ECertificateRevoked = 44,
173 0fc65b37 2004-03-21 devnull ECertificateExpired = 45,
174 0fc65b37 2004-03-21 devnull ECertificateUnknown = 46,
175 0fc65b37 2004-03-21 devnull EIllegalParameter = 47,
176 0fc65b37 2004-03-21 devnull EUnknownCa = 48,
177 0fc65b37 2004-03-21 devnull EAccessDenied = 49,
178 0fc65b37 2004-03-21 devnull EDecodeError = 50,
179 0fc65b37 2004-03-21 devnull EDecryptError = 51,
180 0fc65b37 2004-03-21 devnull EExportRestriction = 60,
181 0fc65b37 2004-03-21 devnull EProtocolVersion = 70,
182 0fc65b37 2004-03-21 devnull EInsufficientSecurity = 71,
183 0fc65b37 2004-03-21 devnull EInternalError = 80,
184 0fc65b37 2004-03-21 devnull EUserCanceled = 90,
185 0fc65b37 2004-03-21 devnull ENoRenegotiation = 100,
186 0fc65b37 2004-03-21 devnull EMax = 256
187 0fc65b37 2004-03-21 devnull };
188 0fc65b37 2004-03-21 devnull
189 0fc65b37 2004-03-21 devnull // cipher suites
190 0fc65b37 2004-03-21 devnull enum {
191 0fc65b37 2004-03-21 devnull TLS_NULL_WITH_NULL_NULL = 0x0000,
192 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_NULL_MD5 = 0x0001,
193 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_NULL_SHA = 0x0002,
194 0fc65b37 2004-03-21 devnull TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003,
195 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_RC4_128_MD5 = 0x0004,
196 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_RC4_128_SHA = 0x0005,
197 0fc65b37 2004-03-21 devnull TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0X0006,
198 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_IDEA_CBC_SHA = 0X0007,
199 0fc65b37 2004-03-21 devnull TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X0008,
200 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_DES_CBC_SHA = 0X0009,
201 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0X000A,
202 0fc65b37 2004-03-21 devnull TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0X000B,
203 0fc65b37 2004-03-21 devnull TLS_DH_DSS_WITH_DES_CBC_SHA = 0X000C,
204 0fc65b37 2004-03-21 devnull TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0X000D,
205 0fc65b37 2004-03-21 devnull TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X000E,
206 0fc65b37 2004-03-21 devnull TLS_DH_RSA_WITH_DES_CBC_SHA = 0X000F,
207 0fc65b37 2004-03-21 devnull TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0X0010,
208 0fc65b37 2004-03-21 devnull TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0X0011,
209 0fc65b37 2004-03-21 devnull TLS_DHE_DSS_WITH_DES_CBC_SHA = 0X0012,
210 0fc65b37 2004-03-21 devnull TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0X0013, // ZZZ must be implemented for tls1.0 compliance
211 0fc65b37 2004-03-21 devnull TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0X0014,
212 0fc65b37 2004-03-21 devnull TLS_DHE_RSA_WITH_DES_CBC_SHA = 0X0015,
213 0fc65b37 2004-03-21 devnull TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0X0016,
214 0fc65b37 2004-03-21 devnull TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = 0x0017,
215 0fc65b37 2004-03-21 devnull TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018,
216 0fc65b37 2004-03-21 devnull TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = 0X0019,
217 0fc65b37 2004-03-21 devnull TLS_DH_anon_WITH_DES_CBC_SHA = 0X001A,
218 0fc65b37 2004-03-21 devnull TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0X001B,
219 0fc65b37 2004-03-21 devnull
220 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_AES_128_CBC_SHA = 0X002f, // aes, aka rijndael with 128 bit blocks
221 0fc65b37 2004-03-21 devnull TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0X0030,
222 0fc65b37 2004-03-21 devnull TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0X0031,
223 0fc65b37 2004-03-21 devnull TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0X0032,
224 0fc65b37 2004-03-21 devnull TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0X0033,
225 0fc65b37 2004-03-21 devnull TLS_DH_anon_WITH_AES_128_CBC_SHA = 0X0034,
226 0fc65b37 2004-03-21 devnull TLS_RSA_WITH_AES_256_CBC_SHA = 0X0035,
227 0fc65b37 2004-03-21 devnull TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0X0036,
228 0fc65b37 2004-03-21 devnull TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0X0037,
229 0fc65b37 2004-03-21 devnull TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0X0038,
230 0fc65b37 2004-03-21 devnull TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0X0039,
231 0fc65b37 2004-03-21 devnull TLS_DH_anon_WITH_AES_256_CBC_SHA = 0X003A,
232 0fc65b37 2004-03-21 devnull CipherMax
233 0fc65b37 2004-03-21 devnull };
234 0fc65b37 2004-03-21 devnull
235 0fc65b37 2004-03-21 devnull // compression methods
236 0fc65b37 2004-03-21 devnull enum {
237 0fc65b37 2004-03-21 devnull CompressionNull = 0,
238 0fc65b37 2004-03-21 devnull CompressionMax
239 0fc65b37 2004-03-21 devnull };
240 0fc65b37 2004-03-21 devnull
241 0fc65b37 2004-03-21 devnull static Algs cipherAlgs[] = {
242 0fc65b37 2004-03-21 devnull {"rc4_128", "md5", 2 * (16 + MD5dlen), TLS_RSA_WITH_RC4_128_MD5},
243 0fc65b37 2004-03-21 devnull {"rc4_128", "sha1", 2 * (16 + SHA1dlen), TLS_RSA_WITH_RC4_128_SHA},
244 0fc65b37 2004-03-21 devnull {"3des_ede_cbc","sha1",2*(4*8+SHA1dlen), TLS_RSA_WITH_3DES_EDE_CBC_SHA},
245 0fc65b37 2004-03-21 devnull };
246 0fc65b37 2004-03-21 devnull
247 0fc65b37 2004-03-21 devnull static uchar compressors[] = {
248 0fc65b37 2004-03-21 devnull CompressionNull,
249 0fc65b37 2004-03-21 devnull };
250 0fc65b37 2004-03-21 devnull
251 0fc65b37 2004-03-21 devnull static TlsConnection *tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...));
252 0fc65b37 2004-03-21 devnull static TlsConnection *tlsClient2(int ctl, int hand, uchar *csid, int ncsid, int (*trace)(char*fmt, ...));
253 0fc65b37 2004-03-21 devnull
254 0fc65b37 2004-03-21 devnull static void msgClear(Msg *m);
255 0fc65b37 2004-03-21 devnull static char* msgPrint(char *buf, int n, Msg *m);
256 0fc65b37 2004-03-21 devnull static int msgRecv(TlsConnection *c, Msg *m);
257 0fc65b37 2004-03-21 devnull static int msgSend(TlsConnection *c, Msg *m, int act);
258 0fc65b37 2004-03-21 devnull static void tlsError(TlsConnection *c, int err, char *msg, ...);
259 0fc65b37 2004-03-21 devnull /* #pragma varargck argpos tlsError 3*/
260 0fc65b37 2004-03-21 devnull static int setVersion(TlsConnection *c, int version);
261 0fc65b37 2004-03-21 devnull static int finishedMatch(TlsConnection *c, Finished *f);
262 0fc65b37 2004-03-21 devnull static void tlsConnectionFree(TlsConnection *c);
263 0fc65b37 2004-03-21 devnull
264 0fc65b37 2004-03-21 devnull static int setAlgs(TlsConnection *c, int a);
265 0fc65b37 2004-03-21 devnull static int okCipher(Ints *cv);
266 0fc65b37 2004-03-21 devnull static int okCompression(Bytes *cv);
267 0fc65b37 2004-03-21 devnull static int initCiphers(void);
268 0fc65b37 2004-03-21 devnull static Ints* makeciphers(void);
269 0fc65b37 2004-03-21 devnull
270 0fc65b37 2004-03-21 devnull static TlsSec* tlsSecInits(int cvers, uchar *csid, int ncsid, uchar *crandom, uchar *ssid, int *nssid, uchar *srandom);
271 0fc65b37 2004-03-21 devnull static int tlsSecSecrets(TlsSec *sec, int vers, uchar *epm, int nepm, uchar *kd, int nkd);
272 0fc65b37 2004-03-21 devnull static TlsSec* tlsSecInitc(int cvers, uchar *crandom);
273 0fc65b37 2004-03-21 devnull static int tlsSecSecretc(TlsSec *sec, uchar *sid, int nsid, uchar *srandom, uchar *cert, int ncert, int vers, uchar **epm, int *nepm, uchar *kd, int nkd);
274 0fc65b37 2004-03-21 devnull static int tlsSecFinished(TlsSec *sec, MD5state md5, SHAstate sha1, uchar *fin, int nfin, int isclient);
275 0fc65b37 2004-03-21 devnull static void tlsSecOk(TlsSec *sec);
276 0fc65b37 2004-03-21 devnull static void tlsSecKill(TlsSec *sec);
277 0fc65b37 2004-03-21 devnull static void tlsSecClose(TlsSec *sec);
278 0fc65b37 2004-03-21 devnull static void setMasterSecret(TlsSec *sec, Bytes *pm);
279 0fc65b37 2004-03-21 devnull static void serverMasterSecret(TlsSec *sec, uchar *epm, int nepm);
280 0fc65b37 2004-03-21 devnull static void setSecrets(TlsSec *sec, uchar *kd, int nkd);
281 0fc65b37 2004-03-21 devnull static int clientMasterSecret(TlsSec *sec, RSApub *pub, uchar **epm, int *nepm);
282 0fc65b37 2004-03-21 devnull static Bytes *pkcs1_encrypt(Bytes* data, RSApub* key, int blocktype);
283 0fc65b37 2004-03-21 devnull static Bytes *pkcs1_decrypt(TlsSec *sec, uchar *epm, int nepm);
284 0fc65b37 2004-03-21 devnull static void tlsSetFinished(TlsSec *sec, MD5state hsmd5, SHAstate hssha1, uchar *finished, int isClient);
285 0fc65b37 2004-03-21 devnull static void sslSetFinished(TlsSec *sec, MD5state hsmd5, SHAstate hssha1, uchar *finished, int isClient);
286 0fc65b37 2004-03-21 devnull static void sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label,
287 0fc65b37 2004-03-21 devnull uchar *seed0, int nseed0, uchar *seed1, int nseed1);
288 0fc65b37 2004-03-21 devnull static int setVers(TlsSec *sec, int version);
289 0fc65b37 2004-03-21 devnull
290 0fc65b37 2004-03-21 devnull static AuthRpc* factotum_rsa_open(uchar *cert, int certlen);
291 0fc65b37 2004-03-21 devnull static mpint* factotum_rsa_decrypt(AuthRpc *rpc, mpint *cipher);
292 0fc65b37 2004-03-21 devnull static void factotum_rsa_close(AuthRpc*rpc);
293 0fc65b37 2004-03-21 devnull
294 0fc65b37 2004-03-21 devnull static void* emalloc(int);
295 0fc65b37 2004-03-21 devnull static void* erealloc(void*, int);
296 0fc65b37 2004-03-21 devnull static void put32(uchar *p, u32int);
297 0fc65b37 2004-03-21 devnull static void put24(uchar *p, int);
298 0fc65b37 2004-03-21 devnull static void put16(uchar *p, int);
299 0fc65b37 2004-03-21 devnull static u32int get32(uchar *p);
300 0fc65b37 2004-03-21 devnull static int get24(uchar *p);
301 0fc65b37 2004-03-21 devnull static int get16(uchar *p);
302 0fc65b37 2004-03-21 devnull static Bytes* newbytes(int len);
303 0fc65b37 2004-03-21 devnull static Bytes* makebytes(uchar* buf, int len);
304 0fc65b37 2004-03-21 devnull static void freebytes(Bytes* b);
305 0fc65b37 2004-03-21 devnull static Ints* newints(int len);
306 0fc65b37 2004-03-21 devnull static Ints* makeints(int* buf, int len);
307 0fc65b37 2004-03-21 devnull static void freeints(Ints* b);
308 0fc65b37 2004-03-21 devnull
309 0fc65b37 2004-03-21 devnull //================= client/server ========================
310 0fc65b37 2004-03-21 devnull
311 0fc65b37 2004-03-21 devnull // push TLS onto fd, returning new (application) file descriptor
312 0fc65b37 2004-03-21 devnull // or -1 if error.
313 0fc65b37 2004-03-21 devnull int
314 0fc65b37 2004-03-21 devnull tlsServer(int fd, TLSconn *conn)
315 0fc65b37 2004-03-21 devnull {
316 0fc65b37 2004-03-21 devnull char buf[8];
317 0fc65b37 2004-03-21 devnull char dname[64];
318 0fc65b37 2004-03-21 devnull int n, data, ctl, hand;
319 0fc65b37 2004-03-21 devnull TlsConnection *tls;
320 0fc65b37 2004-03-21 devnull
321 0fc65b37 2004-03-21 devnull if(conn == nil)
322 0fc65b37 2004-03-21 devnull return -1;
323 0fc65b37 2004-03-21 devnull ctl = open("#a/tls/clone", ORDWR);
324 0fc65b37 2004-03-21 devnull if(ctl < 0)
325 0fc65b37 2004-03-21 devnull return -1;
326 0fc65b37 2004-03-21 devnull n = read(ctl, buf, sizeof(buf)-1);
327 0fc65b37 2004-03-21 devnull if(n < 0){
328 0fc65b37 2004-03-21 devnull close(ctl);
329 0fc65b37 2004-03-21 devnull return -1;
330 0fc65b37 2004-03-21 devnull }
331 0fc65b37 2004-03-21 devnull buf[n] = 0;
332 0fc65b37 2004-03-21 devnull sprint(conn->dir, "#a/tls/%s", buf);
333 0fc65b37 2004-03-21 devnull sprint(dname, "#a/tls/%s/hand", buf);
334 0fc65b37 2004-03-21 devnull hand = open(dname, ORDWR);
335 0fc65b37 2004-03-21 devnull if(hand < 0){
336 0fc65b37 2004-03-21 devnull close(ctl);
337 0fc65b37 2004-03-21 devnull return -1;
338 0fc65b37 2004-03-21 devnull }
339 0fc65b37 2004-03-21 devnull fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
340 0fc65b37 2004-03-21 devnull tls = tlsServer2(ctl, hand, conn->cert, conn->certlen, conn->trace);
341 0fc65b37 2004-03-21 devnull sprint(dname, "#a/tls/%s/data", buf);
342 0fc65b37 2004-03-21 devnull data = open(dname, ORDWR);
343 0fc65b37 2004-03-21 devnull close(fd);
344 0fc65b37 2004-03-21 devnull close(hand);
345 0fc65b37 2004-03-21 devnull close(ctl);
346 0fc65b37 2004-03-21 devnull if(data < 0){
347 0fc65b37 2004-03-21 devnull return -1;
348 0fc65b37 2004-03-21 devnull }
349 0fc65b37 2004-03-21 devnull if(tls == nil){
350 0fc65b37 2004-03-21 devnull close(data);
351 0fc65b37 2004-03-21 devnull return -1;
352 0fc65b37 2004-03-21 devnull }
353 0fc65b37 2004-03-21 devnull if(conn->cert)
354 0fc65b37 2004-03-21 devnull free(conn->cert);
355 0fc65b37 2004-03-21 devnull conn->cert = 0; // client certificates are not yet implemented
356 0fc65b37 2004-03-21 devnull conn->certlen = 0;
357 0fc65b37 2004-03-21 devnull conn->sessionIDlen = tls->sid->len;
358 0fc65b37 2004-03-21 devnull conn->sessionID = emalloc(conn->sessionIDlen);
359 0fc65b37 2004-03-21 devnull memcpy(conn->sessionID, tls->sid->data, conn->sessionIDlen);
360 0fc65b37 2004-03-21 devnull tlsConnectionFree(tls);
361 0fc65b37 2004-03-21 devnull return data;
362 0fc65b37 2004-03-21 devnull }
363 0fc65b37 2004-03-21 devnull
364 0fc65b37 2004-03-21 devnull // push TLS onto fd, returning new (application) file descriptor
365 0fc65b37 2004-03-21 devnull // or -1 if error.
366 0fc65b37 2004-03-21 devnull int
367 0fc65b37 2004-03-21 devnull tlsClient(int fd, TLSconn *conn)
368 0fc65b37 2004-03-21 devnull {
369 0fc65b37 2004-03-21 devnull char buf[8];
370 0fc65b37 2004-03-21 devnull char dname[64];
371 0fc65b37 2004-03-21 devnull int n, data, ctl, hand;
372 0fc65b37 2004-03-21 devnull TlsConnection *tls;
373 0fc65b37 2004-03-21 devnull
374 0fc65b37 2004-03-21 devnull if(!conn)
375 0fc65b37 2004-03-21 devnull return -1;
376 0fc65b37 2004-03-21 devnull ctl = open("#a/tls/clone", ORDWR);
377 0fc65b37 2004-03-21 devnull if(ctl < 0)
378 0fc65b37 2004-03-21 devnull return -1;
379 0fc65b37 2004-03-21 devnull n = read(ctl, buf, sizeof(buf)-1);
380 0fc65b37 2004-03-21 devnull if(n < 0){
381 0fc65b37 2004-03-21 devnull close(ctl);
382 0fc65b37 2004-03-21 devnull return -1;
383 0fc65b37 2004-03-21 devnull }
384 0fc65b37 2004-03-21 devnull buf[n] = 0;
385 0fc65b37 2004-03-21 devnull sprint(conn->dir, "#a/tls/%s", buf);
386 0fc65b37 2004-03-21 devnull sprint(dname, "#a/tls/%s/hand", buf);
387 0fc65b37 2004-03-21 devnull hand = open(dname, ORDWR);
388 0fc65b37 2004-03-21 devnull if(hand < 0){
389 0fc65b37 2004-03-21 devnull close(ctl);
390 0fc65b37 2004-03-21 devnull return -1;
391 0fc65b37 2004-03-21 devnull }
392 0fc65b37 2004-03-21 devnull sprint(dname, "#a/tls/%s/data", buf);
393 0fc65b37 2004-03-21 devnull data = open(dname, ORDWR);
394 0fc65b37 2004-03-21 devnull if(data < 0)
395 0fc65b37 2004-03-21 devnull return -1;
396 0fc65b37 2004-03-21 devnull fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
397 0fc65b37 2004-03-21 devnull tls = tlsClient2(ctl, hand, conn->sessionID, conn->sessionIDlen, conn->trace);
398 0fc65b37 2004-03-21 devnull close(fd);
399 0fc65b37 2004-03-21 devnull close(hand);
400 0fc65b37 2004-03-21 devnull close(ctl);
401 0fc65b37 2004-03-21 devnull if(tls == nil){
402 0fc65b37 2004-03-21 devnull close(data);
403 0fc65b37 2004-03-21 devnull return -1;
404 0fc65b37 2004-03-21 devnull }
405 0fc65b37 2004-03-21 devnull conn->certlen = tls->cert->len;
406 0fc65b37 2004-03-21 devnull conn->cert = emalloc(conn->certlen);
407 0fc65b37 2004-03-21 devnull memcpy(conn->cert, tls->cert->data, conn->certlen);
408 0fc65b37 2004-03-21 devnull conn->sessionIDlen = tls->sid->len;
409 0fc65b37 2004-03-21 devnull conn->sessionID = emalloc(conn->sessionIDlen);
410 0fc65b37 2004-03-21 devnull memcpy(conn->sessionID, tls->sid->data, conn->sessionIDlen);
411 0fc65b37 2004-03-21 devnull tlsConnectionFree(tls);
412 0fc65b37 2004-03-21 devnull return data;
413 0fc65b37 2004-03-21 devnull }
414 0fc65b37 2004-03-21 devnull
415 0fc65b37 2004-03-21 devnull static TlsConnection *
416 0fc65b37 2004-03-21 devnull tlsServer2(int ctl, int hand, uchar *cert, int ncert, int (*trace)(char*fmt, ...))
417 0fc65b37 2004-03-21 devnull {
418 0fc65b37 2004-03-21 devnull TlsConnection *c;
419 0fc65b37 2004-03-21 devnull Msg m;
420 0fc65b37 2004-03-21 devnull Bytes *csid;
421 0fc65b37 2004-03-21 devnull uchar sid[SidSize], kd[MaxKeyData];
422 0fc65b37 2004-03-21 devnull char *secrets;
423 0fc65b37 2004-03-21 devnull int cipher, compressor, nsid, rv;
424 0fc65b37 2004-03-21 devnull
425 0fc65b37 2004-03-21 devnull if(trace)
426 0fc65b37 2004-03-21 devnull trace("tlsServer2\n");
427 0fc65b37 2004-03-21 devnull if(!initCiphers())
428 0fc65b37 2004-03-21 devnull return nil;
429 0fc65b37 2004-03-21 devnull c = emalloc(sizeof(TlsConnection));
430 0fc65b37 2004-03-21 devnull c->ctl = ctl;
431 0fc65b37 2004-03-21 devnull c->hand = hand;
432 0fc65b37 2004-03-21 devnull c->trace = trace;
433 0fc65b37 2004-03-21 devnull c->version = ProtocolVersion;
434 0fc65b37 2004-03-21 devnull
435 0fc65b37 2004-03-21 devnull memset(&m, 0, sizeof(m));
436 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m)){
437 0fc65b37 2004-03-21 devnull if(trace)
438 0fc65b37 2004-03-21 devnull trace("initial msgRecv failed\n");
439 0fc65b37 2004-03-21 devnull goto Err;
440 0fc65b37 2004-03-21 devnull }
441 0fc65b37 2004-03-21 devnull if(m.tag != HClientHello) {
442 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a client hello");
443 0fc65b37 2004-03-21 devnull goto Err;
444 0fc65b37 2004-03-21 devnull }
445 0fc65b37 2004-03-21 devnull c->clientVersion = m.u.clientHello.version;
446 0fc65b37 2004-03-21 devnull if(trace)
447 0fc65b37 2004-03-21 devnull trace("ClientHello version %x\n", c->clientVersion);
448 0fc65b37 2004-03-21 devnull if(setVersion(c, m.u.clientHello.version) < 0) {
449 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "incompatible version");
450 0fc65b37 2004-03-21 devnull goto Err;
451 0fc65b37 2004-03-21 devnull }
452 0fc65b37 2004-03-21 devnull
453 0fc65b37 2004-03-21 devnull memmove(c->crandom, m.u.clientHello.random, RandomSize);
454 0fc65b37 2004-03-21 devnull cipher = okCipher(m.u.clientHello.ciphers);
455 0fc65b37 2004-03-21 devnull if(cipher < 0) {
456 0fc65b37 2004-03-21 devnull // reply with EInsufficientSecurity if we know that's the case
457 0fc65b37 2004-03-21 devnull if(cipher == -2)
458 0fc65b37 2004-03-21 devnull tlsError(c, EInsufficientSecurity, "cipher suites too weak");
459 0fc65b37 2004-03-21 devnull else
460 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "no matching cipher suite");
461 0fc65b37 2004-03-21 devnull goto Err;
462 0fc65b37 2004-03-21 devnull }
463 0fc65b37 2004-03-21 devnull if(!setAlgs(c, cipher)){
464 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "no matching cipher suite");
465 0fc65b37 2004-03-21 devnull goto Err;
466 0fc65b37 2004-03-21 devnull }
467 0fc65b37 2004-03-21 devnull compressor = okCompression(m.u.clientHello.compressors);
468 0fc65b37 2004-03-21 devnull if(compressor < 0) {
469 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "no matching compressor");
470 0fc65b37 2004-03-21 devnull goto Err;
471 0fc65b37 2004-03-21 devnull }
472 0fc65b37 2004-03-21 devnull
473 0fc65b37 2004-03-21 devnull csid = m.u.clientHello.sid;
474 0fc65b37 2004-03-21 devnull if(trace)
475 0fc65b37 2004-03-21 devnull trace(" cipher %d, compressor %d, csidlen %d\n", cipher, compressor, csid->len);
476 0fc65b37 2004-03-21 devnull c->sec = tlsSecInits(c->clientVersion, csid->data, csid->len, c->crandom, sid, &nsid, c->srandom);
477 0fc65b37 2004-03-21 devnull if(c->sec == nil){
478 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "can't initialize security: %r");
479 0fc65b37 2004-03-21 devnull goto Err;
480 0fc65b37 2004-03-21 devnull }
481 0fc65b37 2004-03-21 devnull c->sec->rpc = factotum_rsa_open(cert, ncert);
482 0fc65b37 2004-03-21 devnull if(c->sec->rpc == nil){
483 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "factotum_rsa_open: %r");
484 0fc65b37 2004-03-21 devnull goto Err;
485 0fc65b37 2004-03-21 devnull }
486 0fc65b37 2004-03-21 devnull c->sec->rsapub = X509toRSApub(cert, ncert, nil, 0);
487 0fc65b37 2004-03-21 devnull msgClear(&m);
488 0fc65b37 2004-03-21 devnull
489 0fc65b37 2004-03-21 devnull m.tag = HServerHello;
490 0fc65b37 2004-03-21 devnull m.u.serverHello.version = c->version;
491 0fc65b37 2004-03-21 devnull memmove(m.u.serverHello.random, c->srandom, RandomSize);
492 0fc65b37 2004-03-21 devnull m.u.serverHello.cipher = cipher;
493 0fc65b37 2004-03-21 devnull m.u.serverHello.compressor = compressor;
494 0fc65b37 2004-03-21 devnull c->sid = makebytes(sid, nsid);
495 0fc65b37 2004-03-21 devnull m.u.serverHello.sid = makebytes(c->sid->data, c->sid->len);
496 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AQueue))
497 0fc65b37 2004-03-21 devnull goto Err;
498 0fc65b37 2004-03-21 devnull msgClear(&m);
499 0fc65b37 2004-03-21 devnull
500 0fc65b37 2004-03-21 devnull m.tag = HCertificate;
501 0fc65b37 2004-03-21 devnull m.u.certificate.ncert = 1;
502 0fc65b37 2004-03-21 devnull m.u.certificate.certs = emalloc(m.u.certificate.ncert * sizeof(Bytes));
503 0fc65b37 2004-03-21 devnull m.u.certificate.certs[0] = makebytes(cert, ncert);
504 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AQueue))
505 0fc65b37 2004-03-21 devnull goto Err;
506 0fc65b37 2004-03-21 devnull msgClear(&m);
507 0fc65b37 2004-03-21 devnull
508 0fc65b37 2004-03-21 devnull m.tag = HServerHelloDone;
509 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush))
510 0fc65b37 2004-03-21 devnull goto Err;
511 0fc65b37 2004-03-21 devnull msgClear(&m);
512 0fc65b37 2004-03-21 devnull
513 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m))
514 0fc65b37 2004-03-21 devnull goto Err;
515 0fc65b37 2004-03-21 devnull if(m.tag != HClientKeyExchange) {
516 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a client key exchange");
517 0fc65b37 2004-03-21 devnull goto Err;
518 0fc65b37 2004-03-21 devnull }
519 0fc65b37 2004-03-21 devnull if(tlsSecSecrets(c->sec, c->version, m.u.clientKeyExchange.key->data, m.u.clientKeyExchange.key->len, kd, c->nsecret) < 0){
520 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "couldn't set secrets: %r");
521 0fc65b37 2004-03-21 devnull goto Err;
522 0fc65b37 2004-03-21 devnull }
523 0fc65b37 2004-03-21 devnull if(trace)
524 0fc65b37 2004-03-21 devnull trace("tls secrets\n");
525 0fc65b37 2004-03-21 devnull secrets = (char*)emalloc(2*c->nsecret);
526 0fc65b37 2004-03-21 devnull enc64(secrets, 2*c->nsecret, kd, c->nsecret);
527 0fc65b37 2004-03-21 devnull rv = fprint(c->ctl, "secret %s %s 0 %s", c->digest, c->enc, secrets);
528 0fc65b37 2004-03-21 devnull memset(secrets, 0, 2*c->nsecret);
529 0fc65b37 2004-03-21 devnull free(secrets);
530 0fc65b37 2004-03-21 devnull memset(kd, 0, c->nsecret);
531 0fc65b37 2004-03-21 devnull if(rv < 0){
532 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "can't set keys: %r");
533 0fc65b37 2004-03-21 devnull goto Err;
534 0fc65b37 2004-03-21 devnull }
535 0fc65b37 2004-03-21 devnull msgClear(&m);
536 0fc65b37 2004-03-21 devnull
537 0fc65b37 2004-03-21 devnull /* no CertificateVerify; skip to Finished */
538 0fc65b37 2004-03-21 devnull if(tlsSecFinished(c->sec, c->hsmd5, c->hssha1, c->finished.verify, c->finished.n, 1) < 0){
539 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't set finished: %r");
540 0fc65b37 2004-03-21 devnull goto Err;
541 0fc65b37 2004-03-21 devnull }
542 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m))
543 0fc65b37 2004-03-21 devnull goto Err;
544 0fc65b37 2004-03-21 devnull if(m.tag != HFinished) {
545 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a finished");
546 0fc65b37 2004-03-21 devnull goto Err;
547 0fc65b37 2004-03-21 devnull }
548 0fc65b37 2004-03-21 devnull if(!finishedMatch(c, &m.u.finished)) {
549 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "finished verification failed");
550 0fc65b37 2004-03-21 devnull goto Err;
551 0fc65b37 2004-03-21 devnull }
552 0fc65b37 2004-03-21 devnull msgClear(&m);
553 0fc65b37 2004-03-21 devnull
554 0fc65b37 2004-03-21 devnull /* change cipher spec */
555 0fc65b37 2004-03-21 devnull if(fprint(c->ctl, "changecipher") < 0){
556 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't enable cipher: %r");
557 0fc65b37 2004-03-21 devnull goto Err;
558 0fc65b37 2004-03-21 devnull }
559 0fc65b37 2004-03-21 devnull
560 0fc65b37 2004-03-21 devnull if(tlsSecFinished(c->sec, c->hsmd5, c->hssha1, c->finished.verify, c->finished.n, 0) < 0){
561 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't set finished: %r");
562 0fc65b37 2004-03-21 devnull goto Err;
563 0fc65b37 2004-03-21 devnull }
564 0fc65b37 2004-03-21 devnull m.tag = HFinished;
565 0fc65b37 2004-03-21 devnull m.u.finished = c->finished;
566 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush))
567 0fc65b37 2004-03-21 devnull goto Err;
568 0fc65b37 2004-03-21 devnull msgClear(&m);
569 0fc65b37 2004-03-21 devnull if(trace)
570 0fc65b37 2004-03-21 devnull trace("tls finished\n");
571 0fc65b37 2004-03-21 devnull
572 0fc65b37 2004-03-21 devnull if(fprint(c->ctl, "opened") < 0)
573 0fc65b37 2004-03-21 devnull goto Err;
574 0fc65b37 2004-03-21 devnull tlsSecOk(c->sec);
575 0fc65b37 2004-03-21 devnull return c;
576 0fc65b37 2004-03-21 devnull
577 0fc65b37 2004-03-21 devnull Err:
578 0fc65b37 2004-03-21 devnull msgClear(&m);
579 0fc65b37 2004-03-21 devnull tlsConnectionFree(c);
580 0fc65b37 2004-03-21 devnull return 0;
581 0fc65b37 2004-03-21 devnull }
582 0fc65b37 2004-03-21 devnull
583 0fc65b37 2004-03-21 devnull static TlsConnection *
584 0fc65b37 2004-03-21 devnull tlsClient2(int ctl, int hand, uchar *csid, int ncsid, int (*trace)(char*fmt, ...))
585 0fc65b37 2004-03-21 devnull {
586 0fc65b37 2004-03-21 devnull TlsConnection *c;
587 0fc65b37 2004-03-21 devnull Msg m;
588 0fc65b37 2004-03-21 devnull uchar kd[MaxKeyData], *epm;
589 0fc65b37 2004-03-21 devnull char *secrets;
590 0fc65b37 2004-03-21 devnull int creq, nepm, rv;
591 0fc65b37 2004-03-21 devnull
592 0fc65b37 2004-03-21 devnull if(!initCiphers())
593 0fc65b37 2004-03-21 devnull return nil;
594 0fc65b37 2004-03-21 devnull epm = nil;
595 0fc65b37 2004-03-21 devnull c = emalloc(sizeof(TlsConnection));
596 0fc65b37 2004-03-21 devnull c->version = ProtocolVersion;
597 0fc65b37 2004-03-21 devnull c->ctl = ctl;
598 0fc65b37 2004-03-21 devnull c->hand = hand;
599 0fc65b37 2004-03-21 devnull c->trace = trace;
600 0fc65b37 2004-03-21 devnull c->isClient = 1;
601 0fc65b37 2004-03-21 devnull c->clientVersion = c->version;
602 0fc65b37 2004-03-21 devnull
603 0fc65b37 2004-03-21 devnull c->sec = tlsSecInitc(c->clientVersion, c->crandom);
604 0fc65b37 2004-03-21 devnull if(c->sec == nil)
605 0fc65b37 2004-03-21 devnull goto Err;
606 0fc65b37 2004-03-21 devnull
607 0fc65b37 2004-03-21 devnull /* client hello */
608 0fc65b37 2004-03-21 devnull memset(&m, 0, sizeof(m));
609 0fc65b37 2004-03-21 devnull m.tag = HClientHello;
610 0fc65b37 2004-03-21 devnull m.u.clientHello.version = c->clientVersion;
611 0fc65b37 2004-03-21 devnull memmove(m.u.clientHello.random, c->crandom, RandomSize);
612 0fc65b37 2004-03-21 devnull m.u.clientHello.sid = makebytes(csid, ncsid);
613 0fc65b37 2004-03-21 devnull m.u.clientHello.ciphers = makeciphers();
614 0fc65b37 2004-03-21 devnull m.u.clientHello.compressors = makebytes(compressors,sizeof(compressors));
615 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush))
616 0fc65b37 2004-03-21 devnull goto Err;
617 0fc65b37 2004-03-21 devnull msgClear(&m);
618 0fc65b37 2004-03-21 devnull
619 0fc65b37 2004-03-21 devnull /* server hello */
620 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m))
621 0fc65b37 2004-03-21 devnull goto Err;
622 0fc65b37 2004-03-21 devnull if(m.tag != HServerHello) {
623 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a server hello");
624 0fc65b37 2004-03-21 devnull goto Err;
625 0fc65b37 2004-03-21 devnull }
626 0fc65b37 2004-03-21 devnull if(setVersion(c, m.u.serverHello.version) < 0) {
627 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "incompatible version %r");
628 0fc65b37 2004-03-21 devnull goto Err;
629 0fc65b37 2004-03-21 devnull }
630 0fc65b37 2004-03-21 devnull memmove(c->srandom, m.u.serverHello.random, RandomSize);
631 0fc65b37 2004-03-21 devnull c->sid = makebytes(m.u.serverHello.sid->data, m.u.serverHello.sid->len);
632 0fc65b37 2004-03-21 devnull if(c->sid->len != 0 && c->sid->len != SidSize) {
633 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "invalid server session identifier");
634 0fc65b37 2004-03-21 devnull goto Err;
635 0fc65b37 2004-03-21 devnull }
636 0fc65b37 2004-03-21 devnull if(!setAlgs(c, m.u.serverHello.cipher)) {
637 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "invalid cipher suite");
638 0fc65b37 2004-03-21 devnull goto Err;
639 0fc65b37 2004-03-21 devnull }
640 0fc65b37 2004-03-21 devnull if(m.u.serverHello.compressor != CompressionNull) {
641 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "invalid compression");
642 0fc65b37 2004-03-21 devnull goto Err;
643 0fc65b37 2004-03-21 devnull }
644 0fc65b37 2004-03-21 devnull msgClear(&m);
645 0fc65b37 2004-03-21 devnull
646 0fc65b37 2004-03-21 devnull /* certificate */
647 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m) || m.tag != HCertificate) {
648 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a certificate");
649 0fc65b37 2004-03-21 devnull goto Err;
650 0fc65b37 2004-03-21 devnull }
651 0fc65b37 2004-03-21 devnull if(m.u.certificate.ncert < 1) {
652 0fc65b37 2004-03-21 devnull tlsError(c, EIllegalParameter, "runt certificate");
653 0fc65b37 2004-03-21 devnull goto Err;
654 0fc65b37 2004-03-21 devnull }
655 0fc65b37 2004-03-21 devnull c->cert = makebytes(m.u.certificate.certs[0]->data, m.u.certificate.certs[0]->len);
656 0fc65b37 2004-03-21 devnull msgClear(&m);
657 0fc65b37 2004-03-21 devnull
658 0fc65b37 2004-03-21 devnull /* server key exchange (optional) */
659 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m))
660 0fc65b37 2004-03-21 devnull goto Err;
661 0fc65b37 2004-03-21 devnull if(m.tag == HServerKeyExchange) {
662 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "got an server key exchange");
663 0fc65b37 2004-03-21 devnull goto Err;
664 0fc65b37 2004-03-21 devnull // If implementing this later, watch out for rollback attack
665 0fc65b37 2004-03-21 devnull // described in Wagner Schneier 1996, section 4.4.
666 0fc65b37 2004-03-21 devnull }
667 0fc65b37 2004-03-21 devnull
668 0fc65b37 2004-03-21 devnull /* certificate request (optional) */
669 0fc65b37 2004-03-21 devnull creq = 0;
670 0fc65b37 2004-03-21 devnull if(m.tag == HCertificateRequest) {
671 0fc65b37 2004-03-21 devnull creq = 1;
672 0fc65b37 2004-03-21 devnull msgClear(&m);
673 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m))
674 0fc65b37 2004-03-21 devnull goto Err;
675 0fc65b37 2004-03-21 devnull }
676 0fc65b37 2004-03-21 devnull
677 0fc65b37 2004-03-21 devnull if(m.tag != HServerHelloDone) {
678 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a server hello done");
679 0fc65b37 2004-03-21 devnull goto Err;
680 0fc65b37 2004-03-21 devnull }
681 0fc65b37 2004-03-21 devnull msgClear(&m);
682 0fc65b37 2004-03-21 devnull
683 0fc65b37 2004-03-21 devnull if(tlsSecSecretc(c->sec, c->sid->data, c->sid->len, c->srandom,
684 0fc65b37 2004-03-21 devnull c->cert->data, c->cert->len, c->version, &epm, &nepm,
685 0fc65b37 2004-03-21 devnull kd, c->nsecret) < 0){
686 0fc65b37 2004-03-21 devnull tlsError(c, EBadCertificate, "invalid x509/rsa certificate");
687 0fc65b37 2004-03-21 devnull goto Err;
688 0fc65b37 2004-03-21 devnull }
689 0fc65b37 2004-03-21 devnull secrets = (char*)emalloc(2*c->nsecret);
690 0fc65b37 2004-03-21 devnull enc64(secrets, 2*c->nsecret, kd, c->nsecret);
691 0fc65b37 2004-03-21 devnull rv = fprint(c->ctl, "secret %s %s 1 %s", c->digest, c->enc, secrets);
692 0fc65b37 2004-03-21 devnull memset(secrets, 0, 2*c->nsecret);
693 0fc65b37 2004-03-21 devnull free(secrets);
694 0fc65b37 2004-03-21 devnull memset(kd, 0, c->nsecret);
695 0fc65b37 2004-03-21 devnull if(rv < 0){
696 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "can't set keys: %r");
697 0fc65b37 2004-03-21 devnull goto Err;
698 0fc65b37 2004-03-21 devnull }
699 0fc65b37 2004-03-21 devnull
700 0fc65b37 2004-03-21 devnull if(creq) {
701 0fc65b37 2004-03-21 devnull /* send a zero length certificate */
702 0fc65b37 2004-03-21 devnull m.tag = HCertificate;
703 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush))
704 0fc65b37 2004-03-21 devnull goto Err;
705 0fc65b37 2004-03-21 devnull msgClear(&m);
706 0fc65b37 2004-03-21 devnull }
707 0fc65b37 2004-03-21 devnull
708 0fc65b37 2004-03-21 devnull /* client key exchange */
709 0fc65b37 2004-03-21 devnull m.tag = HClientKeyExchange;
710 0fc65b37 2004-03-21 devnull m.u.clientKeyExchange.key = makebytes(epm, nepm);
711 0fc65b37 2004-03-21 devnull free(epm);
712 0fc65b37 2004-03-21 devnull epm = nil;
713 0fc65b37 2004-03-21 devnull if(m.u.clientKeyExchange.key == nil) {
714 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "can't set secret: %r");
715 0fc65b37 2004-03-21 devnull goto Err;
716 0fc65b37 2004-03-21 devnull }
717 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush))
718 0fc65b37 2004-03-21 devnull goto Err;
719 0fc65b37 2004-03-21 devnull msgClear(&m);
720 0fc65b37 2004-03-21 devnull
721 0fc65b37 2004-03-21 devnull /* change cipher spec */
722 0fc65b37 2004-03-21 devnull if(fprint(c->ctl, "changecipher") < 0){
723 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't enable cipher: %r");
724 0fc65b37 2004-03-21 devnull goto Err;
725 0fc65b37 2004-03-21 devnull }
726 0fc65b37 2004-03-21 devnull
727 0fc65b37 2004-03-21 devnull // Cipherchange must occur immediately before Finished to avoid
728 0fc65b37 2004-03-21 devnull // potential hole; see section 4.3 of Wagner Schneier 1996.
729 0fc65b37 2004-03-21 devnull if(tlsSecFinished(c->sec, c->hsmd5, c->hssha1, c->finished.verify, c->finished.n, 1) < 0){
730 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't set finished 1: %r");
731 0fc65b37 2004-03-21 devnull goto Err;
732 0fc65b37 2004-03-21 devnull }
733 0fc65b37 2004-03-21 devnull m.tag = HFinished;
734 0fc65b37 2004-03-21 devnull m.u.finished = c->finished;
735 0fc65b37 2004-03-21 devnull
736 0fc65b37 2004-03-21 devnull if(!msgSend(c, &m, AFlush)) {
737 0fc65b37 2004-03-21 devnull fprint(2, "tlsClient nepm=%d\n", nepm);
738 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't flush after client Finished: %r");
739 0fc65b37 2004-03-21 devnull goto Err;
740 0fc65b37 2004-03-21 devnull }
741 0fc65b37 2004-03-21 devnull msgClear(&m);
742 0fc65b37 2004-03-21 devnull
743 0fc65b37 2004-03-21 devnull if(tlsSecFinished(c->sec, c->hsmd5, c->hssha1, c->finished.verify, c->finished.n, 0) < 0){
744 0fc65b37 2004-03-21 devnull fprint(2, "tlsClient nepm=%d\n", nepm);
745 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't set finished 0: %r");
746 0fc65b37 2004-03-21 devnull goto Err;
747 0fc65b37 2004-03-21 devnull }
748 0fc65b37 2004-03-21 devnull if(!msgRecv(c, &m)) {
749 0fc65b37 2004-03-21 devnull fprint(2, "tlsClient nepm=%d\n", nepm);
750 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't read server Finished: %r");
751 0fc65b37 2004-03-21 devnull goto Err;
752 0fc65b37 2004-03-21 devnull }
753 0fc65b37 2004-03-21 devnull if(m.tag != HFinished) {
754 0fc65b37 2004-03-21 devnull fprint(2, "tlsClient nepm=%d\n", nepm);
755 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "expected a Finished msg from server");
756 0fc65b37 2004-03-21 devnull goto Err;
757 0fc65b37 2004-03-21 devnull }
758 0fc65b37 2004-03-21 devnull
759 0fc65b37 2004-03-21 devnull if(!finishedMatch(c, &m.u.finished)) {
760 0fc65b37 2004-03-21 devnull tlsError(c, EHandshakeFailure, "finished verification failed");
761 0fc65b37 2004-03-21 devnull goto Err;
762 0fc65b37 2004-03-21 devnull }
763 0fc65b37 2004-03-21 devnull msgClear(&m);
764 0fc65b37 2004-03-21 devnull
765 0fc65b37 2004-03-21 devnull if(fprint(c->ctl, "opened") < 0){
766 0fc65b37 2004-03-21 devnull if(trace)
767 0fc65b37 2004-03-21 devnull trace("unable to do final open: %r\n");
768 0fc65b37 2004-03-21 devnull goto Err;
769 0fc65b37 2004-03-21 devnull }
770 0fc65b37 2004-03-21 devnull tlsSecOk(c->sec);
771 0fc65b37 2004-03-21 devnull return c;
772 0fc65b37 2004-03-21 devnull
773 0fc65b37 2004-03-21 devnull Err:
774 0fc65b37 2004-03-21 devnull free(epm);
775 0fc65b37 2004-03-21 devnull msgClear(&m);
776 0fc65b37 2004-03-21 devnull tlsConnectionFree(c);
777 0fc65b37 2004-03-21 devnull return 0;
778 0fc65b37 2004-03-21 devnull }
779 0fc65b37 2004-03-21 devnull
780 0fc65b37 2004-03-21 devnull
781 0fc65b37 2004-03-21 devnull //================= message functions ========================
782 0fc65b37 2004-03-21 devnull
783 0fc65b37 2004-03-21 devnull static uchar sendbuf[9000], *sendp;
784 0fc65b37 2004-03-21 devnull
785 0fc65b37 2004-03-21 devnull static int
786 0fc65b37 2004-03-21 devnull msgSend(TlsConnection *c, Msg *m, int act)
787 0fc65b37 2004-03-21 devnull {
788 0fc65b37 2004-03-21 devnull uchar *p; // sendp = start of new message; p = write pointer
789 0fc65b37 2004-03-21 devnull int nn, n, i;
790 0fc65b37 2004-03-21 devnull
791 0fc65b37 2004-03-21 devnull if(sendp == nil)
792 0fc65b37 2004-03-21 devnull sendp = sendbuf;
793 0fc65b37 2004-03-21 devnull p = sendp;
794 0fc65b37 2004-03-21 devnull if(c->trace)
795 0fc65b37 2004-03-21 devnull c->trace("send %s", msgPrint((char*)p, (sizeof sendbuf) - (p-sendbuf), m));
796 0fc65b37 2004-03-21 devnull
797 0fc65b37 2004-03-21 devnull p[0] = m->tag; // header - fill in size later
798 0fc65b37 2004-03-21 devnull p += 4;
799 0fc65b37 2004-03-21 devnull
800 0fc65b37 2004-03-21 devnull switch(m->tag) {
801 0fc65b37 2004-03-21 devnull default:
802 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "can't encode a %d", m->tag);
803 0fc65b37 2004-03-21 devnull goto Err;
804 0fc65b37 2004-03-21 devnull case HClientHello:
805 0fc65b37 2004-03-21 devnull // version
806 0fc65b37 2004-03-21 devnull put16(p, m->u.clientHello.version);
807 0fc65b37 2004-03-21 devnull p += 2;
808 0fc65b37 2004-03-21 devnull
809 0fc65b37 2004-03-21 devnull // random
810 0fc65b37 2004-03-21 devnull memmove(p, m->u.clientHello.random, RandomSize);
811 0fc65b37 2004-03-21 devnull p += RandomSize;
812 0fc65b37 2004-03-21 devnull
813 0fc65b37 2004-03-21 devnull // sid
814 0fc65b37 2004-03-21 devnull n = m->u.clientHello.sid->len;
815 0fc65b37 2004-03-21 devnull assert(n < 256);
816 0fc65b37 2004-03-21 devnull p[0] = n;
817 0fc65b37 2004-03-21 devnull memmove(p+1, m->u.clientHello.sid->data, n);
818 0fc65b37 2004-03-21 devnull p += n+1;
819 0fc65b37 2004-03-21 devnull
820 0fc65b37 2004-03-21 devnull n = m->u.clientHello.ciphers->len;
821 0fc65b37 2004-03-21 devnull assert(n > 0 && n < 200);
822 0fc65b37 2004-03-21 devnull put16(p, n*2);
823 0fc65b37 2004-03-21 devnull p += 2;
824 0fc65b37 2004-03-21 devnull for(i=0; i<n; i++) {
825 0fc65b37 2004-03-21 devnull put16(p, m->u.clientHello.ciphers->data[i]);
826 0fc65b37 2004-03-21 devnull p += 2;
827 0fc65b37 2004-03-21 devnull }
828 0fc65b37 2004-03-21 devnull
829 0fc65b37 2004-03-21 devnull n = m->u.clientHello.compressors->len;
830 0fc65b37 2004-03-21 devnull assert(n > 0);
831 0fc65b37 2004-03-21 devnull p[0] = n;
832 0fc65b37 2004-03-21 devnull memmove(p+1, m->u.clientHello.compressors->data, n);
833 0fc65b37 2004-03-21 devnull p += n+1;
834 0fc65b37 2004-03-21 devnull break;
835 0fc65b37 2004-03-21 devnull case HServerHello:
836 0fc65b37 2004-03-21 devnull put16(p, m->u.serverHello.version);
837 0fc65b37 2004-03-21 devnull p += 2;
838 0fc65b37 2004-03-21 devnull
839 0fc65b37 2004-03-21 devnull // random
840 0fc65b37 2004-03-21 devnull memmove(p, m->u.serverHello.random, RandomSize);
841 0fc65b37 2004-03-21 devnull p += RandomSize;
842 0fc65b37 2004-03-21 devnull
843 0fc65b37 2004-03-21 devnull // sid
844 0fc65b37 2004-03-21 devnull n = m->u.serverHello.sid->len;
845 0fc65b37 2004-03-21 devnull assert(n < 256);
846 0fc65b37 2004-03-21 devnull p[0] = n;
847 0fc65b37 2004-03-21 devnull memmove(p+1, m->u.serverHello.sid->data, n);
848 0fc65b37 2004-03-21 devnull p += n+1;
849 0fc65b37 2004-03-21 devnull
850 0fc65b37 2004-03-21 devnull put16(p, m->u.serverHello.cipher);
851 0fc65b37 2004-03-21 devnull p += 2;
852 0fc65b37 2004-03-21 devnull p[0] = m->u.serverHello.compressor;
853 0fc65b37 2004-03-21 devnull p += 1;
854 0fc65b37 2004-03-21 devnull break;
855 0fc65b37 2004-03-21 devnull case HServerHelloDone:
856 0fc65b37 2004-03-21 devnull break;
857 0fc65b37 2004-03-21 devnull case HCertificate:
858 0fc65b37 2004-03-21 devnull nn = 0;
859 0fc65b37 2004-03-21 devnull for(i = 0; i < m->u.certificate.ncert; i++)
860 0fc65b37 2004-03-21 devnull nn += 3 + m->u.certificate.certs[i]->len;
861 0fc65b37 2004-03-21 devnull if(p + 3 + nn - sendbuf > sizeof(sendbuf)) {
862 0fc65b37 2004-03-21 devnull tlsError(c, EInternalError, "output buffer too small for certificate");
863 0fc65b37 2004-03-21 devnull goto Err;
864 0fc65b37 2004-03-21 devnull }
865 0fc65b37 2004-03-21 devnull put24(p, nn);
866 0fc65b37 2004-03-21 devnull p += 3;
867 0fc65b37 2004-03-21 devnull for(i = 0; i < m->u.certificate.ncert; i++){
868 0fc65b37 2004-03-21 devnull put24(p, m->u.certificate.certs[i]->len);
869 0fc65b37 2004-03-21 devnull p += 3;
870 0fc65b37 2004-03-21 devnull memmove(p, m->u.certificate.certs[i]->data, m->u.certificate.certs[i]->len);
871 0fc65b37 2004-03-21 devnull p += m->u.certificate.certs[i]->len;
872 0fc65b37 2004-03-21 devnull }
873 0fc65b37 2004-03-21 devnull break;
874 0fc65b37 2004-03-21 devnull case HClientKeyExchange:
875 0fc65b37 2004-03-21 devnull n = m->u.clientKeyExchange.key->len;
876 0fc65b37 2004-03-21 devnull if(c->version != SSL3Version){
877 0fc65b37 2004-03-21 devnull put16(p, n);
878 0fc65b37 2004-03-21 devnull p += 2;
879 0fc65b37 2004-03-21 devnull }
880 0fc65b37 2004-03-21 devnull memmove(p, m->u.clientKeyExchange.key->data, n);
881 0fc65b37 2004-03-21 devnull p += n;
882 0fc65b37 2004-03-21 devnull break;
883 0fc65b37 2004-03-21 devnull case HFinished:
884 0fc65b37 2004-03-21 devnull memmove(p, m->u.finished.verify, m->u.finished.n);
885 0fc65b37 2004-03-21 devnull p += m->u.finished.n;
886 0fc65b37 2004-03-21 devnull break;
887 0fc65b37 2004-03-21 devnull }
888 0fc65b37 2004-03-21 devnull
889 0fc65b37 2004-03-21 devnull // go back and fill in size
890 0fc65b37 2004-03-21 devnull n = p-sendp;
891 0fc65b37 2004-03-21 devnull assert(p <= sendbuf+sizeof(sendbuf));
892 0fc65b37 2004-03-21 devnull put24(sendp+1, n-4);
893 0fc65b37 2004-03-21 devnull
894 0fc65b37 2004-03-21 devnull // remember hash of Handshake messages
895 0fc65b37 2004-03-21 devnull if(m->tag != HHelloRequest) {
896 0fc65b37 2004-03-21 devnull md5(sendp, n, 0, &c->hsmd5);
897 0fc65b37 2004-03-21 devnull sha1(sendp, n, 0, &c->hssha1);
898 0fc65b37 2004-03-21 devnull }
899 0fc65b37 2004-03-21 devnull
900 0fc65b37 2004-03-21 devnull sendp = p;
901 0fc65b37 2004-03-21 devnull if(act == AFlush){
902 0fc65b37 2004-03-21 devnull sendp = sendbuf;
903 0fc65b37 2004-03-21 devnull if(write(c->hand, sendbuf, p-sendbuf) < 0){
904 0fc65b37 2004-03-21 devnull fprint(2, "write error: %r\n");
905 0fc65b37 2004-03-21 devnull goto Err;
906 0fc65b37 2004-03-21 devnull }
907 0fc65b37 2004-03-21 devnull }
908 0fc65b37 2004-03-21 devnull msgClear(m);
909 0fc65b37 2004-03-21 devnull return 1;
910 0fc65b37 2004-03-21 devnull Err:
911 0fc65b37 2004-03-21 devnull msgClear(m);
912 0fc65b37 2004-03-21 devnull return 0;
913 0fc65b37 2004-03-21 devnull }
914 0fc65b37 2004-03-21 devnull
915 0fc65b37 2004-03-21 devnull static uchar*
916 0fc65b37 2004-03-21 devnull tlsReadN(TlsConnection *c, int n)
917 0fc65b37 2004-03-21 devnull {
918 0fc65b37 2004-03-21 devnull uchar *p;
919 0fc65b37 2004-03-21 devnull int nn, nr;
920 0fc65b37 2004-03-21 devnull
921 0fc65b37 2004-03-21 devnull nn = c->ep - c->rp;
922 0fc65b37 2004-03-21 devnull if(nn < n){
923 0fc65b37 2004-03-21 devnull if(c->rp != c->buf){
924 0fc65b37 2004-03-21 devnull memmove(c->buf, c->rp, nn);
925 0fc65b37 2004-03-21 devnull c->rp = c->buf;
926 0fc65b37 2004-03-21 devnull c->ep = &c->buf[nn];
927 0fc65b37 2004-03-21 devnull }
928 0fc65b37 2004-03-21 devnull for(; nn < n; nn += nr) {
929 0fc65b37 2004-03-21 devnull nr = read(c->hand, &c->rp[nn], n - nn);
930 0fc65b37 2004-03-21 devnull if(nr <= 0)
931 0fc65b37 2004-03-21 devnull return nil;
932 0fc65b37 2004-03-21 devnull c->ep += nr;
933 0fc65b37 2004-03-21 devnull }
934 0fc65b37 2004-03-21 devnull }
935 0fc65b37 2004-03-21 devnull p = c->rp;
936 0fc65b37 2004-03-21 devnull c->rp += n;
937 0fc65b37 2004-03-21 devnull return p;
938 0fc65b37 2004-03-21 devnull }
939 0fc65b37 2004-03-21 devnull
940 0fc65b37 2004-03-21 devnull static int
941 0fc65b37 2004-03-21 devnull msgRecv(TlsConnection *c, Msg *m)
942 0fc65b37 2004-03-21 devnull {
943 0fc65b37 2004-03-21 devnull uchar *p;
944 0fc65b37 2004-03-21 devnull int type, n, nn, i, nsid, nrandom, nciph;
945 0fc65b37 2004-03-21 devnull
946 0fc65b37 2004-03-21 devnull for(;;) {
947 0fc65b37 2004-03-21 devnull p = tlsReadN(c, 4);
948 0fc65b37 2004-03-21 devnull if(p == nil)
949 0fc65b37 2004-03-21 devnull return 0;
950 0fc65b37 2004-03-21 devnull type = p[0];
951 0fc65b37 2004-03-21 devnull n = get24(p+1);
952 0fc65b37 2004-03-21 devnull
953 0fc65b37 2004-03-21 devnull if(type != HHelloRequest)
954 0fc65b37 2004-03-21 devnull break;
955 0fc65b37 2004-03-21 devnull if(n != 0) {
956 0fc65b37 2004-03-21 devnull tlsError(c, EDecodeError, "invalid hello request during handshake");
957 0fc65b37 2004-03-21 devnull return 0;
958 0fc65b37 2004-03-21 devnull }
959 0fc65b37 2004-03-21 devnull }
960 0fc65b37 2004-03-21 devnull
961 0fc65b37 2004-03-21 devnull if(n > sizeof(c->buf)) {
962 0fc65b37 2004-03-21 devnull tlsError(c, EDecodeError, "handshake message too long %d %d", n, sizeof(c->buf));
963 0fc65b37 2004-03-21 devnull return 0;
964 0fc65b37 2004-03-21 devnull }
965 0fc65b37 2004-03-21 devnull
966 0fc65b37 2004-03-21 devnull if(type == HSSL2ClientHello){
967 0fc65b37 2004-03-21 devnull /* Cope with an SSL3 ClientHello expressed in SSL2 record format.
968 0fc65b37 2004-03-21 devnull This is sent by some clients that we must interoperate
969 0fc65b37 2004-03-21 devnull with, such as Java's JSSE and Microsoft's Internet Explorer. */
970 0fc65b37 2004-03-21 devnull p = tlsReadN(c, n);
971 0fc65b37 2004-03-21 devnull if(p == nil)
972 0fc65b37 2004-03-21 devnull return 0;
973 0fc65b37 2004-03-21 devnull md5(p, n, 0, &c->hsmd5);
974 0fc65b37 2004-03-21 devnull sha1(p, n, 0, &c->hssha1);
975 0fc65b37 2004-03-21 devnull m->tag = HClientHello;
976 0fc65b37 2004-03-21 devnull if(n < 22)
977 0fc65b37 2004-03-21 devnull goto Short;
978 0fc65b37 2004-03-21 devnull m->u.clientHello.version = get16(p+1);
979 0fc65b37 2004-03-21 devnull p += 3;
980 0fc65b37 2004-03-21 devnull n -= 3;
981 0fc65b37 2004-03-21 devnull nn = get16(p); /* cipher_spec_len */
982 0fc65b37 2004-03-21 devnull nsid = get16(p + 2);
983 0fc65b37 2004-03-21 devnull nrandom = get16(p + 4);
984 0fc65b37 2004-03-21 devnull p += 6;
985 0fc65b37 2004-03-21 devnull n -= 6;
986 0fc65b37 2004-03-21 devnull if(nsid != 0 /* no sid's, since shouldn't restart using ssl2 header */
987 0fc65b37 2004-03-21 devnull || nrandom < 16 || nn % 3)
988 0fc65b37 2004-03-21 devnull goto Err;
989 0fc65b37 2004-03-21 devnull if(c->trace && (n - nrandom != nn))
990 0fc65b37 2004-03-21 devnull c->trace("n-nrandom!=nn: n=%d nrandom=%d nn=%d\n", n, nrandom, nn);
991 0fc65b37 2004-03-21 devnull /* ignore ssl2 ciphers and look for {0x00, ssl3 cipher} */
992 0fc65b37 2004-03-21 devnull nciph = 0;
993 0fc65b37 2004-03-21 devnull for(i = 0; i < nn; i += 3)
994 0fc65b37 2004-03-21 devnull if(p[i] == 0)
995 0fc65b37 2004-03-21 devnull nciph++;
996 0fc65b37 2004-03-21 devnull m->u.clientHello.ciphers = newints(nciph);
997 0fc65b37 2004-03-21 devnull nciph = 0;
998 0fc65b37 2004-03-21 devnull for(i = 0; i < nn; i += 3)
999 0fc65b37 2004-03-21 devnull if(p[i] == 0)
1000 0fc65b37 2004-03-21 devnull m->u.clientHello.ciphers->data[nciph++] = get16(&p[i + 1]);
1001 0fc65b37 2004-03-21 devnull p += nn;
1002 0fc65b37 2004-03-21 devnull m->u.clientHello.sid = makebytes(nil, 0);
1003 0fc65b37 2004-03-21 devnull if(nrandom > RandomSize)
1004 0fc65b37 2004-03-21 devnull nrandom = RandomSize;
1005 0fc65b37 2004-03-21 devnull memset(m->u.clientHello.random, 0, RandomSize - nrandom);
1006 0fc65b37 2004-03-21 devnull memmove(&m->u.clientHello.random[RandomSize - nrandom], p, nrandom);
1007 0fc65b37 2004-03-21 devnull m->u.clientHello.compressors = newbytes(1);
1008 0fc65b37 2004-03-21 devnull m->u.clientHello.compressors->data[0] = CompressionNull;
1009 0fc65b37 2004-03-21 devnull goto Ok;
1010 0fc65b37 2004-03-21 devnull }
1011 0fc65b37 2004-03-21 devnull
1012 0fc65b37 2004-03-21 devnull md5(p, 4, 0, &c->hsmd5);
1013 0fc65b37 2004-03-21 devnull sha1(p, 4, 0, &c->hssha1);
1014 0fc65b37 2004-03-21 devnull
1015 0fc65b37 2004-03-21 devnull p = tlsReadN(c, n);
1016 0fc65b37 2004-03-21 devnull if(p == nil)
1017 0fc65b37 2004-03-21 devnull return 0;
1018 0fc65b37 2004-03-21 devnull
1019 0fc65b37 2004-03-21 devnull md5(p, n, 0, &c->hsmd5);
1020 0fc65b37 2004-03-21 devnull sha1(p, n, 0, &c->hssha1);
1021 0fc65b37 2004-03-21 devnull
1022 0fc65b37 2004-03-21 devnull m->tag = type;
1023 0fc65b37 2004-03-21 devnull
1024 0fc65b37 2004-03-21 devnull switch(type) {
1025 0fc65b37 2004-03-21 devnull default:
1026 0fc65b37 2004-03-21 devnull tlsError(c, EUnexpectedMessage, "can't decode a %d", type);
1027 0fc65b37 2004-03-21 devnull goto Err;
1028 0fc65b37 2004-03-21 devnull case HClientHello:
1029 0fc65b37 2004-03-21 devnull if(n < 2)
1030 0fc65b37 2004-03-21 devnull goto Short;
1031 0fc65b37 2004-03-21 devnull m->u.clientHello.version = get16(p);
1032 0fc65b37 2004-03-21 devnull p += 2;
1033 0fc65b37 2004-03-21 devnull n -= 2;
1034 0fc65b37 2004-03-21 devnull
1035 0fc65b37 2004-03-21 devnull if(n < RandomSize)
1036 0fc65b37 2004-03-21 devnull goto Short;
1037 0fc65b37 2004-03-21 devnull memmove(m->u.clientHello.random, p, RandomSize);
1038 0fc65b37 2004-03-21 devnull p += RandomSize;
1039 0fc65b37 2004-03-21 devnull n -= RandomSize;
1040 0fc65b37 2004-03-21 devnull if(n < 1 || n < p[0]+1)
1041 0fc65b37 2004-03-21 devnull goto Short;
1042 0fc65b37 2004-03-21 devnull m->u.clientHello.sid = makebytes(p+1, p[0]);
1043 0fc65b37 2004-03-21 devnull p += m->u.clientHello.sid->len+1;
1044 0fc65b37 2004-03-21 devnull n -= m->u.clientHello.sid->len+1;
1045 0fc65b37 2004-03-21 devnull
1046 0fc65b37 2004-03-21 devnull if(n < 2)
1047 0fc65b37 2004-03-21 devnull goto Short;
1048 0fc65b37 2004-03-21 devnull nn = get16(p);
1049 0fc65b37 2004-03-21 devnull p += 2;
1050 0fc65b37 2004-03-21 devnull n -= 2;
1051 0fc65b37 2004-03-21 devnull
1052 0fc65b37 2004-03-21 devnull if((nn & 1) || n < nn || nn < 2)
1053 0fc65b37 2004-03-21 devnull goto Short;
1054 0fc65b37 2004-03-21 devnull m->u.clientHello.ciphers = newints(nn >> 1);
1055 0fc65b37 2004-03-21 devnull for(i = 0; i < nn; i += 2)
1056 0fc65b37 2004-03-21 devnull m->u.clientHello.ciphers->data[i >> 1] = get16(&p[i]);
1057 0fc65b37 2004-03-21 devnull p += nn;
1058 0fc65b37 2004-03-21 devnull n -= nn;
1059 0fc65b37 2004-03-21 devnull
1060 0fc65b37 2004-03-21 devnull if(n < 1 || n < p[0]+1 || p[0] == 0)
1061 0fc65b37 2004-03-21 devnull goto Short;
1062 0fc65b37 2004-03-21 devnull nn = p[0];
1063 0fc65b37 2004-03-21 devnull m->u.clientHello.compressors = newbytes(nn);
1064 0fc65b37 2004-03-21 devnull memmove(m->u.clientHello.compressors->data, p+1, nn);
1065 0fc65b37 2004-03-21 devnull n -= nn + 1;
1066 0fc65b37 2004-03-21 devnull break;
1067 0fc65b37 2004-03-21 devnull case HServerHello:
1068 0fc65b37 2004-03-21 devnull if(n < 2)
1069 0fc65b37 2004-03-21 devnull goto Short;
1070 0fc65b37 2004-03-21 devnull m->u.serverHello.version = get16(p);
1071 0fc65b37 2004-03-21 devnull p += 2;
1072 0fc65b37 2004-03-21 devnull n -= 2;
1073 0fc65b37 2004-03-21 devnull
1074 0fc65b37 2004-03-21 devnull if(n < RandomSize)
1075 0fc65b37 2004-03-21 devnull goto Short;
1076 0fc65b37 2004-03-21 devnull memmove(m->u.serverHello.random, p, RandomSize);
1077 0fc65b37 2004-03-21 devnull p += RandomSize;
1078 0fc65b37 2004-03-21 devnull n -= RandomSize;
1079 0fc65b37 2004-03-21 devnull
1080 0fc65b37 2004-03-21 devnull if(n < 1 || n < p[0]+1)
1081 0fc65b37 2004-03-21 devnull goto Short;
1082 0fc65b37 2004-03-21 devnull m->u.serverHello.sid = makebytes(p+1, p[0]);
1083 0fc65b37 2004-03-21 devnull p += m->u.serverHello.sid->len+1;
1084 0fc65b37 2004-03-21 devnull n -= m->u.serverHello.sid->len+1;
1085 0fc65b37 2004-03-21 devnull
1086 0fc65b37 2004-03-21 devnull if(n < 3)
1087 0fc65b37 2004-03-21 devnull goto Short;
1088 0fc65b37 2004-03-21 devnull m->u.serverHello.cipher = get16(p);
1089 0fc65b37 2004-03-21 devnull m->u.serverHello.compressor = p[2];
1090 0fc65b37 2004-03-21 devnull n -= 3;
1091 0fc65b37 2004-03-21 devnull break;
1092 0fc65b37 2004-03-21 devnull case HCertificate:
1093 0fc65b37 2004-03-21 devnull if(n < 3)
1094 0fc65b37 2004-03-21 devnull goto Short;
1095 0fc65b37 2004-03-21 devnull nn = get24(p);
1096 0fc65b37 2004-03-21 devnull p += 3;
1097 0fc65b37 2004-03-21 devnull n -= 3;
1098 0fc65b37 2004-03-21 devnull if(n != nn)
1099 0fc65b37 2004-03-21 devnull goto Short;
1100 0fc65b37 2004-03-21 devnull /* certs */
1101 0fc65b37 2004-03-21 devnull i = 0;
1102 0fc65b37 2004-03-21 devnull while(n > 0) {
1103 0fc65b37 2004-03-21 devnull if(n < 3)
1104 0fc65b37 2004-03-21 devnull goto Short;
1105 0fc65b37 2004-03-21 devnull nn = get24(p);
1106 0fc65b37 2004-03-21 devnull p += 3;
1107 0fc65b37 2004-03-21 devnull n -= 3;
1108 0fc65b37 2004-03-21 devnull if(nn > n)
1109 0fc65b37 2004-03-21 devnull goto Short;
1110 0fc65b37 2004-03-21 devnull m->u.certificate.ncert = i+1;
1111 0fc65b37 2004-03-21 devnull m->u.certificate.certs = erealloc(m->u.certificate.certs, (i+1)*sizeof(Bytes));
1112 0fc65b37 2004-03-21 devnull m->u.certificate.certs[i] = makebytes(p, nn);
1113 0fc65b37 2004-03-21 devnull p += nn;
1114 0fc65b37 2004-03-21 devnull n -= nn;
1115 0fc65b37 2004-03-21 devnull i++;
1116 0fc65b37 2004-03-21 devnull }
1117 0fc65b37 2004-03-21 devnull break;
1118 0fc65b37 2004-03-21 devnull case HCertificateRequest:
1119 0fc65b37 2004-03-21 devnull if(n < 2)
1120 0fc65b37 2004-03-21 devnull goto Short;
1121 0fc65b37 2004-03-21 devnull nn = get16(p);
1122 0fc65b37 2004-03-21 devnull p += 2;
1123 0fc65b37 2004-03-21 devnull n -= 2;
1124 0fc65b37 2004-03-21 devnull if(nn < 1 || nn > n)
1125 0fc65b37 2004-03-21 devnull goto Short;
1126 0fc65b37 2004-03-21 devnull m->u.certificateRequest.types = makebytes(p, nn);
1127 0fc65b37 2004-03-21 devnull nn = get24(p);
1128 0fc65b37 2004-03-21 devnull p += 3;
1129 0fc65b37 2004-03-21 devnull n -= 3;
1130 0fc65b37 2004-03-21 devnull if(nn == 0 || n != nn)
1131 0fc65b37 2004-03-21 devnull goto Short;
1132 0fc65b37 2004-03-21 devnull /* cas */
1133 0fc65b37 2004-03-21 devnull i = 0;
1134 0fc65b37 2004-03-21 devnull while(n > 0) {
1135 0fc65b37 2004-03-21 devnull if(n < 2)
1136 0fc65b37 2004-03-21 devnull goto Short;
1137 0fc65b37 2004-03-21 devnull nn = get16(p);
1138 0fc65b37 2004-03-21 devnull p += 2;
1139 0fc65b37 2004-03-21 devnull n -= 2;
1140 0fc65b37 2004-03-21 devnull if(nn < 1 || nn > n)
1141 0fc65b37 2004-03-21 devnull goto Short;
1142 0fc65b37 2004-03-21 devnull m->u.certificateRequest.nca = i+1;
1143 0fc65b37 2004-03-21 devnull m->u.certificateRequest.cas = erealloc(m->u.certificateRequest.cas, (i+1)*sizeof(Bytes));
1144 0fc65b37 2004-03-21 devnull m->u.certificateRequest.cas[i] = makebytes(p, nn);
1145 0fc65b37 2004-03-21 devnull p += nn;
1146 0fc65b37 2004-03-21 devnull n -= nn;
1147 0fc65b37 2004-03-21 devnull i++;
1148 0fc65b37 2004-03-21 devnull }
1149 0fc65b37 2004-03-21 devnull break;
1150 0fc65b37 2004-03-21 devnull case HServerHelloDone:
1151 0fc65b37 2004-03-21 devnull break;
1152 0fc65b37 2004-03-21 devnull case HClientKeyExchange:
1153 0fc65b37 2004-03-21 devnull /*
1154 0fc65b37 2004-03-21 devnull * this message depends upon the encryption selected
1155 0fc65b37 2004-03-21 devnull * assume rsa.
1156 0fc65b37 2004-03-21 devnull */
1157 0fc65b37 2004-03-21 devnull if(c->version == SSL3Version)
1158 0fc65b37 2004-03-21 devnull nn = n;
1159 0fc65b37 2004-03-21 devnull else{
1160 0fc65b37 2004-03-21 devnull if(n < 2)
1161 0fc65b37 2004-03-21 devnull goto Short;
1162 0fc65b37 2004-03-21 devnull nn = get16(p);
1163 0fc65b37 2004-03-21 devnull p += 2;
1164 0fc65b37 2004-03-21 devnull n -= 2;
1165 0fc65b37 2004-03-21 devnull }
1166 0fc65b37 2004-03-21 devnull if(n < nn)
1167 0fc65b37 2004-03-21 devnull goto Short;
1168 0fc65b37 2004-03-21 devnull m->u.clientKeyExchange.key = makebytes(p, nn);
1169 0fc65b37 2004-03-21 devnull n -= nn;
1170 0fc65b37 2004-03-21 devnull break;
1171 0fc65b37 2004-03-21 devnull case HFinished:
1172 0fc65b37 2004-03-21 devnull m->u.finished.n = c->finished.n;
1173 0fc65b37 2004-03-21 devnull if(n < m->u.finished.n)
1174 0fc65b37 2004-03-21 devnull goto Short;
1175 0fc65b37 2004-03-21 devnull memmove(m->u.finished.verify, p, m->u.finished.n);
1176 0fc65b37 2004-03-21 devnull n -= m->u.finished.n;
1177 0fc65b37 2004-03-21 devnull break;
1178 0fc65b37 2004-03-21 devnull }
1179 0fc65b37 2004-03-21 devnull
1180 0fc65b37 2004-03-21 devnull if(type != HClientHello && n != 0)
1181 0fc65b37 2004-03-21 devnull goto Short;
1182 0fc65b37 2004-03-21 devnull Ok:
1183 0fc65b37 2004-03-21 devnull if(c->trace){
1184 0fc65b37 2004-03-21 devnull char buf[8000];
1185 0fc65b37 2004-03-21 devnull c->trace("recv %s", msgPrint(buf, sizeof buf, m));
1186 0fc65b37 2004-03-21 devnull }
1187 0fc65b37 2004-03-21 devnull return 1;
1188 0fc65b37 2004-03-21 devnull Short:
1189 0fc65b37 2004-03-21 devnull tlsError(c, EDecodeError, "handshake message has invalid length");
1190 0fc65b37 2004-03-21 devnull Err:
1191 0fc65b37 2004-03-21 devnull msgClear(m);
1192 0fc65b37 2004-03-21 devnull return 0;
1193 0fc65b37 2004-03-21 devnull }
1194 0fc65b37 2004-03-21 devnull
1195 0fc65b37 2004-03-21 devnull static void
1196 0fc65b37 2004-03-21 devnull msgClear(Msg *m)
1197 0fc65b37 2004-03-21 devnull {
1198 0fc65b37 2004-03-21 devnull int i;
1199 0fc65b37 2004-03-21 devnull
1200 0fc65b37 2004-03-21 devnull switch(m->tag) {
1201 0fc65b37 2004-03-21 devnull default:
1202 0fc65b37 2004-03-21 devnull sysfatal("msgClear: unknown message type: %d\n", m->tag);
1203 0fc65b37 2004-03-21 devnull case HHelloRequest:
1204 0fc65b37 2004-03-21 devnull break;
1205 0fc65b37 2004-03-21 devnull case HClientHello:
1206 0fc65b37 2004-03-21 devnull freebytes(m->u.clientHello.sid);
1207 0fc65b37 2004-03-21 devnull freeints(m->u.clientHello.ciphers);
1208 0fc65b37 2004-03-21 devnull freebytes(m->u.clientHello.compressors);
1209 0fc65b37 2004-03-21 devnull break;
1210 0fc65b37 2004-03-21 devnull case HServerHello:
1211 0fc65b37 2004-03-21 devnull freebytes(m->u.clientHello.sid);
1212 0fc65b37 2004-03-21 devnull break;
1213 0fc65b37 2004-03-21 devnull case HCertificate:
1214 0fc65b37 2004-03-21 devnull for(i=0; i<m->u.certificate.ncert; i++)
1215 0fc65b37 2004-03-21 devnull freebytes(m->u.certificate.certs[i]);
1216 0fc65b37 2004-03-21 devnull free(m->u.certificate.certs);
1217 0fc65b37 2004-03-21 devnull break;
1218 0fc65b37 2004-03-21 devnull case HCertificateRequest:
1219 0fc65b37 2004-03-21 devnull freebytes(m->u.certificateRequest.types);
1220 0fc65b37 2004-03-21 devnull for(i=0; i<m->u.certificateRequest.nca; i++)
1221 0fc65b37 2004-03-21 devnull freebytes(m->u.certificateRequest.cas[i]);
1222 0fc65b37 2004-03-21 devnull free(m->u.certificateRequest.cas);
1223 0fc65b37 2004-03-21 devnull break;
1224 0fc65b37 2004-03-21 devnull case HServerHelloDone:
1225 0fc65b37 2004-03-21 devnull break;
1226 0fc65b37 2004-03-21 devnull case HClientKeyExchange:
1227 0fc65b37 2004-03-21 devnull freebytes(m->u.clientKeyExchange.key);
1228 0fc65b37 2004-03-21 devnull break;
1229 0fc65b37 2004-03-21 devnull case HFinished:
1230 0fc65b37 2004-03-21 devnull break;
1231 0fc65b37 2004-03-21 devnull }
1232 0fc65b37 2004-03-21 devnull memset(m, 0, sizeof(Msg));
1233 0fc65b37 2004-03-21 devnull }
1234 0fc65b37 2004-03-21 devnull
1235 0fc65b37 2004-03-21 devnull static char *
1236 0fc65b37 2004-03-21 devnull bytesPrint(char *bs, char *be, char *s0, Bytes *b, char *s1)
1237 0fc65b37 2004-03-21 devnull {
1238 0fc65b37 2004-03-21 devnull int i;
1239 0fc65b37 2004-03-21 devnull
1240 0fc65b37 2004-03-21 devnull if(s0)
1241 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%s", s0);
1242 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "[");
1243 0fc65b37 2004-03-21 devnull if(b == nil)
1244 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "nil");
1245 0fc65b37 2004-03-21 devnull else
1246 0fc65b37 2004-03-21 devnull for(i=0; i<b->len; i++)
1247 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%.2x ", b->data[i]);
1248 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "]");
1249 0fc65b37 2004-03-21 devnull if(s1)
1250 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%s", s1);
1251 0fc65b37 2004-03-21 devnull return bs;
1252 0fc65b37 2004-03-21 devnull }
1253 0fc65b37 2004-03-21 devnull
1254 0fc65b37 2004-03-21 devnull static char *
1255 0fc65b37 2004-03-21 devnull intsPrint(char *bs, char *be, char *s0, Ints *b, char *s1)
1256 0fc65b37 2004-03-21 devnull {
1257 0fc65b37 2004-03-21 devnull int i;
1258 0fc65b37 2004-03-21 devnull
1259 0fc65b37 2004-03-21 devnull if(s0)
1260 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%s", s0);
1261 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "[");
1262 0fc65b37 2004-03-21 devnull if(b == nil)
1263 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "nil");
1264 0fc65b37 2004-03-21 devnull else
1265 0fc65b37 2004-03-21 devnull for(i=0; i<b->len; i++)
1266 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%x ", b->data[i]);
1267 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "]");
1268 0fc65b37 2004-03-21 devnull if(s1)
1269 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%s", s1);
1270 0fc65b37 2004-03-21 devnull return bs;
1271 0fc65b37 2004-03-21 devnull }
1272 0fc65b37 2004-03-21 devnull
1273 0fc65b37 2004-03-21 devnull static char*
1274 0fc65b37 2004-03-21 devnull msgPrint(char *buf, int n, Msg *m)
1275 0fc65b37 2004-03-21 devnull {
1276 0fc65b37 2004-03-21 devnull int i;
1277 0fc65b37 2004-03-21 devnull char *bs = buf, *be = buf+n;
1278 0fc65b37 2004-03-21 devnull
1279 0fc65b37 2004-03-21 devnull switch(m->tag) {
1280 0fc65b37 2004-03-21 devnull default:
1281 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "unknown %d\n", m->tag);
1282 0fc65b37 2004-03-21 devnull break;
1283 0fc65b37 2004-03-21 devnull case HClientHello:
1284 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "ClientHello\n");
1285 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\tversion: %.4x\n", m->u.clientHello.version);
1286 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\trandom: ");
1287 0fc65b37 2004-03-21 devnull for(i=0; i<RandomSize; i++)
1288 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%.2x", m->u.clientHello.random[i]);
1289 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\n");
1290 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\tsid: ", m->u.clientHello.sid, "\n");
1291 0fc65b37 2004-03-21 devnull bs = intsPrint(bs, be, "\tciphers: ", m->u.clientHello.ciphers, "\n");
1292 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\tcompressors: ", m->u.clientHello.compressors, "\n");
1293 0fc65b37 2004-03-21 devnull break;
1294 0fc65b37 2004-03-21 devnull case HServerHello:
1295 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "ServerHello\n");
1296 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\tversion: %.4x\n", m->u.serverHello.version);
1297 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\trandom: ");
1298 0fc65b37 2004-03-21 devnull for(i=0; i<RandomSize; i++)
1299 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%.2x", m->u.serverHello.random[i]);
1300 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\n");
1301 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\tsid: ", m->u.serverHello.sid, "\n");
1302 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\tcipher: %.4x\n", m->u.serverHello.cipher);
1303 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\tcompressor: %.2x\n", m->u.serverHello.compressor);
1304 0fc65b37 2004-03-21 devnull break;
1305 0fc65b37 2004-03-21 devnull case HCertificate:
1306 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "Certificate\n");
1307 0fc65b37 2004-03-21 devnull for(i=0; i<m->u.certificate.ncert; i++)
1308 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\t", m->u.certificate.certs[i], "\n");
1309 0fc65b37 2004-03-21 devnull break;
1310 0fc65b37 2004-03-21 devnull case HCertificateRequest:
1311 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "CertificateRequest\n");
1312 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\ttypes: ", m->u.certificateRequest.types, "\n");
1313 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\tcertificateauthorities\n");
1314 0fc65b37 2004-03-21 devnull for(i=0; i<m->u.certificateRequest.nca; i++)
1315 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\t\t", m->u.certificateRequest.cas[i], "\n");
1316 0fc65b37 2004-03-21 devnull break;
1317 0fc65b37 2004-03-21 devnull case HServerHelloDone:
1318 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "ServerHelloDone\n");
1319 0fc65b37 2004-03-21 devnull break;
1320 0fc65b37 2004-03-21 devnull case HClientKeyExchange:
1321 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "HClientKeyExchange\n");
1322 0fc65b37 2004-03-21 devnull bs = bytesPrint(bs, be, "\tkey: ", m->u.clientKeyExchange.key, "\n");
1323 0fc65b37 2004-03-21 devnull break;
1324 0fc65b37 2004-03-21 devnull case HFinished:
1325 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "HFinished\n");
1326 0fc65b37 2004-03-21 devnull for(i=0; i<m->u.finished.n; i++)
1327 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "%.2x", m->u.finished.verify[i]);
1328 0fc65b37 2004-03-21 devnull bs = seprint(bs, be, "\n");
1329 0fc65b37 2004-03-21 devnull break;
1330 0fc65b37 2004-03-21 devnull }
1331 0fc65b37 2004-03-21 devnull USED(bs);
1332 0fc65b37 2004-03-21 devnull return buf;
1333 0fc65b37 2004-03-21 devnull }
1334 0fc65b37 2004-03-21 devnull
1335 0fc65b37 2004-03-21 devnull static void
1336 0fc65b37 2004-03-21 devnull tlsError(TlsConnection *c, int err, char *fmt, ...)
1337 0fc65b37 2004-03-21 devnull {
1338 0fc65b37 2004-03-21 devnull char msg[512];
1339 0fc65b37 2004-03-21 devnull va_list arg;
1340 0fc65b37 2004-03-21 devnull
1341 0fc65b37 2004-03-21 devnull va_start(arg, fmt);
1342 0fc65b37 2004-03-21 devnull vseprint(msg, msg+sizeof(msg), fmt, arg);
1343 0fc65b37 2004-03-21 devnull va_end(arg);
1344 0fc65b37 2004-03-21 devnull if(c->trace)
1345 0fc65b37 2004-03-21 devnull c->trace("tlsError: %s\n", msg);
1346 0fc65b37 2004-03-21 devnull else if(c->erred)
1347 0fc65b37 2004-03-21 devnull fprint(2, "double error: %r, %s", msg);
1348 0fc65b37 2004-03-21 devnull else
1349 0fc65b37 2004-03-21 devnull werrstr("tls: local %s", msg);
1350 0fc65b37 2004-03-21 devnull c->erred = 1;
1351 0fc65b37 2004-03-21 devnull fprint(c->ctl, "alert %d", err);
1352 0fc65b37 2004-03-21 devnull }
1353 0fc65b37 2004-03-21 devnull
1354 0fc65b37 2004-03-21 devnull // commit to specific version number
1355 0fc65b37 2004-03-21 devnull static int
1356 0fc65b37 2004-03-21 devnull setVersion(TlsConnection *c, int version)
1357 0fc65b37 2004-03-21 devnull {
1358 0fc65b37 2004-03-21 devnull if(c->verset || version > MaxProtoVersion || version < MinProtoVersion)
1359 0fc65b37 2004-03-21 devnull return -1;
1360 0fc65b37 2004-03-21 devnull if(version > c->version)
1361 0fc65b37 2004-03-21 devnull version = c->version;
1362 0fc65b37 2004-03-21 devnull if(version == SSL3Version) {
1363 0fc65b37 2004-03-21 devnull c->version = version;
1364 0fc65b37 2004-03-21 devnull c->finished.n = SSL3FinishedLen;
1365 0fc65b37 2004-03-21 devnull }else if(version == TLSVersion){
1366 0fc65b37 2004-03-21 devnull c->version = version;
1367 0fc65b37 2004-03-21 devnull c->finished.n = TLSFinishedLen;
1368 0fc65b37 2004-03-21 devnull }else
1369 0fc65b37 2004-03-21 devnull return -1;
1370 0fc65b37 2004-03-21 devnull c->verset = 1;
1371 0fc65b37 2004-03-21 devnull return fprint(c->ctl, "version 0x%x", version);
1372 0fc65b37 2004-03-21 devnull }
1373 0fc65b37 2004-03-21 devnull
1374 0fc65b37 2004-03-21 devnull // confirm that received Finished message matches the expected value
1375 0fc65b37 2004-03-21 devnull static int
1376 0fc65b37 2004-03-21 devnull finishedMatch(TlsConnection *c, Finished *f)
1377 0fc65b37 2004-03-21 devnull {
1378 0fc65b37 2004-03-21 devnull return memcmp(f->verify, c->finished.verify, f->n) == 0;
1379 0fc65b37 2004-03-21 devnull }
1380 0fc65b37 2004-03-21 devnull
1381 0fc65b37 2004-03-21 devnull // free memory associated with TlsConnection struct
1382 0fc65b37 2004-03-21 devnull // (but don't close the TLS channel itself)
1383 0fc65b37 2004-03-21 devnull static void
1384 0fc65b37 2004-03-21 devnull tlsConnectionFree(TlsConnection *c)
1385 0fc65b37 2004-03-21 devnull {
1386 0fc65b37 2004-03-21 devnull tlsSecClose(c->sec);
1387 0fc65b37 2004-03-21 devnull freebytes(c->sid);
1388 0fc65b37 2004-03-21 devnull freebytes(c->cert);
1389 0fc65b37 2004-03-21 devnull memset(c, 0, sizeof(c));
1390 0fc65b37 2004-03-21 devnull free(c);
1391 0fc65b37 2004-03-21 devnull }
1392 0fc65b37 2004-03-21 devnull
1393 0fc65b37 2004-03-21 devnull
1394 0fc65b37 2004-03-21 devnull //================= cipher choices ========================
1395 0fc65b37 2004-03-21 devnull
1396 0fc65b37 2004-03-21 devnull static int weakCipher[CipherMax] =
1397 0fc65b37 2004-03-21 devnull {
1398 0fc65b37 2004-03-21 devnull 1, /* TLS_NULL_WITH_NULL_NULL */
1399 0fc65b37 2004-03-21 devnull 1, /* TLS_RSA_WITH_NULL_MD5 */
1400 0fc65b37 2004-03-21 devnull 1, /* TLS_RSA_WITH_NULL_SHA */
1401 0fc65b37 2004-03-21 devnull 1, /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
1402 0fc65b37 2004-03-21 devnull 0, /* TLS_RSA_WITH_RC4_128_MD5 */
1403 0fc65b37 2004-03-21 devnull 0, /* TLS_RSA_WITH_RC4_128_SHA */
1404 0fc65b37 2004-03-21 devnull 1, /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
1405 0fc65b37 2004-03-21 devnull 0, /* TLS_RSA_WITH_IDEA_CBC_SHA */
1406 0fc65b37 2004-03-21 devnull 1, /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
1407 0fc65b37 2004-03-21 devnull 0, /* TLS_RSA_WITH_DES_CBC_SHA */
1408 0fc65b37 2004-03-21 devnull 0, /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
1409 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
1410 0fc65b37 2004-03-21 devnull 0, /* TLS_DH_DSS_WITH_DES_CBC_SHA */
1411 0fc65b37 2004-03-21 devnull 0, /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
1412 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
1413 0fc65b37 2004-03-21 devnull 0, /* TLS_DH_RSA_WITH_DES_CBC_SHA */
1414 0fc65b37 2004-03-21 devnull 0, /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
1415 0fc65b37 2004-03-21 devnull 1, /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
1416 0fc65b37 2004-03-21 devnull 0, /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
1417 0fc65b37 2004-03-21 devnull 0, /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
1418 0fc65b37 2004-03-21 devnull 1, /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
1419 0fc65b37 2004-03-21 devnull 0, /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
1420 0fc65b37 2004-03-21 devnull 0, /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
1421 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
1422 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_anon_WITH_RC4_128_MD5 */
1423 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
1424 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_anon_WITH_DES_CBC_SHA */
1425 0fc65b37 2004-03-21 devnull 1, /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
1426 0fc65b37 2004-03-21 devnull };
1427 0fc65b37 2004-03-21 devnull
1428 0fc65b37 2004-03-21 devnull static int
1429 0fc65b37 2004-03-21 devnull setAlgs(TlsConnection *c, int a)
1430 0fc65b37 2004-03-21 devnull {
1431 0fc65b37 2004-03-21 devnull int i;
1432 0fc65b37 2004-03-21 devnull
1433 0fc65b37 2004-03-21 devnull for(i = 0; i < nelem(cipherAlgs); i++){
1434 0fc65b37 2004-03-21 devnull if(cipherAlgs[i].tlsid == a){
1435 0fc65b37 2004-03-21 devnull c->enc = cipherAlgs[i].enc;
1436 0fc65b37 2004-03-21 devnull c->digest = cipherAlgs[i].digest;
1437 0fc65b37 2004-03-21 devnull c->nsecret = cipherAlgs[i].nsecret;
1438 0fc65b37 2004-03-21 devnull if(c->nsecret > MaxKeyData)
1439 0fc65b37 2004-03-21 devnull return 0;
1440 0fc65b37 2004-03-21 devnull return 1;
1441 0fc65b37 2004-03-21 devnull }
1442 0fc65b37 2004-03-21 devnull }
1443 0fc65b37 2004-03-21 devnull return 0;
1444 0fc65b37 2004-03-21 devnull }
1445 0fc65b37 2004-03-21 devnull
1446 0fc65b37 2004-03-21 devnull static int
1447 0fc65b37 2004-03-21 devnull okCipher(Ints *cv)
1448 0fc65b37 2004-03-21 devnull {
1449 0fc65b37 2004-03-21 devnull int weak, i, j, c;
1450 0fc65b37 2004-03-21 devnull
1451 0fc65b37 2004-03-21 devnull weak = 1;
1452 0fc65b37 2004-03-21 devnull for(i = 0; i < cv->len; i++) {
1453 0fc65b37 2004-03-21 devnull c = cv->data[i];
1454 0fc65b37 2004-03-21 devnull if(c >= CipherMax)
1455 0fc65b37 2004-03-21 devnull weak = 0;
1456 0fc65b37 2004-03-21 devnull else
1457 0fc65b37 2004-03-21 devnull weak &= weakCipher[c];
1458 0fc65b37 2004-03-21 devnull for(j = 0; j < nelem(cipherAlgs); j++)
1459 0fc65b37 2004-03-21 devnull if(cipherAlgs[j].ok && cipherAlgs[j].tlsid == c)
1460 0fc65b37 2004-03-21 devnull return c;
1461 0fc65b37 2004-03-21 devnull }
1462 0fc65b37 2004-03-21 devnull if(weak)
1463 0fc65b37 2004-03-21 devnull return -2;
1464 0fc65b37 2004-03-21 devnull return -1;
1465 0fc65b37 2004-03-21 devnull }
1466 0fc65b37 2004-03-21 devnull
1467 0fc65b37 2004-03-21 devnull static int
1468 0fc65b37 2004-03-21 devnull okCompression(Bytes *cv)
1469 0fc65b37 2004-03-21 devnull {
1470 0fc65b37 2004-03-21 devnull int i, j, c;
1471 0fc65b37 2004-03-21 devnull
1472 0fc65b37 2004-03-21 devnull for(i = 0; i < cv->len; i++) {
1473 0fc65b37 2004-03-21 devnull c = cv->data[i];
1474 0fc65b37 2004-03-21 devnull for(j = 0; j < nelem(compressors); j++) {
1475 0fc65b37 2004-03-21 devnull if(compressors[j] == c)
1476 0fc65b37 2004-03-21 devnull return c;
1477 0fc65b37 2004-03-21 devnull }
1478 0fc65b37 2004-03-21 devnull }
1479 0fc65b37 2004-03-21 devnull return -1;
1480 0fc65b37 2004-03-21 devnull }
1481 0fc65b37 2004-03-21 devnull
1482 0fc65b37 2004-03-21 devnull static Lock ciphLock;
1483 0fc65b37 2004-03-21 devnull static int nciphers;
1484 0fc65b37 2004-03-21 devnull
1485 0fc65b37 2004-03-21 devnull static int
1486 0fc65b37 2004-03-21 devnull initCiphers(void)
1487 0fc65b37 2004-03-21 devnull {
1488 0fc65b37 2004-03-21 devnull enum {MaxAlgF = 1024, MaxAlgs = 10};
1489 0fc65b37 2004-03-21 devnull char s[MaxAlgF], *flds[MaxAlgs];
1490 0fc65b37 2004-03-21 devnull int i, j, n, ok;
1491 0fc65b37 2004-03-21 devnull
1492 0fc65b37 2004-03-21 devnull lock(&ciphLock);
1493 0fc65b37 2004-03-21 devnull if(nciphers){
1494 0fc65b37 2004-03-21 devnull unlock(&ciphLock);
1495 0fc65b37 2004-03-21 devnull return nciphers;
1496 0fc65b37 2004-03-21 devnull }
1497 0fc65b37 2004-03-21 devnull j = open("#a/tls/encalgs", OREAD);
1498 0fc65b37 2004-03-21 devnull if(j < 0){
1499 0fc65b37 2004-03-21 devnull werrstr("can't open #a/tls/encalgs: %r");
1500 0fc65b37 2004-03-21 devnull return 0;
1501 0fc65b37 2004-03-21 devnull }
1502 0fc65b37 2004-03-21 devnull n = read(j, s, MaxAlgF-1);
1503 0fc65b37 2004-03-21 devnull close(j);
1504 0fc65b37 2004-03-21 devnull if(n <= 0){
1505 0fc65b37 2004-03-21 devnull werrstr("nothing in #a/tls/encalgs: %r");
1506 0fc65b37 2004-03-21 devnull return 0;
1507 0fc65b37 2004-03-21 devnull }
1508 0fc65b37 2004-03-21 devnull s[n] = 0;
1509 0fc65b37 2004-03-21 devnull n = getfields(s, flds, MaxAlgs, 1, " \t\r\n");
1510 0fc65b37 2004-03-21 devnull for(i = 0; i < nelem(cipherAlgs); i++){
1511 0fc65b37 2004-03-21 devnull ok = 0;
1512 0fc65b37 2004-03-21 devnull for(j = 0; j < n; j++){
1513 0fc65b37 2004-03-21 devnull if(strcmp(cipherAlgs[i].enc, flds[j]) == 0){
1514 0fc65b37 2004-03-21 devnull ok = 1;
1515 0fc65b37 2004-03-21 devnull break;
1516 0fc65b37 2004-03-21 devnull }
1517 0fc65b37 2004-03-21 devnull }
1518 0fc65b37 2004-03-21 devnull cipherAlgs[i].ok = ok;
1519 0fc65b37 2004-03-21 devnull }
1520 0fc65b37 2004-03-21 devnull
1521 0fc65b37 2004-03-21 devnull j = open("#a/tls/hashalgs", OREAD);
1522 0fc65b37 2004-03-21 devnull if(j < 0){
1523 0fc65b37 2004-03-21 devnull werrstr("can't open #a/tls/hashalgs: %r");
1524 0fc65b37 2004-03-21 devnull return 0;
1525 0fc65b37 2004-03-21 devnull }
1526 0fc65b37 2004-03-21 devnull n = read(j, s, MaxAlgF-1);
1527 0fc65b37 2004-03-21 devnull close(j);
1528 0fc65b37 2004-03-21 devnull if(n <= 0){
1529 0fc65b37 2004-03-21 devnull werrstr("nothing in #a/tls/hashalgs: %r");
1530 0fc65b37 2004-03-21 devnull return 0;
1531 0fc65b37 2004-03-21 devnull }
1532 0fc65b37 2004-03-21 devnull s[n] = 0;
1533 0fc65b37 2004-03-21 devnull n = getfields(s, flds, MaxAlgs, 1, " \t\r\n");
1534 0fc65b37 2004-03-21 devnull for(i = 0; i < nelem(cipherAlgs); i++){
1535 0fc65b37 2004-03-21 devnull ok = 0;
1536 0fc65b37 2004-03-21 devnull for(j = 0; j < n; j++){
1537 0fc65b37 2004-03-21 devnull if(strcmp(cipherAlgs[i].digest, flds[j]) == 0){
1538 0fc65b37 2004-03-21 devnull ok = 1;
1539 0fc65b37 2004-03-21 devnull break;
1540 0fc65b37 2004-03-21 devnull }
1541 0fc65b37 2004-03-21 devnull }
1542 0fc65b37 2004-03-21 devnull cipherAlgs[i].ok &= ok;
1543 0fc65b37 2004-03-21 devnull if(cipherAlgs[i].ok)
1544 0fc65b37 2004-03-21 devnull nciphers++;
1545 0fc65b37 2004-03-21 devnull }
1546 0fc65b37 2004-03-21 devnull unlock(&ciphLock);
1547 0fc65b37 2004-03-21 devnull return nciphers;
1548 0fc65b37 2004-03-21 devnull }
1549 0fc65b37 2004-03-21 devnull
1550 0fc65b37 2004-03-21 devnull static Ints*
1551 0fc65b37 2004-03-21 devnull makeciphers(void)
1552 0fc65b37 2004-03-21 devnull {
1553 0fc65b37 2004-03-21 devnull Ints *is;
1554 0fc65b37 2004-03-21 devnull int i, j;
1555 0fc65b37 2004-03-21 devnull
1556 0fc65b37 2004-03-21 devnull is = newints(nciphers);
1557 0fc65b37 2004-03-21 devnull j = 0;
1558 0fc65b37 2004-03-21 devnull for(i = 0; i < nelem(cipherAlgs); i++){
1559 0fc65b37 2004-03-21 devnull if(cipherAlgs[i].ok)
1560 0fc65b37 2004-03-21 devnull is->data[j++] = cipherAlgs[i].tlsid;
1561 0fc65b37 2004-03-21 devnull }
1562 0fc65b37 2004-03-21 devnull return is;
1563 0fc65b37 2004-03-21 devnull }
1564 0fc65b37 2004-03-21 devnull
1565 0fc65b37 2004-03-21 devnull
1566 0fc65b37 2004-03-21 devnull
1567 0fc65b37 2004-03-21 devnull //================= security functions ========================
1568 0fc65b37 2004-03-21 devnull
1569 0fc65b37 2004-03-21 devnull // given X.509 certificate, set up connection to factotum
1570 0fc65b37 2004-03-21 devnull // for using corresponding private key
1571 0fc65b37 2004-03-21 devnull static AuthRpc*
1572 0fc65b37 2004-03-21 devnull factotum_rsa_open(uchar *cert, int certlen)
1573 0fc65b37 2004-03-21 devnull {
1574 0fc65b37 2004-03-21 devnull int afd;
1575 0fc65b37 2004-03-21 devnull char *s;
1576 0fc65b37 2004-03-21 devnull mpint *pub = nil;
1577 0fc65b37 2004-03-21 devnull RSApub *rsapub;
1578 0fc65b37 2004-03-21 devnull AuthRpc *rpc;
1579 0fc65b37 2004-03-21 devnull
1580 0fc65b37 2004-03-21 devnull // start talking to factotum
1581 0fc65b37 2004-03-21 devnull if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
1582 0fc65b37 2004-03-21 devnull return nil;
1583 0fc65b37 2004-03-21 devnull if((rpc = auth_allocrpc(afd)) == nil){
1584 0fc65b37 2004-03-21 devnull close(afd);
1585 0fc65b37 2004-03-21 devnull return nil;
1586 0fc65b37 2004-03-21 devnull }
1587 0fc65b37 2004-03-21 devnull s = "proto=rsa service=tls role=client";
1588 0fc65b37 2004-03-21 devnull if(auth_rpc(rpc, "start", s, strlen(s)) != ARok){
1589 0fc65b37 2004-03-21 devnull factotum_rsa_close(rpc);
1590 0fc65b37 2004-03-21 devnull return nil;
1591 0fc65b37 2004-03-21 devnull }
1592 0fc65b37 2004-03-21 devnull
1593 0fc65b37 2004-03-21 devnull // roll factotum keyring around to match certificate
1594 0fc65b37 2004-03-21 devnull rsapub = X509toRSApub(cert, certlen, nil, 0);
1595 0fc65b37 2004-03-21 devnull while(1){
1596 0fc65b37 2004-03-21 devnull if(auth_rpc(rpc, "read", nil, 0) != ARok){
1597 0fc65b37 2004-03-21 devnull factotum_rsa_close(rpc);
1598 0fc65b37 2004-03-21 devnull rpc = nil;
1599 0fc65b37 2004-03-21 devnull goto done;
1600 0fc65b37 2004-03-21 devnull }
1601 0fc65b37 2004-03-21 devnull pub = strtomp(rpc->arg, nil, 16, nil);
1602 0fc65b37 2004-03-21 devnull assert(pub != nil);
1603 0fc65b37 2004-03-21 devnull if(mpcmp(pub,rsapub->n) == 0)
1604 0fc65b37 2004-03-21 devnull break;
1605 0fc65b37 2004-03-21 devnull }
1606 0fc65b37 2004-03-21 devnull done:
1607 0fc65b37 2004-03-21 devnull mpfree(pub);
1608 0fc65b37 2004-03-21 devnull rsapubfree(rsapub);
1609 0fc65b37 2004-03-21 devnull return rpc;
1610 0fc65b37 2004-03-21 devnull }
1611 0fc65b37 2004-03-21 devnull
1612 0fc65b37 2004-03-21 devnull static mpint*
1613 0fc65b37 2004-03-21 devnull factotum_rsa_decrypt(AuthRpc *rpc, mpint *cipher)
1614 0fc65b37 2004-03-21 devnull {
1615 0fc65b37 2004-03-21 devnull char *p;
1616 0fc65b37 2004-03-21 devnull int rv;
1617 0fc65b37 2004-03-21 devnull
1618 0fc65b37 2004-03-21 devnull if((p = mptoa(cipher, 16, nil, 0)) == nil)
1619 0fc65b37 2004-03-21 devnull return nil;
1620 0fc65b37 2004-03-21 devnull rv = auth_rpc(rpc, "write", p, strlen(p));
1621 0fc65b37 2004-03-21 devnull free(p);
1622 0fc65b37 2004-03-21 devnull if(rv != ARok || auth_rpc(rpc, "read", nil, 0) != ARok)
1623 0fc65b37 2004-03-21 devnull return nil;
1624 0fc65b37 2004-03-21 devnull mpfree(cipher);
1625 0fc65b37 2004-03-21 devnull return strtomp(rpc->arg, nil, 16, nil);
1626 0fc65b37 2004-03-21 devnull }
1627 0fc65b37 2004-03-21 devnull
1628 0fc65b37 2004-03-21 devnull static void
1629 0fc65b37 2004-03-21 devnull factotum_rsa_close(AuthRpc*rpc)
1630 0fc65b37 2004-03-21 devnull {
1631 0fc65b37 2004-03-21 devnull if(!rpc)
1632 0fc65b37 2004-03-21 devnull return;
1633 0fc65b37 2004-03-21 devnull close(rpc->afd);
1634 0fc65b37 2004-03-21 devnull auth_freerpc(rpc);
1635 0fc65b37 2004-03-21 devnull }
1636 0fc65b37 2004-03-21 devnull
1637 0fc65b37 2004-03-21 devnull static void
1638 0fc65b37 2004-03-21 devnull tlsPmd5(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
1639 0fc65b37 2004-03-21 devnull {
1640 0fc65b37 2004-03-21 devnull uchar ai[MD5dlen], tmp[MD5dlen];
1641 0fc65b37 2004-03-21 devnull int i, n;
1642 0fc65b37 2004-03-21 devnull MD5state *s;
1643 0fc65b37 2004-03-21 devnull
1644 0fc65b37 2004-03-21 devnull // generate a1
1645 0fc65b37 2004-03-21 devnull s = hmac_md5(label, nlabel, key, nkey, nil, nil);
1646 0fc65b37 2004-03-21 devnull s = hmac_md5(seed0, nseed0, key, nkey, nil, s);
1647 0fc65b37 2004-03-21 devnull hmac_md5(seed1, nseed1, key, nkey, ai, s);
1648 0fc65b37 2004-03-21 devnull
1649 0fc65b37 2004-03-21 devnull while(nbuf > 0) {
1650 0fc65b37 2004-03-21 devnull s = hmac_md5(ai, MD5dlen, key, nkey, nil, nil);
1651 0fc65b37 2004-03-21 devnull s = hmac_md5(label, nlabel, key, nkey, nil, s);
1652 0fc65b37 2004-03-21 devnull s = hmac_md5(seed0, nseed0, key, nkey, nil, s);
1653 0fc65b37 2004-03-21 devnull hmac_md5(seed1, nseed1, key, nkey, tmp, s);
1654 0fc65b37 2004-03-21 devnull n = MD5dlen;
1655 0fc65b37 2004-03-21 devnull if(n > nbuf)
1656 0fc65b37 2004-03-21 devnull n = nbuf;
1657 0fc65b37 2004-03-21 devnull for(i = 0; i < n; i++)
1658 0fc65b37 2004-03-21 devnull buf[i] ^= tmp[i];
1659 0fc65b37 2004-03-21 devnull buf += n;
1660 0fc65b37 2004-03-21 devnull nbuf -= n;
1661 0fc65b37 2004-03-21 devnull hmac_md5(ai, MD5dlen, key, nkey, tmp, nil);
1662 0fc65b37 2004-03-21 devnull memmove(ai, tmp, MD5dlen);
1663 0fc65b37 2004-03-21 devnull }
1664 0fc65b37 2004-03-21 devnull }
1665 0fc65b37 2004-03-21 devnull
1666 0fc65b37 2004-03-21 devnull static void
1667 0fc65b37 2004-03-21 devnull tlsPsha1(uchar *buf, int nbuf, uchar *key, int nkey, uchar *label, int nlabel, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
1668 0fc65b37 2004-03-21 devnull {
1669 0fc65b37 2004-03-21 devnull uchar ai[SHA1dlen], tmp[SHA1dlen];
1670 0fc65b37 2004-03-21 devnull int i, n;
1671 0fc65b37 2004-03-21 devnull SHAstate *s;
1672 0fc65b37 2004-03-21 devnull
1673 0fc65b37 2004-03-21 devnull // generate a1
1674 0fc65b37 2004-03-21 devnull s = hmac_sha1(label, nlabel, key, nkey, nil, nil);
1675 0fc65b37 2004-03-21 devnull s = hmac_sha1(seed0, nseed0, key, nkey, nil, s);
1676 0fc65b37 2004-03-21 devnull hmac_sha1(seed1, nseed1, key, nkey, ai, s);
1677 0fc65b37 2004-03-21 devnull
1678 0fc65b37 2004-03-21 devnull while(nbuf > 0) {
1679 0fc65b37 2004-03-21 devnull s = hmac_sha1(ai, SHA1dlen, key, nkey, nil, nil);
1680 0fc65b37 2004-03-21 devnull s = hmac_sha1(label, nlabel, key, nkey, nil, s);
1681 0fc65b37 2004-03-21 devnull s = hmac_sha1(seed0, nseed0, key, nkey, nil, s);
1682 0fc65b37 2004-03-21 devnull hmac_sha1(seed1, nseed1, key, nkey, tmp, s);
1683 0fc65b37 2004-03-21 devnull n = SHA1dlen;
1684 0fc65b37 2004-03-21 devnull if(n > nbuf)
1685 0fc65b37 2004-03-21 devnull n = nbuf;
1686 0fc65b37 2004-03-21 devnull for(i = 0; i < n; i++)
1687 0fc65b37 2004-03-21 devnull buf[i] ^= tmp[i];
1688 0fc65b37 2004-03-21 devnull buf += n;
1689 0fc65b37 2004-03-21 devnull nbuf -= n;
1690 0fc65b37 2004-03-21 devnull hmac_sha1(ai, SHA1dlen, key, nkey, tmp, nil);
1691 0fc65b37 2004-03-21 devnull memmove(ai, tmp, SHA1dlen);
1692 0fc65b37 2004-03-21 devnull }
1693 0fc65b37 2004-03-21 devnull }
1694 0fc65b37 2004-03-21 devnull
1695 0fc65b37 2004-03-21 devnull // fill buf with md5(args)^sha1(args)
1696 0fc65b37 2004-03-21 devnull static void
1697 0fc65b37 2004-03-21 devnull tlsPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
1698 0fc65b37 2004-03-21 devnull {
1699 0fc65b37 2004-03-21 devnull int i;
1700 0fc65b37 2004-03-21 devnull int nlabel = strlen(label);
1701 0fc65b37 2004-03-21 devnull int n = (nkey + 1) >> 1;
1702 0fc65b37 2004-03-21 devnull
1703 0fc65b37 2004-03-21 devnull for(i = 0; i < nbuf; i++)
1704 0fc65b37 2004-03-21 devnull buf[i] = 0;
1705 0fc65b37 2004-03-21 devnull tlsPmd5(buf, nbuf, key, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);
1706 0fc65b37 2004-03-21 devnull tlsPsha1(buf, nbuf, key+nkey-n, n, (uchar*)label, nlabel, seed0, nseed0, seed1, nseed1);
1707 0fc65b37 2004-03-21 devnull }
1708 0fc65b37 2004-03-21 devnull
1709 0fc65b37 2004-03-21 devnull /*
1710 0fc65b37 2004-03-21 devnull * for setting server session id's
1711 0fc65b37 2004-03-21 devnull */
1712 0fc65b37 2004-03-21 devnull static Lock sidLock;
1713 0fc65b37 2004-03-21 devnull static long maxSid = 1;
1714 0fc65b37 2004-03-21 devnull
1715 0fc65b37 2004-03-21 devnull /* the keys are verified to have the same public components
1716 0fc65b37 2004-03-21 devnull * and to function correctly with pkcs 1 encryption and decryption. */
1717 0fc65b37 2004-03-21 devnull static TlsSec*
1718 0fc65b37 2004-03-21 devnull tlsSecInits(int cvers, uchar *csid, int ncsid, uchar *crandom, uchar *ssid, int *nssid, uchar *srandom)
1719 0fc65b37 2004-03-21 devnull {
1720 0fc65b37 2004-03-21 devnull TlsSec *sec = emalloc(sizeof(*sec));
1721 0fc65b37 2004-03-21 devnull
1722 0fc65b37 2004-03-21 devnull USED(csid); USED(ncsid); // ignore csid for now
1723 0fc65b37 2004-03-21 devnull
1724 0fc65b37 2004-03-21 devnull memmove(sec->crandom, crandom, RandomSize);
1725 0fc65b37 2004-03-21 devnull sec->clientVers = cvers;
1726 0fc65b37 2004-03-21 devnull
1727 0fc65b37 2004-03-21 devnull put32(sec->srandom, time(0));
1728 0fc65b37 2004-03-21 devnull genrandom(sec->srandom+4, RandomSize-4);
1729 0fc65b37 2004-03-21 devnull memmove(srandom, sec->srandom, RandomSize);
1730 0fc65b37 2004-03-21 devnull
1731 0fc65b37 2004-03-21 devnull /*
1732 0fc65b37 2004-03-21 devnull * make up a unique sid: use our pid, and and incrementing id
1733 0fc65b37 2004-03-21 devnull * can signal no sid by setting nssid to 0.
1734 0fc65b37 2004-03-21 devnull */
1735 0fc65b37 2004-03-21 devnull memset(ssid, 0, SidSize);
1736 0fc65b37 2004-03-21 devnull put32(ssid, getpid());
1737 0fc65b37 2004-03-21 devnull lock(&sidLock);
1738 0fc65b37 2004-03-21 devnull put32(ssid+4, maxSid++);
1739 0fc65b37 2004-03-21 devnull unlock(&sidLock);
1740 0fc65b37 2004-03-21 devnull *nssid = SidSize;
1741 0fc65b37 2004-03-21 devnull return sec;
1742 0fc65b37 2004-03-21 devnull }
1743 0fc65b37 2004-03-21 devnull
1744 0fc65b37 2004-03-21 devnull static int
1745 0fc65b37 2004-03-21 devnull tlsSecSecrets(TlsSec *sec, int vers, uchar *epm, int nepm, uchar *kd, int nkd)
1746 0fc65b37 2004-03-21 devnull {
1747 0fc65b37 2004-03-21 devnull if(epm != nil){
1748 0fc65b37 2004-03-21 devnull if(setVers(sec, vers) < 0)
1749 0fc65b37 2004-03-21 devnull goto Err;
1750 0fc65b37 2004-03-21 devnull serverMasterSecret(sec, epm, nepm);
1751 0fc65b37 2004-03-21 devnull }else if(sec->vers != vers){
1752 0fc65b37 2004-03-21 devnull werrstr("mismatched session versions");
1753 0fc65b37 2004-03-21 devnull goto Err;
1754 0fc65b37 2004-03-21 devnull }
1755 0fc65b37 2004-03-21 devnull setSecrets(sec, kd, nkd);
1756 0fc65b37 2004-03-21 devnull return 0;
1757 0fc65b37 2004-03-21 devnull Err:
1758 0fc65b37 2004-03-21 devnull sec->ok = -1;
1759 0fc65b37 2004-03-21 devnull return -1;
1760 0fc65b37 2004-03-21 devnull }
1761 0fc65b37 2004-03-21 devnull
1762 0fc65b37 2004-03-21 devnull static TlsSec*
1763 0fc65b37 2004-03-21 devnull tlsSecInitc(int cvers, uchar *crandom)
1764 0fc65b37 2004-03-21 devnull {
1765 0fc65b37 2004-03-21 devnull TlsSec *sec = emalloc(sizeof(*sec));
1766 0fc65b37 2004-03-21 devnull sec->clientVers = cvers;
1767 0fc65b37 2004-03-21 devnull put32(sec->crandom, time(0));
1768 0fc65b37 2004-03-21 devnull genrandom(sec->crandom+4, RandomSize-4);
1769 0fc65b37 2004-03-21 devnull memmove(crandom, sec->crandom, RandomSize);
1770 0fc65b37 2004-03-21 devnull return sec;
1771 0fc65b37 2004-03-21 devnull }
1772 0fc65b37 2004-03-21 devnull
1773 0fc65b37 2004-03-21 devnull static int
1774 0fc65b37 2004-03-21 devnull tlsSecSecretc(TlsSec *sec, uchar *sid, int nsid, uchar *srandom, uchar *cert, int ncert, int vers, uchar **epm, int *nepm, uchar *kd, int nkd)
1775 0fc65b37 2004-03-21 devnull {
1776 0fc65b37 2004-03-21 devnull RSApub *pub;
1777 0fc65b37 2004-03-21 devnull
1778 0fc65b37 2004-03-21 devnull pub = nil;
1779 0fc65b37 2004-03-21 devnull
1780 0fc65b37 2004-03-21 devnull USED(sid);
1781 0fc65b37 2004-03-21 devnull USED(nsid);
1782 0fc65b37 2004-03-21 devnull
1783 0fc65b37 2004-03-21 devnull memmove(sec->srandom, srandom, RandomSize);
1784 0fc65b37 2004-03-21 devnull
1785 0fc65b37 2004-03-21 devnull if(setVers(sec, vers) < 0)
1786 0fc65b37 2004-03-21 devnull goto Err;
1787 0fc65b37 2004-03-21 devnull
1788 0fc65b37 2004-03-21 devnull pub = X509toRSApub(cert, ncert, nil, 0);
1789 0fc65b37 2004-03-21 devnull if(pub == nil){
1790 0fc65b37 2004-03-21 devnull werrstr("invalid x509/rsa certificate");
1791 0fc65b37 2004-03-21 devnull goto Err;
1792 0fc65b37 2004-03-21 devnull }
1793 0fc65b37 2004-03-21 devnull if(clientMasterSecret(sec, pub, epm, nepm) < 0)
1794 0fc65b37 2004-03-21 devnull goto Err;
1795 0fc65b37 2004-03-21 devnull rsapubfree(pub);
1796 0fc65b37 2004-03-21 devnull setSecrets(sec, kd, nkd);
1797 0fc65b37 2004-03-21 devnull return 0;
1798 0fc65b37 2004-03-21 devnull
1799 0fc65b37 2004-03-21 devnull Err:
1800 0fc65b37 2004-03-21 devnull if(pub != nil)
1801 0fc65b37 2004-03-21 devnull rsapubfree(pub);
1802 0fc65b37 2004-03-21 devnull sec->ok = -1;
1803 0fc65b37 2004-03-21 devnull return -1;
1804 0fc65b37 2004-03-21 devnull }
1805 0fc65b37 2004-03-21 devnull
1806 0fc65b37 2004-03-21 devnull static int
1807 0fc65b37 2004-03-21 devnull tlsSecFinished(TlsSec *sec, MD5state md5, SHAstate sha1, uchar *fin, int nfin, int isclient)
1808 0fc65b37 2004-03-21 devnull {
1809 0fc65b37 2004-03-21 devnull if(sec->nfin != nfin){
1810 0fc65b37 2004-03-21 devnull sec->ok = -1;
1811 0fc65b37 2004-03-21 devnull werrstr("invalid finished exchange");
1812 0fc65b37 2004-03-21 devnull return -1;
1813 0fc65b37 2004-03-21 devnull }
1814 0fc65b37 2004-03-21 devnull md5.malloced = 0;
1815 0fc65b37 2004-03-21 devnull sha1.malloced = 0;
1816 0fc65b37 2004-03-21 devnull (*sec->setFinished)(sec, md5, sha1, fin, isclient);
1817 0fc65b37 2004-03-21 devnull return 1;
1818 0fc65b37 2004-03-21 devnull }
1819 0fc65b37 2004-03-21 devnull
1820 0fc65b37 2004-03-21 devnull static void
1821 0fc65b37 2004-03-21 devnull tlsSecOk(TlsSec *sec)
1822 0fc65b37 2004-03-21 devnull {
1823 0fc65b37 2004-03-21 devnull if(sec->ok == 0)
1824 0fc65b37 2004-03-21 devnull sec->ok = 1;
1825 0fc65b37 2004-03-21 devnull }
1826 0fc65b37 2004-03-21 devnull
1827 0fc65b37 2004-03-21 devnull static void
1828 0fc65b37 2004-03-21 devnull tlsSecKill(TlsSec *sec)
1829 0fc65b37 2004-03-21 devnull {
1830 0fc65b37 2004-03-21 devnull if(!sec)
1831 0fc65b37 2004-03-21 devnull return;
1832 0fc65b37 2004-03-21 devnull factotum_rsa_close(sec->rpc);
1833 0fc65b37 2004-03-21 devnull sec->ok = -1;
1834 0fc65b37 2004-03-21 devnull }
1835 0fc65b37 2004-03-21 devnull
1836 0fc65b37 2004-03-21 devnull static void
1837 0fc65b37 2004-03-21 devnull tlsSecClose(TlsSec *sec)
1838 0fc65b37 2004-03-21 devnull {
1839 0fc65b37 2004-03-21 devnull if(!sec)
1840 0fc65b37 2004-03-21 devnull return;
1841 0fc65b37 2004-03-21 devnull factotum_rsa_close(sec->rpc);
1842 0fc65b37 2004-03-21 devnull free(sec->server);
1843 0fc65b37 2004-03-21 devnull free(sec);
1844 0fc65b37 2004-03-21 devnull }
1845 0fc65b37 2004-03-21 devnull
1846 0fc65b37 2004-03-21 devnull static int
1847 0fc65b37 2004-03-21 devnull setVers(TlsSec *sec, int v)
1848 0fc65b37 2004-03-21 devnull {
1849 0fc65b37 2004-03-21 devnull if(v == SSL3Version){
1850 0fc65b37 2004-03-21 devnull sec->setFinished = sslSetFinished;
1851 0fc65b37 2004-03-21 devnull sec->nfin = SSL3FinishedLen;
1852 0fc65b37 2004-03-21 devnull sec->prf = sslPRF;
1853 0fc65b37 2004-03-21 devnull }else if(v == TLSVersion){
1854 0fc65b37 2004-03-21 devnull sec->setFinished = tlsSetFinished;
1855 0fc65b37 2004-03-21 devnull sec->nfin = TLSFinishedLen;
1856 0fc65b37 2004-03-21 devnull sec->prf = tlsPRF;
1857 0fc65b37 2004-03-21 devnull }else{
1858 0fc65b37 2004-03-21 devnull werrstr("invalid version");
1859 0fc65b37 2004-03-21 devnull return -1;
1860 0fc65b37 2004-03-21 devnull }
1861 0fc65b37 2004-03-21 devnull sec->vers = v;
1862 0fc65b37 2004-03-21 devnull return 0;
1863 0fc65b37 2004-03-21 devnull }
1864 0fc65b37 2004-03-21 devnull
1865 0fc65b37 2004-03-21 devnull /*
1866 0fc65b37 2004-03-21 devnull * generate secret keys from the master secret.
1867 0fc65b37 2004-03-21 devnull *
1868 0fc65b37 2004-03-21 devnull * different crypto selections will require different amounts
1869 0fc65b37 2004-03-21 devnull * of key expansion and use of key expansion data,
1870 0fc65b37 2004-03-21 devnull * but it's all generated using the same function.
1871 0fc65b37 2004-03-21 devnull */
1872 0fc65b37 2004-03-21 devnull static void
1873 0fc65b37 2004-03-21 devnull setSecrets(TlsSec *sec, uchar *kd, int nkd)
1874 0fc65b37 2004-03-21 devnull {
1875 0fc65b37 2004-03-21 devnull (*sec->prf)(kd, nkd, sec->sec, MasterSecretSize, "key expansion",
1876 0fc65b37 2004-03-21 devnull sec->srandom, RandomSize, sec->crandom, RandomSize);
1877 0fc65b37 2004-03-21 devnull }
1878 0fc65b37 2004-03-21 devnull
1879 0fc65b37 2004-03-21 devnull /*
1880 0fc65b37 2004-03-21 devnull * set the master secret from the pre-master secret.
1881 0fc65b37 2004-03-21 devnull */
1882 0fc65b37 2004-03-21 devnull static void
1883 0fc65b37 2004-03-21 devnull setMasterSecret(TlsSec *sec, Bytes *pm)
1884 0fc65b37 2004-03-21 devnull {
1885 0fc65b37 2004-03-21 devnull (*sec->prf)(sec->sec, MasterSecretSize, pm->data, MasterSecretSize, "master secret",
1886 0fc65b37 2004-03-21 devnull sec->crandom, RandomSize, sec->srandom, RandomSize);
1887 0fc65b37 2004-03-21 devnull }
1888 0fc65b37 2004-03-21 devnull
1889 0fc65b37 2004-03-21 devnull static void
1890 0fc65b37 2004-03-21 devnull serverMasterSecret(TlsSec *sec, uchar *epm, int nepm)
1891 0fc65b37 2004-03-21 devnull {
1892 0fc65b37 2004-03-21 devnull Bytes *pm;
1893 0fc65b37 2004-03-21 devnull
1894 0fc65b37 2004-03-21 devnull pm = pkcs1_decrypt(sec, epm, nepm);
1895 0fc65b37 2004-03-21 devnull
1896 0fc65b37 2004-03-21 devnull // if the client messed up, just continue as if everything is ok,
1897 0fc65b37 2004-03-21 devnull // to prevent attacks to check for correctly formatted messages.
1898 0fc65b37 2004-03-21 devnull // Hence the fprint(2,) can't be replaced by tlsError(), which sends an Alert msg to the client.
1899 0fc65b37 2004-03-21 devnull if(sec->ok < 0 || pm == nil || get16(pm->data) != sec->clientVers){
1900 0fc65b37 2004-03-21 devnull fprint(2, "serverMasterSecret failed ok=%d pm=%p pmvers=%x cvers=%x nepm=%d\n",
1901 0fc65b37 2004-03-21 devnull sec->ok, pm, pm ? get16(pm->data) : -1, sec->clientVers, nepm);
1902 0fc65b37 2004-03-21 devnull sec->ok = -1;
1903 0fc65b37 2004-03-21 devnull if(pm != nil)
1904 0fc65b37 2004-03-21 devnull freebytes(pm);
1905 0fc65b37 2004-03-21 devnull pm = newbytes(MasterSecretSize);
1906 0fc65b37 2004-03-21 devnull genrandom(pm->data, MasterSecretSize);
1907 0fc65b37 2004-03-21 devnull }
1908 0fc65b37 2004-03-21 devnull setMasterSecret(sec, pm);
1909 0fc65b37 2004-03-21 devnull memset(pm->data, 0, pm->len);
1910 0fc65b37 2004-03-21 devnull freebytes(pm);
1911 0fc65b37 2004-03-21 devnull }
1912 0fc65b37 2004-03-21 devnull
1913 0fc65b37 2004-03-21 devnull static int
1914 0fc65b37 2004-03-21 devnull clientMasterSecret(TlsSec *sec, RSApub *pub, uchar **epm, int *nepm)
1915 0fc65b37 2004-03-21 devnull {
1916 0fc65b37 2004-03-21 devnull Bytes *pm, *key;
1917 0fc65b37 2004-03-21 devnull
1918 0fc65b37 2004-03-21 devnull pm = newbytes(MasterSecretSize);
1919 0fc65b37 2004-03-21 devnull put16(pm->data, sec->clientVers);
1920 0fc65b37 2004-03-21 devnull genrandom(pm->data+2, MasterSecretSize - 2);
1921 0fc65b37 2004-03-21 devnull
1922 0fc65b37 2004-03-21 devnull setMasterSecret(sec, pm);
1923 0fc65b37 2004-03-21 devnull
1924 0fc65b37 2004-03-21 devnull key = pkcs1_encrypt(pm, pub, 2);
1925 0fc65b37 2004-03-21 devnull memset(pm->data, 0, pm->len);
1926 0fc65b37 2004-03-21 devnull freebytes(pm);
1927 0fc65b37 2004-03-21 devnull if(key == nil){
1928 0fc65b37 2004-03-21 devnull werrstr("tls pkcs1_encrypt failed");
1929 0fc65b37 2004-03-21 devnull return -1;
1930 0fc65b37 2004-03-21 devnull }
1931 0fc65b37 2004-03-21 devnull
1932 0fc65b37 2004-03-21 devnull *nepm = key->len;
1933 0fc65b37 2004-03-21 devnull *epm = malloc(*nepm);
1934 0fc65b37 2004-03-21 devnull if(*epm == nil){
1935 0fc65b37 2004-03-21 devnull freebytes(key);
1936 0fc65b37 2004-03-21 devnull werrstr("out of memory");
1937 0fc65b37 2004-03-21 devnull return -1;
1938 0fc65b37 2004-03-21 devnull }
1939 0fc65b37 2004-03-21 devnull memmove(*epm, key->data, *nepm);
1940 0fc65b37 2004-03-21 devnull
1941 0fc65b37 2004-03-21 devnull freebytes(key);
1942 0fc65b37 2004-03-21 devnull
1943 0fc65b37 2004-03-21 devnull return 1;
1944 0fc65b37 2004-03-21 devnull }
1945 0fc65b37 2004-03-21 devnull
1946 0fc65b37 2004-03-21 devnull static void
1947 0fc65b37 2004-03-21 devnull sslSetFinished(TlsSec *sec, MD5state hsmd5, SHAstate hssha1, uchar *finished, int isClient)
1948 0fc65b37 2004-03-21 devnull {
1949 0fc65b37 2004-03-21 devnull DigestState *s;
1950 0fc65b37 2004-03-21 devnull uchar h0[MD5dlen], h1[SHA1dlen], pad[48];
1951 0fc65b37 2004-03-21 devnull char *label;
1952 0fc65b37 2004-03-21 devnull
1953 0fc65b37 2004-03-21 devnull if(isClient)
1954 0fc65b37 2004-03-21 devnull label = "CLNT";
1955 0fc65b37 2004-03-21 devnull else
1956 0fc65b37 2004-03-21 devnull label = "SRVR";
1957 0fc65b37 2004-03-21 devnull
1958 0fc65b37 2004-03-21 devnull md5((uchar*)label, 4, nil, &hsmd5);
1959 0fc65b37 2004-03-21 devnull md5(sec->sec, MasterSecretSize, nil, &hsmd5);
1960 0fc65b37 2004-03-21 devnull memset(pad, 0x36, 48);
1961 0fc65b37 2004-03-21 devnull md5(pad, 48, nil, &hsmd5);
1962 0fc65b37 2004-03-21 devnull md5(nil, 0, h0, &hsmd5);
1963 0fc65b37 2004-03-21 devnull memset(pad, 0x5C, 48);
1964 0fc65b37 2004-03-21 devnull s = md5(sec->sec, MasterSecretSize, nil, nil);
1965 0fc65b37 2004-03-21 devnull s = md5(pad, 48, nil, s);
1966 0fc65b37 2004-03-21 devnull md5(h0, MD5dlen, finished, s);
1967 0fc65b37 2004-03-21 devnull
1968 0fc65b37 2004-03-21 devnull sha1((uchar*)label, 4, nil, &hssha1);
1969 0fc65b37 2004-03-21 devnull sha1(sec->sec, MasterSecretSize, nil, &hssha1);
1970 0fc65b37 2004-03-21 devnull memset(pad, 0x36, 40);
1971 0fc65b37 2004-03-21 devnull sha1(pad, 40, nil, &hssha1);
1972 0fc65b37 2004-03-21 devnull sha1(nil, 0, h1, &hssha1);
1973 0fc65b37 2004-03-21 devnull memset(pad, 0x5C, 40);
1974 0fc65b37 2004-03-21 devnull s = sha1(sec->sec, MasterSecretSize, nil, nil);
1975 0fc65b37 2004-03-21 devnull s = sha1(pad, 40, nil, s);
1976 0fc65b37 2004-03-21 devnull sha1(h1, SHA1dlen, finished + MD5dlen, s);
1977 0fc65b37 2004-03-21 devnull }
1978 0fc65b37 2004-03-21 devnull
1979 0fc65b37 2004-03-21 devnull // fill "finished" arg with md5(args)^sha1(args)
1980 0fc65b37 2004-03-21 devnull static void
1981 0fc65b37 2004-03-21 devnull tlsSetFinished(TlsSec *sec, MD5state hsmd5, SHAstate hssha1, uchar *finished, int isClient)
1982 0fc65b37 2004-03-21 devnull {
1983 0fc65b37 2004-03-21 devnull uchar h0[MD5dlen], h1[SHA1dlen];
1984 0fc65b37 2004-03-21 devnull char *label;
1985 0fc65b37 2004-03-21 devnull
1986 0fc65b37 2004-03-21 devnull // get current hash value, but allow further messages to be hashed in
1987 0fc65b37 2004-03-21 devnull md5(nil, 0, h0, &hsmd5);
1988 0fc65b37 2004-03-21 devnull sha1(nil, 0, h1, &hssha1);
1989 0fc65b37 2004-03-21 devnull
1990 0fc65b37 2004-03-21 devnull if(isClient)
1991 0fc65b37 2004-03-21 devnull label = "client finished";
1992 0fc65b37 2004-03-21 devnull else
1993 0fc65b37 2004-03-21 devnull label = "server finished";
1994 0fc65b37 2004-03-21 devnull tlsPRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, h0, MD5dlen, h1, SHA1dlen);
1995 0fc65b37 2004-03-21 devnull }
1996 0fc65b37 2004-03-21 devnull
1997 0fc65b37 2004-03-21 devnull static void
1998 0fc65b37 2004-03-21 devnull sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed0, int nseed0, uchar *seed1, int nseed1)
1999 0fc65b37 2004-03-21 devnull {
2000 0fc65b37 2004-03-21 devnull DigestState *s;
2001 0fc65b37 2004-03-21 devnull uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];
2002 0fc65b37 2004-03-21 devnull int i, n, len;
2003 0fc65b37 2004-03-21 devnull
2004 0fc65b37 2004-03-21 devnull USED(label);
2005 0fc65b37 2004-03-21 devnull len = 1;
2006 0fc65b37 2004-03-21 devnull while(nbuf > 0){
2007 0fc65b37 2004-03-21 devnull if(len > 26)
2008 0fc65b37 2004-03-21 devnull return;
2009 0fc65b37 2004-03-21 devnull for(i = 0; i < len; i++)
2010 0fc65b37 2004-03-21 devnull tmp[i] = 'A' - 1 + len;
2011 0fc65b37 2004-03-21 devnull s = sha1(tmp, len, nil, nil);
2012 0fc65b37 2004-03-21 devnull s = sha1(key, nkey, nil, s);
2013 0fc65b37 2004-03-21 devnull s = sha1(seed0, nseed0, nil, s);
2014 0fc65b37 2004-03-21 devnull sha1(seed1, nseed1, sha1dig, s);
2015 0fc65b37 2004-03-21 devnull s = md5(key, nkey, nil, nil);
2016 0fc65b37 2004-03-21 devnull md5(sha1dig, SHA1dlen, md5dig, s);
2017 0fc65b37 2004-03-21 devnull n = MD5dlen;
2018 0fc65b37 2004-03-21 devnull if(n > nbuf)
2019 0fc65b37 2004-03-21 devnull n = nbuf;
2020 0fc65b37 2004-03-21 devnull memmove(buf, md5dig, n);
2021 0fc65b37 2004-03-21 devnull buf += n;
2022 0fc65b37 2004-03-21 devnull nbuf -= n;
2023 0fc65b37 2004-03-21 devnull len++;
2024 0fc65b37 2004-03-21 devnull }
2025 0fc65b37 2004-03-21 devnull }
2026 0fc65b37 2004-03-21 devnull
2027 0fc65b37 2004-03-21 devnull static mpint*
2028 0fc65b37 2004-03-21 devnull bytestomp(Bytes* bytes)
2029 0fc65b37 2004-03-21 devnull {
2030 0fc65b37 2004-03-21 devnull mpint* ans;
2031 0fc65b37 2004-03-21 devnull
2032 0fc65b37 2004-03-21 devnull ans = betomp(bytes->data, bytes->len, nil);
2033 0fc65b37 2004-03-21 devnull return ans;
2034 0fc65b37 2004-03-21 devnull }
2035 0fc65b37 2004-03-21 devnull
2036 0fc65b37 2004-03-21 devnull /*
2037 0fc65b37 2004-03-21 devnull * Convert mpint* to Bytes, putting high order byte first.
2038 0fc65b37 2004-03-21 devnull */
2039 0fc65b37 2004-03-21 devnull static Bytes*
2040 0fc65b37 2004-03-21 devnull mptobytes(mpint* big)
2041 0fc65b37 2004-03-21 devnull {
2042 0fc65b37 2004-03-21 devnull int n, m;
2043 0fc65b37 2004-03-21 devnull uchar *a;
2044 0fc65b37 2004-03-21 devnull Bytes* ans;
2045 0fc65b37 2004-03-21 devnull
2046 0fc65b37 2004-03-21 devnull n = (mpsignif(big)+7)/8;
2047 0fc65b37 2004-03-21 devnull m = mptobe(big, nil, n, &a);
2048 0fc65b37 2004-03-21 devnull ans = makebytes(a, m);
2049 0fc65b37 2004-03-21 devnull return ans;
2050 0fc65b37 2004-03-21 devnull }
2051 0fc65b37 2004-03-21 devnull
2052 0fc65b37 2004-03-21 devnull // Do RSA computation on block according to key, and pad
2053 0fc65b37 2004-03-21 devnull // result on left with zeros to make it modlen long.
2054 0fc65b37 2004-03-21 devnull static Bytes*
2055 0fc65b37 2004-03-21 devnull rsacomp(Bytes* block, RSApub* key, int modlen)
2056 0fc65b37 2004-03-21 devnull {
2057 0fc65b37 2004-03-21 devnull mpint *x, *y;
2058 0fc65b37 2004-03-21 devnull Bytes *a, *ybytes;
2059 0fc65b37 2004-03-21 devnull int ylen;
2060 0fc65b37 2004-03-21 devnull
2061 0fc65b37 2004-03-21 devnull x = bytestomp(block);
2062 0fc65b37 2004-03-21 devnull y = rsaencrypt(key, x, nil);
2063 0fc65b37 2004-03-21 devnull mpfree(x);
2064 0fc65b37 2004-03-21 devnull ybytes = mptobytes(y);
2065 0fc65b37 2004-03-21 devnull ylen = ybytes->len;
2066 0fc65b37 2004-03-21 devnull
2067 0fc65b37 2004-03-21 devnull if(ylen < modlen) {
2068 0fc65b37 2004-03-21 devnull a = newbytes(modlen);
2069 0fc65b37 2004-03-21 devnull memset(a->data, 0, modlen-ylen);
2070 0fc65b37 2004-03-21 devnull memmove(a->data+modlen-ylen, ybytes->data, ylen);
2071 0fc65b37 2004-03-21 devnull freebytes(ybytes);
2072 0fc65b37 2004-03-21 devnull ybytes = a;
2073 0fc65b37 2004-03-21 devnull }
2074 0fc65b37 2004-03-21 devnull else if(ylen > modlen) {
2075 0fc65b37 2004-03-21 devnull // assume it has leading zeros (mod should make it so)
2076 0fc65b37 2004-03-21 devnull a = newbytes(modlen);
2077 0fc65b37 2004-03-21 devnull memmove(a->data, ybytes->data, modlen);
2078 0fc65b37 2004-03-21 devnull freebytes(ybytes);
2079 0fc65b37 2004-03-21 devnull ybytes = a;
2080 0fc65b37 2004-03-21 devnull }
2081 0fc65b37 2004-03-21 devnull mpfree(y);
2082 0fc65b37 2004-03-21 devnull return ybytes;
2083 0fc65b37 2004-03-21 devnull }
2084 0fc65b37 2004-03-21 devnull
2085 0fc65b37 2004-03-21 devnull // encrypt data according to PKCS#1, /lib/rfc/rfc2437 9.1.2.1
2086 0fc65b37 2004-03-21 devnull static Bytes*
2087 0fc65b37 2004-03-21 devnull pkcs1_encrypt(Bytes* data, RSApub* key, int blocktype)
2088 0fc65b37 2004-03-21 devnull {
2089 0fc65b37 2004-03-21 devnull Bytes *pad, *eb, *ans;
2090 0fc65b37 2004-03-21 devnull int i, dlen, padlen, modlen;
2091 0fc65b37 2004-03-21 devnull
2092 0fc65b37 2004-03-21 devnull modlen = (mpsignif(key->n)+7)/8;
2093 0fc65b37 2004-03-21 devnull dlen = data->len;
2094 0fc65b37 2004-03-21 devnull if(modlen < 12 || dlen > modlen - 11)
2095 0fc65b37 2004-03-21 devnull return nil;
2096 0fc65b37 2004-03-21 devnull padlen = modlen - 3 - dlen;
2097 0fc65b37 2004-03-21 devnull pad = newbytes(padlen);
2098 0fc65b37 2004-03-21 devnull genrandom(pad->data, padlen);
2099 0fc65b37 2004-03-21 devnull for(i = 0; i < padlen; i++) {
2100 0fc65b37 2004-03-21 devnull if(blocktype == 0)
2101 0fc65b37 2004-03-21 devnull pad->data[i] = 0;
2102 0fc65b37 2004-03-21 devnull else if(blocktype == 1)
2103 0fc65b37 2004-03-21 devnull pad->data[i] = 255;
2104 0fc65b37 2004-03-21 devnull else if(pad->data[i] == 0)
2105 0fc65b37 2004-03-21 devnull pad->data[i] = 1;
2106 0fc65b37 2004-03-21 devnull }
2107 0fc65b37 2004-03-21 devnull eb = newbytes(modlen);
2108 0fc65b37 2004-03-21 devnull eb->data[0] = 0;
2109 0fc65b37 2004-03-21 devnull eb->data[1] = blocktype;
2110 0fc65b37 2004-03-21 devnull memmove(eb->data+2, pad->data, padlen);
2111 0fc65b37 2004-03-21 devnull eb->data[padlen+2] = 0;
2112 0fc65b37 2004-03-21 devnull memmove(eb->data+padlen+3, data->data, dlen);
2113 0fc65b37 2004-03-21 devnull ans = rsacomp(eb, key, modlen);
2114 0fc65b37 2004-03-21 devnull freebytes(eb);
2115 0fc65b37 2004-03-21 devnull freebytes(pad);
2116 0fc65b37 2004-03-21 devnull return ans;
2117 0fc65b37 2004-03-21 devnull }
2118 0fc65b37 2004-03-21 devnull
2119 0fc65b37 2004-03-21 devnull // decrypt data according to PKCS#1, with given key.
2120 0fc65b37 2004-03-21 devnull // expect a block type of 2.
2121 0fc65b37 2004-03-21 devnull static Bytes*
2122 0fc65b37 2004-03-21 devnull pkcs1_decrypt(TlsSec *sec, uchar *epm, int nepm)
2123 0fc65b37 2004-03-21 devnull {
2124 0fc65b37 2004-03-21 devnull Bytes *eb, *ans = nil;
2125 0fc65b37 2004-03-21 devnull int i, modlen;
2126 0fc65b37 2004-03-21 devnull mpint *x, *y;
2127 0fc65b37 2004-03-21 devnull
2128 0fc65b37 2004-03-21 devnull modlen = (mpsignif(sec->rsapub->n)+7)/8;
2129 0fc65b37 2004-03-21 devnull if(nepm != modlen)
2130 0fc65b37 2004-03-21 devnull return nil;
2131 0fc65b37 2004-03-21 devnull x = betomp(epm, nepm, nil);
2132 0fc65b37 2004-03-21 devnull y = factotum_rsa_decrypt(sec->rpc, x);
2133 0fc65b37 2004-03-21 devnull if(y == nil)
2134 0fc65b37 2004-03-21 devnull return nil;
2135 0fc65b37 2004-03-21 devnull eb = mptobytes(y);
2136 0fc65b37 2004-03-21 devnull if(eb->len < modlen){ // pad on left with zeros
2137 0fc65b37 2004-03-21 devnull ans = newbytes(modlen);
2138 0fc65b37 2004-03-21 devnull memset(ans->data, 0, modlen-eb->len);
2139 0fc65b37 2004-03-21 devnull memmove(ans->data+modlen-eb->len, eb->data, eb->len);
2140 0fc65b37 2004-03-21 devnull freebytes(eb);
2141 0fc65b37 2004-03-21 devnull eb = ans;
2142 0fc65b37 2004-03-21 devnull }
2143 0fc65b37 2004-03-21 devnull if(eb->data[0] == 0 && eb->data[1] == 2) {
2144 0fc65b37 2004-03-21 devnull for(i = 2; i < modlen; i++)
2145 0fc65b37 2004-03-21 devnull if(eb->data[i] == 0)
2146 0fc65b37 2004-03-21 devnull break;
2147 0fc65b37 2004-03-21 devnull if(i < modlen - 1)
2148 0fc65b37 2004-03-21 devnull ans = makebytes(eb->data+i+1, modlen-(i+1));
2149 0fc65b37 2004-03-21 devnull }
2150 0fc65b37 2004-03-21 devnull freebytes(eb);
2151 0fc65b37 2004-03-21 devnull return ans;
2152 0fc65b37 2004-03-21 devnull }
2153 0fc65b37 2004-03-21 devnull
2154 0fc65b37 2004-03-21 devnull
2155 0fc65b37 2004-03-21 devnull //================= general utility functions ========================
2156 0fc65b37 2004-03-21 devnull
2157 0fc65b37 2004-03-21 devnull static void *
2158 0fc65b37 2004-03-21 devnull emalloc(int n)
2159 0fc65b37 2004-03-21 devnull {
2160 0fc65b37 2004-03-21 devnull void *p;
2161 0fc65b37 2004-03-21 devnull if(n==0)
2162 0fc65b37 2004-03-21 devnull n=1;
2163 0fc65b37 2004-03-21 devnull p = malloc(n);
2164 0fc65b37 2004-03-21 devnull if(p == nil){
2165 0fc65b37 2004-03-21 devnull exits("out of memory");
2166 0fc65b37 2004-03-21 devnull }
2167 0fc65b37 2004-03-21 devnull memset(p, 0, n);
2168 0fc65b37 2004-03-21 devnull return p;
2169 0fc65b37 2004-03-21 devnull }
2170 0fc65b37 2004-03-21 devnull
2171 0fc65b37 2004-03-21 devnull static void *
2172 0fc65b37 2004-03-21 devnull erealloc(void *ReallocP, int ReallocN)
2173 0fc65b37 2004-03-21 devnull {
2174 0fc65b37 2004-03-21 devnull if(ReallocN == 0)
2175 0fc65b37 2004-03-21 devnull ReallocN = 1;
2176 0fc65b37 2004-03-21 devnull if(!ReallocP)
2177 0fc65b37 2004-03-21 devnull ReallocP = emalloc(ReallocN);
2178 0fc65b37 2004-03-21 devnull else if(!(ReallocP = realloc(ReallocP, ReallocN))){
2179 0fc65b37 2004-03-21 devnull exits("out of memory");
2180 0fc65b37 2004-03-21 devnull }
2181 0fc65b37 2004-03-21 devnull return(ReallocP);
2182 0fc65b37 2004-03-21 devnull }
2183 0fc65b37 2004-03-21 devnull
2184 0fc65b37 2004-03-21 devnull static void
2185 0fc65b37 2004-03-21 devnull put32(uchar *p, u32int x)
2186 0fc65b37 2004-03-21 devnull {
2187 0fc65b37 2004-03-21 devnull p[0] = x>>24;
2188 0fc65b37 2004-03-21 devnull p[1] = x>>16;
2189 0fc65b37 2004-03-21 devnull p[2] = x>>8;
2190 0fc65b37 2004-03-21 devnull p[3] = x;
2191 0fc65b37 2004-03-21 devnull }
2192 0fc65b37 2004-03-21 devnull
2193 0fc65b37 2004-03-21 devnull static void
2194 0fc65b37 2004-03-21 devnull put24(uchar *p, int x)
2195 0fc65b37 2004-03-21 devnull {
2196 0fc65b37 2004-03-21 devnull p[0] = x>>16;
2197 0fc65b37 2004-03-21 devnull p[1] = x>>8;
2198 0fc65b37 2004-03-21 devnull p[2] = x;
2199 0fc65b37 2004-03-21 devnull }
2200 0fc65b37 2004-03-21 devnull
2201 0fc65b37 2004-03-21 devnull static void
2202 0fc65b37 2004-03-21 devnull put16(uchar *p, int x)
2203 0fc65b37 2004-03-21 devnull {
2204 0fc65b37 2004-03-21 devnull p[0] = x>>8;
2205 0fc65b37 2004-03-21 devnull p[1] = x;
2206 0fc65b37 2004-03-21 devnull }
2207 0fc65b37 2004-03-21 devnull
2208 0fc65b37 2004-03-21 devnull static u32int
2209 0fc65b37 2004-03-21 devnull get32(uchar *p)
2210 0fc65b37 2004-03-21 devnull {
2211 0fc65b37 2004-03-21 devnull return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
2212 0fc65b37 2004-03-21 devnull }
2213 0fc65b37 2004-03-21 devnull
2214 0fc65b37 2004-03-21 devnull static int
2215 0fc65b37 2004-03-21 devnull get24(uchar *p)
2216 0fc65b37 2004-03-21 devnull {
2217 0fc65b37 2004-03-21 devnull return (p[0]<<16)|(p[1]<<8)|p[2];
2218 0fc65b37 2004-03-21 devnull }
2219 0fc65b37 2004-03-21 devnull
2220 0fc65b37 2004-03-21 devnull static int
2221 0fc65b37 2004-03-21 devnull get16(uchar *p)
2222 0fc65b37 2004-03-21 devnull {
2223 0fc65b37 2004-03-21 devnull return (p[0]<<8)|p[1];
2224 0fc65b37 2004-03-21 devnull }
2225 0fc65b37 2004-03-21 devnull
2226 0fc65b37 2004-03-21 devnull /* ANSI offsetof() */
2227 0fc65b37 2004-03-21 devnull #define OFFSET(x, s) ((int)(&(((s*)0)->x)))
2228 0fc65b37 2004-03-21 devnull
2229 0fc65b37 2004-03-21 devnull /*
2230 0fc65b37 2004-03-21 devnull * malloc and return a new Bytes structure capable of
2231 0fc65b37 2004-03-21 devnull * holding len bytes. (len >= 0)
2232 0fc65b37 2004-03-21 devnull * Used to use crypt_malloc, which aborts if malloc fails.
2233 0fc65b37 2004-03-21 devnull */
2234 0fc65b37 2004-03-21 devnull static Bytes*
2235 0fc65b37 2004-03-21 devnull newbytes(int len)
2236 0fc65b37 2004-03-21 devnull {
2237 0fc65b37 2004-03-21 devnull Bytes* ans;
2238 0fc65b37 2004-03-21 devnull
2239 0fc65b37 2004-03-21 devnull ans = (Bytes*)malloc(OFFSET(data[0], Bytes) + len);
2240 0fc65b37 2004-03-21 devnull ans->len = len;
2241 0fc65b37 2004-03-21 devnull return ans;
2242 0fc65b37 2004-03-21 devnull }
2243 0fc65b37 2004-03-21 devnull
2244 0fc65b37 2004-03-21 devnull /*
2245 0fc65b37 2004-03-21 devnull * newbytes(len), with data initialized from buf
2246 0fc65b37 2004-03-21 devnull */
2247 0fc65b37 2004-03-21 devnull static Bytes*
2248 0fc65b37 2004-03-21 devnull makebytes(uchar* buf, int len)
2249 0fc65b37 2004-03-21 devnull {
2250 0fc65b37 2004-03-21 devnull Bytes* ans;
2251 0fc65b37 2004-03-21 devnull
2252 0fc65b37 2004-03-21 devnull ans = newbytes(len);
2253 0fc65b37 2004-03-21 devnull memmove(ans->data, buf, len);
2254 0fc65b37 2004-03-21 devnull return ans;
2255 0fc65b37 2004-03-21 devnull }
2256 0fc65b37 2004-03-21 devnull
2257 0fc65b37 2004-03-21 devnull static void
2258 0fc65b37 2004-03-21 devnull freebytes(Bytes* b)
2259 0fc65b37 2004-03-21 devnull {
2260 0fc65b37 2004-03-21 devnull if(b != nil)
2261 0fc65b37 2004-03-21 devnull free(b);
2262 0fc65b37 2004-03-21 devnull }
2263 0fc65b37 2004-03-21 devnull
2264 0fc65b37 2004-03-21 devnull /* len is number of ints */
2265 0fc65b37 2004-03-21 devnull static Ints*
2266 0fc65b37 2004-03-21 devnull newints(int len)
2267 0fc65b37 2004-03-21 devnull {
2268 0fc65b37 2004-03-21 devnull Ints* ans;
2269 0fc65b37 2004-03-21 devnull
2270 0fc65b37 2004-03-21 devnull ans = (Ints*)malloc(OFFSET(data[0], Ints) + len*sizeof(int));
2271 0fc65b37 2004-03-21 devnull ans->len = len;
2272 0fc65b37 2004-03-21 devnull return ans;
2273 0fc65b37 2004-03-21 devnull }
2274 0fc65b37 2004-03-21 devnull
2275 0fc65b37 2004-03-21 devnull static Ints*
2276 0fc65b37 2004-03-21 devnull makeints(int* buf, int len)
2277 0fc65b37 2004-03-21 devnull {
2278 0fc65b37 2004-03-21 devnull Ints* ans;
2279 0fc65b37 2004-03-21 devnull
2280 0fc65b37 2004-03-21 devnull ans = newints(len);
2281 0fc65b37 2004-03-21 devnull if(len > 0)
2282 0fc65b37 2004-03-21 devnull memmove(ans->data, buf, len*sizeof(int));
2283 0fc65b37 2004-03-21 devnull return ans;
2284 0fc65b37 2004-03-21 devnull }
2285 0fc65b37 2004-03-21 devnull
2286 0fc65b37 2004-03-21 devnull static void
2287 0fc65b37 2004-03-21 devnull freeints(Ints* b)
2288 0fc65b37 2004-03-21 devnull {
2289 0fc65b37 2004-03-21 devnull if(b != nil)
2290 0fc65b37 2004-03-21 devnull free(b);
2291 0fc65b37 2004-03-21 devnull }