/* * Secure eXtended Message Passing framework * Secure eXtended Transport layer implementation: (libsxt) * - very similar to SSH2/TLS * - using already proven and tested crypto algos * - better than TLS for message passing * * (c) Alexander Vdolainen 2016 * * libsxmp is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * libsxmp is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see ."; * */ #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #define EBADE 1 #define NETDB_SUCCESS 0 #else #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include int sxt_init(void) { /* init SSL library */ SSL_library_init(); OpenSSL_add_all_algorithms(); if(sodium_init() == -1) return SXT_ERROR; return lcrypt_init_ciphers(); } int sxt_finish(void) { EVP_cleanup(); CRYPTO_cleanup_all_ex_data(); return 0; } int sxt_reseed(void) { return lcrypt_reseed(); } int sxt_get_random(void *data, int len, int pseudo) { randombytes_buf(data, (size_t) len); return 1; } int sxt_genbeer(sxtsession_t *session, sxtsafebuffer_t *o) { char *beer; if(!o || !session) return SXT_EINVAL; if(!session->linkset) return SXT_EINVAL; if(!(beer = malloc(128))) return SXT_ENOMEM; else memset(beer, 0, 128); snprintf(beer, 128, "sxtbeer-%s-%d-%lu-%s", SXTBEER_TYPE, SXTPROTO_VERSION, session->linkset->hash, session->linkset->strctx ? session->linkset->strctx : "nil"); sxtsafebuffer_setdata(o, beer, strlen(beer)); return SXT_SUCCESS; } int sxt_scanbeer(sxtsession_t *session, const char *rbuf, size_t rlen) { char *buf = (char *)rbuf, *tbuf; char tuple[32]; uint64_t hash = 0; int i, st, version, len = 0; if(!session || !rbuf) return SXT_EINVAL; if(!rlen || !session->peerbeer) return SXT_EINVAL; memset(tuple, 0, 32); for(i = 0, tbuf = NULL, st = 0; i < rlen; i++, buf++) { switch(st) { case 0: /* first tuple */ if(!tbuf) tbuf = buf; if(*buf == '-') { if(i != strlen("sxtbeer")) return SXT_EPROTO; if(strncmp(tbuf, "sxtbeer", i)) return SXT_EPROTO; /* that's wine! */ st++; tbuf = NULL; } break; case 1: if(!tbuf) tbuf = buf; if(*buf == '-') { len = strlen(tbuf) - strlen(buf); if(len < 1 || len >= 32) return SXT_EPROTO; memcpy(tuple, tbuf, len); /* currently one type supported */ if(strcmp(tuple, SXTBEER_TYPE)) return SXT_EPROTO; memset(tuple, 0, 32); tbuf = NULL; st++; } break; case 2: if(!tbuf) tbuf = buf; if(*buf == '-') { len = strlen(tbuf) - strlen(buf); if(len < 1 || len >= 32) return SXT_EPROTO; memcpy(tuple, tbuf, len); version = atoi(tuple); /* first version supported only */ if(version != SXTPROTO_VERSION) return SXT_EPROTO; memset(tuple, 0, 32); tbuf = NULL; st++; } break; case 3: /* hash value */ if(!tbuf) tbuf = buf; if(*buf == '-') { len = strlen(tbuf) - strlen(buf); if(len < 1 || len >= 32) return SXT_EPROTO; memcpy(tuple, tbuf, len); hash = strtoul(tuple, NULL, 0); memset(tuple, 0, 32); tbuf = NULL; st++; } break; case 4: /* the rest of buffer is some custom plate */ if(!tbuf) { tbuf = buf; len = i; memset(tuple, 0, 32); } break; } } /* ok check for validity */ if(st < 3) return SXT_EPROTO; if(!tbuf) return SXT_EPROTO; else len = rlen - len; if(len >= 32 || len < 1) return SXT_EPROTO; else memcpy(tuple, tbuf, len); session->sxt_version = version; session->peer_swhash = hash; if(sxtsafebuffer_length(session->peerbeer) < 128) return SXT_ENOMEM; /* no room for peer beer */ snprintf((char *)sxtsafebuffer_getdata(session->peerbeer), 128, "sxtbeer-%s-%d-%lu-%s", SXTBEER_TYPE, session->sxt_version, session->peer_swhash, tuple); return SXT_SUCCESS; } /* wrappers */ SHA512CTX sha512_init(void){ SHA512CTX c = malloc(sizeof(*c)); if (c == NULL) { return NULL; } SHA512_Init(c); return c; } void sha512_update(SHA512CTX c, const void *data, unsigned long len){ SHA512_Update(c,data,len); } void sha512_final(unsigned char *md, SHA512CTX c) { SHA512_Final(md, c); if(c) free(c); }