summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PICA_client.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/PICA_client.c b/PICA_client.c
index 0a59af8..239260d 100644
--- a/PICA_client.c
+++ b/PICA_client.c
@@ -61,6 +61,7 @@ static struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned i
static int process_first_async_connect_result(int connect_ret);
static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen);
+static int process_async_ssl_errors(SSL *ssl, int ret);
static int PICA_write_c2n(struct PICA_c2n *ci);
static int PICA_write_c2c(struct PICA_c2c *chn);
@@ -1777,6 +1778,24 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_
return PICA_OK;
}
+static int process_async_ssl_errors(SSL *ssl, int ret)
+{
+ if (ret < 0)
+ switch(SSL_get_error(ssl, ret))
+ {
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ break;
+ default:
+ return PICA_ERRSSL;
+ };
+
+ if (ret == 0)
+ return PICA_ERRDISCONNECT;
+
+ return PICA_OK;
+}
+
static int process_first_async_connect_result(int connect_ret)
{
if (connect_ret == SOCKET_ERROR)
@@ -2051,6 +2070,28 @@ static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_dir
return NULL;
}
+static int directc2c_verify_peer_cert(struct PICA_directc2c *d, struct PICA_c2c *c2c)
+{
+ unsigned char idbuf[PICA_ID_SIZE];
+
+ d->peer_cert = SSL_get_peer_certificate(d->ssl);
+
+ if (!d->peer_cert)
+ return PICA_ERRNOPEERCERT;
+
+ if (PICA_id_from_X509(d->peer_cert, idbuf) == 0)
+ {
+ return PICA_ERRNOPEERCERT;
+ }
+
+ if (memcmp(idbuf, c2c->peer_id, PICA_ID_SIZE) != 0)
+ {
+ return PICA_ERRINVPEERCERT;
+ }
+
+ return PICA_OK;
+}
+
static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds)
{
struct PICA_directc2c *d;
@@ -2151,6 +2192,25 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds)
break;
case PICA_DIRECTC2C_CONNSTATE_WAITINGTLS:
+ if (FD_ISSET(d->sck, wfds) || FD_ISSET(d->sck, rfds))
+ {
+ ret = SSL_connect(d->ssl);
+
+ ret = process_async_ssl_errors(d->ssl, ret);
+
+ if (ret != PICA_OK)
+ break;
+
+ ret = directc2c_verify_peer_cert(d, c2c);
+
+ if (ret != PICA_OK)
+ break;
+
+ d->state = PICA_DIRECTC2C_STATE_ACTIVE;
+
+ ---//? send switch message
+
+ }
break;
case PICA_DIRECTC2C_CONNSTATE_FAILED:
@@ -2269,6 +2329,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd
if (s >= 0)
{
+ IOCTLSETNONBLOCKINGSOCKET(s, 1);
listener_add_connection(lst, s);
}
}