1
// ---------------------------------------------------------------------------
3
// - afnix:tls service - tls connect class implementation -
4
// ---------------------------------------------------------------------------
5
// - This program is free software; you can redistribute it and/or modify -
6
// - it provided that this copyright notice is kept intact. -
8
// - This program is distributed in the hope that it will be useful, but -
9
// - without any warranty; without even the implied warranty of -
10
// - merchantability or fitness for a particular purpose. In no event shall -
11
// - the copyright holder be liable for any direct, indirect, incidental or -
12
// - special damages arising in any way out of the use of this software. -
13
// ---------------------------------------------------------------------------
14
// - copyright (c) 1999-2015 amaury darsch -
15
// ---------------------------------------------------------------------------
18
#include "TlsShake.hpp"
19
#include "Runnable.hpp"
20
#include "QuarkZone.hpp"
21
#include "Exception.hpp"
22
#include "TlsConnect.hpp"
26
// -------------------------------------------------------------------------
28
// -------------------------------------------------------------------------
30
// create a tls connect by flag
32
TlsConnect::TlsConnect (const bool sflg) {
36
// return the class name
38
String TlsConnect::repr (void) const {
42
// reset the tls connection object
44
void TlsConnect::reset (void) {
55
// get the connection info list
57
Plist TlsConnect::getinfo (void) const {
60
Plist result = d_info;
69
// perform a handshake operation
71
TlsState* TlsConnect::connect (InputStream* is, OutputStream* os) {
73
if ((is == nilp) || (os == nilp)) return nilp;
79
// connect the tls socket
80
TlsState* result = d_sflg ? getss (is, os) : nilp;
89
// -------------------------------------------------------------------------
90
// - protected section -
91
// -------------------------------------------------------------------------
95
TlsState* TlsConnect::getss (InputStream* is, OutputStream* os) {
97
if ((is == nilp) || (os == nilp)) return nilp;
100
TlsState* ssta = nilp;
101
TlsProto* tlsp = nilp;
102
TlsChello* chlo = nilp;
103
TlsMessage* shlo = nilp;
105
// check for consistency
106
if (d_sflg == false) {
107
throw Exception ("tls-error", "invalid call to client hello get");
109
// create a server state by flag
110
ssta = new TlsState (d_sflg, d_prms);
112
// get the client hello message
113
chlo = dynamic_cast <TlsChello*> (TlsProto().getchlo (is));
115
throw Exception ("tls-error", "cannot get client hello message");
117
// update the info list
118
d_info += chlo->getinfo ();
119
// update the state version
120
ssta->setvers (chlo->getvmaj (), chlo->getvmin ());
121
// update the selected cipher
122
ssta->setcifr (chlo->getcifr ());
123
// create a tls protocol by state
124
tlsp = TlsProto::create (ssta);
125
// create a server hello message and encode it
126
shlo = tlsp->getshlo (ssta);
128
throw Exception ("tls-error", "cannot get server hello message");
130
tlsp->encode (os, shlo);
148
// -------------------------------------------------------------------------
149
// - object section -
150
// -------------------------------------------------------------------------
153
static const long QUARK_ZONE_LENGTH = 1;
154
static QuarkZone zone (QUARK_ZONE_LENGTH);
156
// the object supported quarks
157
static const long QUARK_CONNECT = zone.intern ("connect");
159
// create a new object in a generic way
161
Object* TlsConnect::mknew (Vector* argv) {
162
// get the number of arguments
163
long argc = (argv == nilp) ? 0 : argv->length ();
165
// check for 1 argument
167
bool sflg = argv->getbool (0);
168
return new TlsConnect (sflg);
170
// too many arguments
171
throw Exception ("argument-error",
172
"too many argument with tls connect constructor");
175
// return true if the given quark is defined
177
bool TlsConnect::isquark (const long quark, const bool hflg) const {
180
if (zone.exists (quark) == true) {
184
bool result = hflg ? TlsInfos::isquark (quark, hflg) : false;
193
// apply this object with a set of arguments and a quark
195
Object* TlsConnect::apply (Runnable* robj, Nameset* nset, const long quark,
197
// get the number of arguments
198
long argc = (argv == nilp) ? 0 : argv->length ();
200
// dispatch 2 arguments
202
if (quark == QUARK_CONNECT) {
203
Object* obj = argv->get (0);
204
InputStream* is = dynamic_cast <InputStream*> (obj);
206
throw Exception ("type-error", "invalid object as input stream",
210
OutputStream* os = dynamic_cast <OutputStream*> (obj);
212
throw Exception ("type-error", "invalid object as output stream",
215
return connect (is, os);
218
// call the info method
219
return TlsInfos::apply (robj, nset, quark, argv);