summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorme_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac>2013-08-21 12:57:33 +0000
committerme_desk <me_desk@fb96df88-216d-11de-830c-f3023f12d8ac>2013-08-21 12:57:33 +0000
commit255f83d5109d7ddeab1c9a343292f2cfbcf10651 (patch)
treeaacdb6793cf3cbd73b549ba45d90e9c8508c7757
parent14af4d5f8b4b59f463d4250fa1c2600e82d22fbe (diff)
downloadpica-pica-255f83d5109d7ddeab1c9a343292f2cfbcf10651.tar.gz
pica-pica-255f83d5109d7ddeab1c9a343292f2cfbcf10651.zip
changed client library code for handling new 224bit client id
git-svn-id: svn://localhost/project_picapica/trunk@262 fb96df88-216d-11de-830c-f3023f12d8ac
-rwxr-xr-xPICA_client.c148
-rwxr-xr-xPICA_client.h36
-rwxr-xr-xPICA_msgproc.c2
-rwxr-xr-xPICA_msgproc.h2
4 files changed, 110 insertions, 78 deletions
diff --git a/PICA_client.c b/PICA_client.c
index ef8c638..8d31e50 100755
--- a/PICA_client.c
+++ b/PICA_client.c
@@ -67,7 +67,7 @@ struct PICA_msginfo c2n_init_messages[] = {
//buf[size - 1] = 0;
//return(strlen(buf));
//}
-
+/*
//функция возвращает номер клиента id в бинарном виде, извлекая его из строки,
//которая возвращается функцией X509_NAME_oneline и представляет собой DN из сертификата клиента
static int get_id_fromsubjstr(char* DN_str,unsigned int* id)
@@ -97,41 +97,56 @@ if (tmp1==tmp2)
*tmp2='#';
return 1;
}
+*/
+int get_id_from_X509(X509 *x, unsigned char *id)
+{
+unsigned char *der = NULL;
+int len;
+
+len = i2d_X509(x, &der);
- int PICA_get_id_from_cert(const char *cert_file, unsigned int *p_id)
- {
- char *DN_str;
- X509 *x;
- FILE *f;
+if (len <= 0)
+{
+ return 0;
+}
- f=fopen(cert_file,"r");
+SHA224(der, len, id);
- if (!f)
- {
- perror(cert_file);
- return 0;
- }
+OPENSSL_free(der);
+
+return 1;
+}
+
+int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id)
+{
+X509 *x;
+FILE *f;
- x=PEM_read_X509(f,0,0,0);
- fclose(f);
+f=fopen(cert_file,"r");
- DN_str=X509_NAME_oneline(X509_get_subject_name(x), 0, 0);
+if (!f)
+{
+ perror(cert_file);
+ return 0;
+}
- if (!get_id_fromsubjstr(DN_str,p_id))
- {
- OPENSSL_free(DN_str);
- return 0;
- }
- //printf("my id is %u\n",*p_id);//debug
- //puts(DN_str);//debug
+x=PEM_read_X509(f,0,0,0);
+fclose(f);
- OPENSSL_free(DN_str);
- return 1;
- }
+if (!x)
+{
+ return 0;
+}
+return get_id_from_X509(x, id);
+}
+static int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
+{ //return 1 for self-signed certificates
+ return preverify_ok;
+}
-static int add_chaninfo(struct PICA_conninfo *ci,struct PICA_chaninfo **chn,unsigned int uid,int is_outgoing)
+static int add_chaninfo(struct PICA_conninfo *ci, struct PICA_chaninfo **chn, const unsigned char *peer_id, int is_outgoing)
{
struct PICA_chaninfo *chnl,*ipt;
@@ -140,9 +155,9 @@ chnl=*chn=(struct PICA_chaninfo*)calloc(sizeof(struct PICA_chaninfo),1);
if (!chnl)
return 0;//ERR_CHECK
-chnl->conn=ci;
-chnl->outgoing=is_outgoing;
-chnl->peer_id=uid;
+chnl->conn = ci;
+chnl->outgoing = is_outgoing;
+memcpy(chnl->peer_id, peer_id, PICA_ID_SIZE);
chnl->timestamp = time(0);
@@ -194,14 +209,13 @@ if (mp)
{
if (chnl->outgoing)
{
- *(unsigned int*)(mp->tail) = chnl->conn->id;//вызвывающий
- *(unsigned int*)(mp->tail + 4) = chnl->peer_id;//вызываемый
+ memcpy(mp->tail, chnl->conn->id, PICA_ID_SIZE);//вызвывающий
+ memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый
}
else
{
- //puts("callee CONNID");//debug
- *(unsigned int*)(mp->tail) = chnl->peer_id;//вызвывающий
- *(unsigned int*)(mp->tail + 4) = chnl->conn->id;//вызываемый
+ memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий
+ memcpy(mp->tail + PICA_ID_SIZE, chnl->conn->id, PICA_ID_SIZE);//вызываемый
}
}
else
@@ -209,7 +223,7 @@ else
err_ret=PICA_ERRNOMEM;
goto error_ret;
}
-//ret=send(chnl->sck_data,buf,PICA_PROTO_CONNID_SIZE,0);
+
do
{
err_ret = PICA_write_c2c(chnl);
@@ -236,7 +250,9 @@ if (!ret)
goto error_ret_;
}
-SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER,0);
+SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER, verify_callback);
+SSL_set_verify_depth(chnl->ssl, 1);//peer certificate and one CA
+
if (chnl->outgoing)
ret=SSL_connect(chnl->ssl);
@@ -263,6 +279,22 @@ if (!chnl->peer_cert)
goto error_ret_;
}
+{
+unsigned char temp_id[PICA_ID_SIZE];
+
+if (get_id_from_X509(chnl->peer_cert, temp_id) == 0)
+ {
+ err_ret=PICA_ERRNOPEERCERT;
+ goto error_ret_;
+ }
+
+if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0)
+ {
+ err_ret=PICA_ERRINVPEERCERT;
+ goto error_ret_;
+ }
+}
+/*
DN_str=X509_NAME_oneline(X509_get_subject_name(chnl->peer_cert), 0, 0);
if (!DN_str)
@@ -279,7 +311,9 @@ if (!get_id_fromsubjstr(DN_str,&tmp_uid) || tmp_uid!=chnl->peer_id)
}
//puts(DN_str);//debug
-OPENSSL_free(DN_str);
+OPENSSL_free(DN_str);*/
+
+
{
BIO *mem = BIO_new(BIO_s_mem());
@@ -339,9 +373,10 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf,unsigned int nb,void*
int ret;
struct PICA_conninfo *ci=(struct PICA_conninfo *)p;
struct PICA_proto_msg *mp;
+unsigned char *peer_id = buf + 2;
- if (callbacks.accept_cb(*(unsigned int*)(buf+2)))
+ if (callbacks.accept_cb(peer_id))
{
struct PICA_chaninfo *_chnl;
@@ -349,12 +384,12 @@ struct PICA_proto_msg *mp;
if (mp)
{
- *(unsigned int*)(mp->tail) = *(unsigned int*)(buf+2);
+ memcpy(mp->tail, peer_id, PICA_ID_SIZE);
}
else
return 0;
- ret = add_chaninfo( ci, &_chnl, *(unsigned int*)(buf+2), 0);
+ ret = add_chaninfo( ci, &_chnl, peer_id, 0);
if (!ret)
return 0; //ERR_CHECK - кончилась память
@@ -378,11 +413,11 @@ struct PICA_proto_msg *mp;
}
else
{
- mp = c2n_writebuf_push( ci, PICA_PROTO_CONNDENY, PICA_PROTO_CONNDENY_SIZE);
+ mp = c2n_writebuf_push(ci, PICA_PROTO_CONNDENY, PICA_PROTO_CONNDENY_SIZE);
if (mp)
{
- *(unsigned int*)(mp->tail) = *(unsigned int*)(buf+2);
+ memcpy(mp->tail, peer_id, PICA_ID_SIZE);
}
else
return 0;//ERR_CHECK
@@ -394,19 +429,20 @@ static unsigned int procmsg_NOTFOUND(unsigned char* buf,unsigned int nb,void* p)
{
struct PICA_conninfo *ci=(struct PICA_conninfo *)p;
struct PICA_chaninfo *ipt,*rq=0;
+unsigned char *peer_id = buf + 2;
//puts("procmsg_NOTFOUND");//debug
ipt=ci->chan_list_end;
while(ipt)
{
- if (ipt->peer_id==*(unsigned int*)(buf+2))
+ if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0)
{
rq=ipt;
break;
}
ipt=ipt->prev;
- }
+ }
if (!rq)
return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался
@@ -416,7 +452,7 @@ PICA_close_channel(rq);
//puts("procmsg_NOTFOUND_chkp1");//debug
-callbacks.notfound_cb(*(unsigned int*)(buf+2));
+callbacks.notfound_cb(peer_id);
return 1;
}
@@ -424,12 +460,13 @@ static unsigned int procmsg_FOUND(unsigned char* buf,unsigned int nb,void* p)
{
struct PICA_conninfo *ci=(struct PICA_conninfo *)p;
struct PICA_chaninfo *ipt,*rq=0;
+unsigned char *peer_id = buf + 2;
int ret;
ipt=ci->chan_list_end;
while(ipt)
{
- if (ipt->peer_id==*(unsigned int*)(buf+2))
+ if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0)
{
rq=ipt;
break;
@@ -698,7 +735,7 @@ if (!cid->ctx)
goto error_ret_2;
}
-if (!PICA_get_id_from_cert(cert_file, &cid->id))
+if (!PICA_get_id_from_cert(cert_file, cid->id))
{
ret_err=PICA_ERRINVCERT;
goto error_ret_3;
@@ -707,7 +744,7 @@ if (!PICA_get_id_from_cert(cert_file, &cid->id))
if (password_cb)
{
SSL_CTX_set_default_passwd_cb(cid->ctx, password_cb);
- SSL_CTX_set_default_passwd_cb_userdata(cid->ctx,&cid->id);
+ SSL_CTX_set_default_passwd_cb_userdata(cid->ctx,cid->id);
}
ret=SSL_CTX_use_certificate_file(cid->ctx,cert_file,SSL_FILETYPE_PEM);
@@ -894,20 +931,15 @@ return ret_err;
//создает ИСХОДЯЩИЙ логический зашифрованный канал связи с указанным собеседником, если тот доступен
// в данный момент.
-
-int PICA_create_channel(struct PICA_conninfo *ci,unsigned int uid,struct PICA_chaninfo **chn)
+int PICA_create_channel(struct PICA_conninfo *ci,const unsigned char *peer_id,struct PICA_chaninfo **chn)
{
struct PICA_proto_msg *mp;
struct PICA_chaninfo *chnl;
-char* DN_str;
-unsigned char buf[12];
-int ret,err_ret;
if (!(ci && chn))
return PICA_ERRINVARG;
-
-if (!add_chaninfo(ci,chn,uid,1))
+if (!add_chaninfo(ci, chn, peer_id, PICA_CHANNEL_OUTGOING))
return PICA_ERRNOMEM;
chnl=*chn;
@@ -916,17 +948,13 @@ mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE)
if (mp)
{
- *(unsigned int*)(mp->tail)=uid;
+ memcpy(mp->tail, peer_id, PICA_ID_SIZE);
}
else
return PICA_ERRNOMEM;
return PICA_OK;
-
-//сделать нормальную обработку ошибок - со стековой последовательностью деинициализирующих процедур (!!??)
-// в этой функции и в предыдущей
-
}
int PICA_read(struct PICA_conninfo *ci,int timeout)
diff --git a/PICA_client.h b/PICA_client.h
index d98a607..b71e8bf 100755
--- a/PICA_client.h
+++ b/PICA_client.h
@@ -36,6 +36,7 @@ typedef unsigned __int16 uint16_t;
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/rand.h>
+#include <openssl/sha.h>
#ifdef PICA_MULTITHREADED
@@ -83,6 +84,11 @@ typedef unsigned __int16 uint16_t;
#define PICA_CHAN_ACTIVATE_TIMEOUT 30
+#define PICA_ID_SIZE SHA224_DIGEST_LENGTH
+
+#define PICA_CHANNEL_INCOMING 0
+#define PICA_CHANNEL_OUTGOING 1
+
struct PICA_conninfo;
struct PICA_chaninfo;
@@ -90,13 +96,11 @@ struct PICA_conninfo
{
//#warning "sockaddr!"
struct sockaddr_in srv_addr; // sockaddr !!
-unsigned int id;
+unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format
SSL_CTX* ctx;
SOCKET sck_comm;
SSL* ssl_comm;
-//сертификат клиента
-// unsigned char r_buf[128];
-// unsigned int r_pos;
+
int state;
@@ -116,7 +120,7 @@ unsigned char node_ver_major, node_ver_minor;
struct PICA_chaninfo
{
struct PICA_conninfo *conn;//соединение с сервером, через которое установлен данный логический канал связи
-unsigned int peer_id;//номер собеседника
+unsigned char peer_id[PICA_ID_SIZE];
SOCKET sck_data;
SSL *ssl;
int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником
@@ -138,24 +142,24 @@ time_t timestamp;
struct PICA_client_callbacks
{
//получение сообщения.
-void (*newmsg_cb)(unsigned int peer_id,char* msgbuf,unsigned int nb,int type);
+void (*newmsg_cb)(const unsigned char *peer_id,char* msgbuf,unsigned int nb,int type);
//получение подтверждения о доставке сообщения
-void (*msgok_cb)(unsigned int peer_id);
+void (*msgok_cb)(const unsigned char *peer_id);
//создание канала с собеседником
-void (*channel_established_cb)(unsigned int peer_id);
+void (*channel_established_cb)(const unsigned char *peer_id);
//создать канал не удалось
-void (*channel_failed)(unsigned int peer_id);
+void (*channel_failed)(const unsigned char *peer_id);
//входящий запрос на создание канала от пользователя с номером caller_id
//возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос
-int (*accept_cb)(unsigned int caller_id);
+int (*accept_cb)(const unsigned char *caller_id);
//запрошенный пользователь не найден, в оффлайне или отказался от общения
-void (*notfound_cb)(unsigned int callee_id);
+void (*notfound_cb)(const unsigned char *callee_id);
//
-void (*channel_closed_cb)(unsigned int peer_id, int reason);
+void (*channel_closed_cb)(const unsigned char *peer_id, int reason);
void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port);
//сертификат собеседника в формате PEM. Функция должна сравнить предъявленный сертификат с сохранённым (если есть) и вернуть 1 при успешной проверке, 0 - при неуспешной
-int (*peer_cert_verify_cb)(unsigned int peer_id, const char *cert_pem, unsigned int nb);
+int (*peer_cert_verify_cb)(const unsigned char *peer_id, const char *cert_pem, unsigned int nb);
};
@@ -164,7 +168,8 @@ int (*peer_cert_verify_cb)(unsigned int peer_id, const char *cert_pem, unsigned
extern "C" {
#endif
-int PICA_get_id_from_cert(const char *cert_file, unsigned int *p_id);
+//read certificate from cert_file in PEM format, store id in buffer pointed by id
+int PICA_get_id_from_cert(const char *cert_file, unsigned char *id);
int PICA_client_init(struct PICA_client_callbacks *clcbs);
int PICA_new_connection
@@ -173,11 +178,10 @@ int PICA_new_connection
const char *CA_file,
const char *cert_file,
const char *pkey_file,
- //const char* password,
int (*password_cb)(char *buf, int size, int rwflag, void *userdata),
struct PICA_conninfo **ci);
-int PICA_create_channel(struct PICA_conninfo *ci,unsigned int uid,struct PICA_chaninfo **chn);
+int PICA_create_channel(struct PICA_conninfo *ci,const unsigned char *peer_id,struct PICA_chaninfo **chn);
int PICA_read_c2n(struct PICA_conninfo *ci);
int PICA_read(struct PICA_conninfo *ci,int timeout);
diff --git a/PICA_msgproc.c b/PICA_msgproc.c
index 78987c6..1564af7 100755
--- a/PICA_msgproc.c
+++ b/PICA_msgproc.c
@@ -60,7 +60,7 @@ for (i=0;i<nmsg;i++)
return 0;
}
-unsigned int PICA_processdatastream(unsigned char *buf,unsigned int *read_pos,void* arg,struct PICA_msginfo *msgs,unsigned int nmsg)
+unsigned int PICA_processdatastream(unsigned char *buf,unsigned int *read_pos,void* arg, const struct PICA_msginfo *msgs,unsigned int nmsg)
{
while(*read_pos)
{
diff --git a/PICA_msgproc.h b/PICA_msgproc.h
index 5bcab20..0bf144e 100755
--- a/PICA_msgproc.h
+++ b/PICA_msgproc.h
@@ -20,5 +20,5 @@ unsigned int PICA_msggetsize(unsigned char *buf,unsigned int nb,struct PICA_msgi
unsigned int PICA_processmsg(unsigned char *buf,unsigned int size,void* arg,struct PICA_msginfo *msgs,unsigned int nmsg);
-unsigned int PICA_processdatastream(unsigned char *buf,unsigned int *read_pos,void* arg,struct PICA_msginfo *msgs,unsigned int nmsg);
+unsigned int PICA_processdatastream(unsigned char *buf,unsigned int *read_pos,void* arg,const struct PICA_msginfo *msgs,unsigned int nmsg);
#endif