First, assume that we have instantiated a TLS object, set up a pseudorandom number generator, and have all certificates required for client and server authentication:
TLS tls; // instantiate a %TLS object PRNG prng; // and a PRNG cstr rootCerts; // trust anchors for server certificate authentication cstr userCerts; // user's certificate chain for client authentication
To initialize the TLS object, we:
int Init(int cipher, int minor, TokenSignCallback tcb, void *tokeninfoptr) { tls.setcipher(cipher,minor); tls.setrand(prng.gens(46),prng.gens(28),prng.gens(20),cdk::timegmt()); tls.sign = tcb; tls.tokeninfoptr = tokeninfoptr; return 0; }
Our basic messaging functions assume the existence of an open communications channel to the server. Here an undocumented object ('sock') will provide that functionality via its Send() and Recv() functions. Using sock, SendRecv() sends anything that might be in the TLS client buffer, then populates the TLS server buffer with whatever data has been received from the server:
int SendRecv() { // returns: 0=did nothing, 1=something, 2=error if (+tls.c.buf) { int i = sock.Send(tls.c.buf); if (i != +tls.c.buf) return 2; tls.c.buf = 0; return 1; } Sleep(200); str x = sock.Recv(); tls.s.buf += x; return !!+x; }
Get() returns a complete communications record from the server, decrypting it if necessary:
str Get()
{
if (m_bHTTPS)
{
for (;;)
{
if (isBad()) return 0;
str x, y;
int i = tls.parse(x,y);
if (i == 0)
{
tls.s.buf = y;
if (tls.unwrap(x,y)) return 0;
return y;
}
if (i == 2) break;
Sleep(90);
tls.s.buf += sock.Recv();
}
}
else
{
Sleep(90);
str y = sock.Recv();
return y;
}
return 0;
}
To connect to a server and 'GET' a page, we simply:
str GETpage(cstr addr, cstr file, int port) { int i; sock.initconnection(addr,port); if (m_bHTTPS) { tls.load(userCerts); for (;;) { i = tls.dorecs(); if (i > 1) return error(tls.lasterror); if (tls.isHot()) break; if (tls.isBad()) return error(tls.lasterror); i = SendRecv(); if (i > 1) return error(errProtocolFailure); } i = 0; // validate the server certificate: if (+rootCerts) i = CheckCA(rootCerts,tls.s.cer); else if (cbvalidatecert != NULL) { cdk::tokenop t; t.cer = tls.s.cer; i = cbvalidatecert(t); } if (i) return error(i); } str data = str("GET /") + file + " HTTP/1.0\r\n\r\n"; str x = data; if (m_bHTTPS) x = tls.wrap(data); i = sock.Send(x); if (i < 0) return error(errProtocolFailure); x = 0; long t = timegmt(); do x += Get(); while (!isComplete(x) && t + 30 > timegmt()); return x; }
POSTing is similar. We:
str POSTpage(const str &addr, const str &file, const str &postdata, int port) { int i; sock.initconnection(addr,port); if (m_bHTTPS) { tls.load(userCerts); for (;;) { i = tls.dorecs(); if (i > 1) return error(tls.lasterror); if (tls.isHot()) break; if (tls.isBad()) return error(tls.lasterror); i = SendRecv(); if (i > 1) return error(errProtocolFailure); } i = 0; // validate the server certificate: if (+rootCerts) i = CheckCA(rootCerts,tls.s.cer); else if (cbvalidatecert != NULL) { cdk::tokenop t; t.cer = tls.s.cer; t.tokeninfoptr = tls.tokeninfoptr; i = cbvalidatecert(t); // 0 OK non-zero bad. } if (i) return error(i); } char szPD[32]; sprintf(szPD, "%d", postdata.length()); str header = str("POST /") + file + str(" HTTP/1.0\n") + str("Content-type: application/x-www-form-urlencoded\n") + str("Content-length: ") + str(szPD) + str("\n\n"); str data = header + postdata; str x = data; if (m_bHTTPS) x = tls.wrap(data); i = sock.Send(x); if (i < 0) return error(errProtocolFailure); x = 0; long t = timegmt(); do x += Get(); while (!isComplete(x) && t + 30 > timegmt()); return x; }
In both GETpage() and POSTpage() we used the following auxiliary function to determine when a message from the server is complete:
int isComplete(str a) { int start = a.find("\r\n\r\n"); if (start < 0) return 0; int i = a.find("Content-Length: "); if (i >= 0) return +a >= start + 4 + atoi(a.c_str()+i+16); if (+a > start && a[start] == 0x30) return asn(a.skip(start)).isParseable(); return a.find("</html>") >= 0 || a.find("</HTML>") >= 0; }
See RFC 2246 for more information.
| ISC Cryptographic Development Kit - User's Guide | |
| Questions? E-mail ISC technical support | |
| Copyright© 2002-2006 Information Security Corp. All rights reserved. |