zxid
view release on metacpan or search on metacpan
zxbusprod.c view on Meta::CPAN
int siz = nonce + 2 + len + *zlen;
ROUND_UP(siz, nonce); /* Round up to block size */
p = ZX_ALLOC(cf->ctx, siz);
if (nonce)
zx_rand(p, nonce);
p[nonce] = (len >> 8) & 0xff;
p[nonce+1] = len & 0xff;
if (len) {
memcpy(p+nonce+2, sig, len);
ZX_FREE(cf->ctx, sig);
}
memcpy(p+nonce+2+len, zbuf, *zlen);
ZX_FREE(cf->ctx, zbuf);
*zlen += nonce + 2 + len;
return p;
}
/*() Write a line to a log, taking care of all formalities of locking and
* observing all special options for signing and encryption of the logs.
* Not usually called directly (but you can if you want to), this is the
* work horse behind zxbus().
*
* cf:: ZXID configuration object, used for memory allocation.
* c_path:: Path to the log file, as C string
* encflags:: Encryption flags. See LOG_ERR or LOG_ACT configuration options in zxidconf.h
* n:: length of log data
* logbuf:: The data that should be logged
*/
/* Called by: */
void zxbus_write_line(zxid_conf* cf, char* c_path, int encflags, int n, const char* logbuf)
{
EVP_PKEY* log_sign_pkey;
struct rsa_st* rsa_pkey;
struct aes_key_st aes_key;
int len = 0, blen, zlen;
char sigletter = 'P';
char encletter = 'P';
char* p;
char* sig = 0;
char* zbuf;
char* b64;
char sigbuf[28+4]; /* Space for "SP " and sha1 */
char keybuf[16];
char ivec[16];
if (n == -2)
n = strlen(logbuf);
if (encflags & 0x70) { /* Encrypt check */
zbuf = zx_zlib_raw_deflate(cf->ctx, n-1, logbuf, &zlen);
switch (encflags & 0x06) { /* Sign check */
case 0x02: /* Sx plain sha1 */
sigletter = 'S';
sig = ZX_ALLOC(cf->ctx, 20);
SHA1((unsigned char*)zbuf, zlen, (unsigned char*)sig);
len = 20;
break;
case 0x04: /* Rx RSA-SHA1 signature */
sigletter = 'R';
LOCK(cf->mx, "logsign-wrln");
if (!(log_sign_pkey = cf->log_sign_pkey))
log_sign_pkey = cf->log_sign_pkey = zxid_read_private_key(cf, "logsign-nopw-cert.pem");
UNLOCK(cf->mx, "logsign-wrln");
if (!log_sign_pkey)
break;
len = zxsig_data(cf->ctx, zlen, zbuf, &sig, log_sign_pkey, "enc log line", 0);
break;
case 0x06: /* Dx DSA-SHA1 signature */
ERR("DSA-SHA1 sig not implemented in encrypted mode. Use RSA-SHA1 or none. %x", encflags);
break;
case 0: break; /* Px no signing */
}
switch (encflags & 0x70) {
case 0x10: /* xZ RFC1951 zip + safe base64 */
encletter = 'Z';
zbuf = zxbus_alloc_zbuf(cf, &zlen, zbuf, len, sig, 0);
break;
case 0x20: /* xA RSA-AES */
encletter = 'A';
zbuf = zxbus_alloc_zbuf(cf, &zlen, zbuf, len, sig, 16);
zx_rand(keybuf, 16);
AES_set_encrypt_key((unsigned char*)keybuf, 128, &aes_key);
memcpy(ivec, zbuf, sizeof(ivec));
AES_cbc_encrypt((unsigned char*)zbuf+16, (unsigned char*)zbuf+16, zlen-16, &aes_key, (unsigned char*)ivec, 1);
ROUND_UP(zlen, 16); /* Round up to block size */
LOCK(cf->mx, "logenc-wrln");
if (!cf->log_enc_cert)
cf->log_enc_cert = zxid_read_cert(cf, "logenc-nopw-cert.pem");
rsa_pkey = zx_get_rsa_pub_from_cert(cf->log_enc_cert, "log_enc_cert");
UNLOCK(cf->mx, "logenc-wrln");
if (!rsa_pkey)
break;
len = RSA_size(rsa_pkey);
sig = ZX_ALLOC(cf->ctx, len);
if (RSA_public_encrypt(16, (unsigned char*)keybuf, (unsigned char*)sig, rsa_pkey, RSA_PKCS1_OAEP_PADDING) < 0) {
ERR("RSA enc fail %x", encflags);
zx_report_openssl_err("zxbus rsa enc");
return;
}
p = ZX_ALLOC(cf->ctx, 2 + len + zlen);
p[0] = (len >> 8) & 0xff;
p[1] = len & 0xff;
memcpy(p+2, sig, len);
memcpy(p+2+len, zbuf, zlen);
ZX_FREE(cf->ctx, sig);
ZX_FREE(cf->ctx, zbuf);
zbuf = p;
zlen += 2 + len;
break;
case 0x30: /* xT RSA-3DES */
encletter = 'T';
ERR("Enc not implemented %x", encflags);
break;
case 0x40: /* xB AES */
encletter = 'B';
zbuf = zxbus_alloc_zbuf(cf, &zlen, zbuf, len, sig, 16);
if (!cf->log_symkey[0])
zx_get_symkey(cf, "logenc.key", cf->log_symkey);
AES_set_encrypt_key((unsigned char*)cf->log_symkey, 128, &aes_key);
memcpy(ivec, zbuf, sizeof(ivec));
AES_cbc_encrypt((unsigned char*)zbuf+16, (unsigned char*)zbuf+16, zlen-16, &aes_key, (unsigned char*)ivec, 1);
ROUND_UP(zlen, 16); /* Round up to block size */
break;
case 0x50: /* xU 3DES */
encletter = 'U';
ERR("Enc not implemented %x", encflags);
break;
default:
ERR("Enc not implemented %x", encflags);
break;
}
blen = SIMPLE_BASE64_LEN(zlen) + 3 + 1;
b64 = ZX_ALLOC(cf->ctx, blen);
b64[0] = sigletter;
b64[1] = encletter;
b64[2] = ' ';
p = base64_fancy_raw(zbuf, zlen, b64+3, safe_basis_64, 1<<31, 0, 0, '.');
blen = p-b64 + 1;
*p = '\n';
write2_or_append_lock_c_path(c_path, 0, 0, blen, b64, "zxbus enc", SEEK_END, O_APPEND);
return;
}
/* Plain text, possibly signed. */
switch (encflags & 0x06) {
case 0x02: /* SP plain sha1 */
strcpy(sigbuf, "SP ");
sha1_safe_base64(sigbuf+3, n-1, logbuf);
sigbuf[3+27] = ' ';
len = 3+27+1;
p = sigbuf;
break;
case 0x04: /* RP RSA-SHA1 signature */
LOCK(cf->mx, "logsign-wrln");
if (!(log_sign_pkey = cf->log_sign_pkey))
log_sign_pkey = cf->log_sign_pkey = zxid_read_private_key(cf, "logsign-nopw-cert.pem");
UNLOCK(cf->mx, "logsign-wrln");
if (!log_sign_pkey)
break;
zlen = zxsig_data(cf->ctx, n-1, logbuf, &zbuf, log_sign_pkey, "log line", 0);
len = SIMPLE_BASE64_LEN(zlen) + 4;
sig = ZX_ALLOC(cf->ctx, len);
strcpy(sig, "RP ");
p = base64_fancy_raw(zbuf, zlen, sig+3, safe_basis_64, 1<<31, 0, 0, '.');
len = p-sig + 1;
*p = ' ';
p = sig;
break;
case 0x06: /* DP DSA-SHA1 signature */
ERR("DSA-SHA1 signature not implemented %x", encflags);
break;
case 0: /* Plain logging, no signing, no encryption. */
len = 5;
p = "PP - ";
break;
}
write2_or_append_lock_c_path(c_path, len, p, n, logbuf, "zxbus sig", SEEK_END, O_APPEND);
if (sig)
ZX_FREE(cf->ctx, sig);
}
/*() Helper function for formatting all kinds of logs. */
static int zxbus_fmt(zxid_conf* cf, /* 1 */
int len, char* logbuf,
struct timeval* ourts, /* 2 null allowed, will use current time */
struct timeval* srcts, /* 3 null allowed, will use start of unix epoch... */
const char* ipport, /* 4 null allowed, -:- or cf->ipport if not given */
struct zx_str* entid, /* 5 null allowed, - if not given */
struct zx_str* msgid, /* 6 null allowed, - if not given */
struct zx_str* a7nid, /* 7 null allowed, - if not given */
struct zx_str* nid, /* 8 null allowed, - if not given */
const char* sigval, /* 9 null allowed, - if not given */
const char* res, /* 10 */
const char* op, /* 11 */
const char* arg, /* 12 null allowed, - if not given */
const char* fmt, /* 13 null allowed as format, ends the line */
va_list ap)
{
int n;
char* p;
char sha1_name[28];
struct tm ot;
struct tm st;
struct timeval ourtsdefault;
struct timeval srctsdefault;
/* Prepare values */
if (!ourts) {
ourts = &ourtsdefault;
GETTIMEOFDAY(ourts, 0);
}
if (!srcts) {
srcts = &srctsdefault;
srctsdefault.tv_sec = 0;
zxbusprod.c view on Meta::CPAN
if (!he) {
ERR("hostname(%s) did not resolve(%d) bu->s(%s) host_len=%d %d host(%.*s) %p port(%s) %p", bu->m, h_errno, bu->s, host_len, MIN(host_len, ZXBUS_BUF_SIZE-2), host_len, host, host, port, port);
exit(5);
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(atoi(port+1));
memcpy(&(sin.sin_addr.s_addr), he->h_addr, sizeof(sin.sin_addr.s_addr));
if ((bu->fd = (fdtype)socket(AF_INET, SOCK_STREAM, 0)) == (fdtype)-1) {
ERR("Unable to create socket(AF_INET, SOCK_STREAM, 0) %d %s", errno, STRERROR(errno));
return 0;
}
#if 0
nonblock(bu->fd);
if (nkbuf)
setkernelbufsizes(bu->fd, nkbuf, nkbuf);
#endif
D("connecting(%x) hs(%s)", bu->fd, bu->s);
if ((connect((SOCKET)bu->fd, (struct sockaddr*)&sin, sizeof(sin)) == -1) && (errno != EINPROGRESS)) {
ERR("Connection to %s failed: %d %s", bu->s, errno, STRERROR(errno));
goto errout;
}
D("connected(%x) at TCP layer hs(%s)", bu->fd, bu->s);
if (tls) {
#ifdef USE_OPENSSL
if (!cf->ssl_ctx) {
SSL_load_error_strings();
SSL_library_init();
#if 0
cf->ssl_ctx = SSL_CTX_new(SSLv23_method());
#else
cf->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
#endif
}
if (!cf->ssl_ctx) {
ERR("TLS/SSL connection to(%s) can not be made. SSL context initialization problem", bu->s);
zx_report_openssl_err("open_bus_url-ssl_ctx");
goto errout;
} else {
if (errmac_debug>1) {
D("OpenSSL header-version(%lx) lib-version(%lx)(%s) %s %s %s %s", OPENSSL_VERSION_NUMBER, SSLeay(), SSLeay_version(SSLEAY_VERSION), SSLeay_version(SSLEAY_CFLAGS), SSLeay_version(SSLEAY_BUILT_ON), SSLeay_version(SSLEAY_PLATFORM), SSLeay_version(SSLEA...
SSL_CTX_set_info_callback(cf->ssl_ctx, zx_ssl_info_cb);
}
SSL_CTX_set_mode(cf->ssl_ctx, SSL_MODE_AUTO_RETRY); /* R/W only return when complete. */
/* Verification strategy: do not attempt verification at SSL layer. Instead
* check the result afterwards against metadata based cert. */
SSL_CTX_set_verify(cf->ssl_ctx, SSL_VERIFY_NONE,0);
//SSL_CTX_set_verify(cf->ssl_ctx, SSL_VERIFY_PEER,0);
//SSL_CTX_set_cert_verify_callback(cf->ssl_ctx, zxbus_cert_verify_cb, cf);
/*SSL_CTX_load_verify_locations() SSL_CTX_set_client_CA_list(3) SSL_CTX_set_cert_store(3) */
LOCK(cf->mx, "logenc wrln");
if (!cf->enc_cert)
cf->enc_cert = zxid_read_cert(cf, "enc-nopw-cert.pem");
if (!cf->enc_pkey)
cf->enc_pkey = zxid_read_private_key(cf, "enc-nopw-cert.pem");
UNLOCK(cf->mx, "logenc wrln");
if (!SSL_CTX_use_certificate(cf->ssl_ctx, cf->enc_cert)) {
ERR("TLS/SSL connection to(%s) can not be made. SSL certificate problem", bu->s);
zx_report_openssl_err("open_bus_url-cert");
goto errout;
}
if (!SSL_CTX_use_PrivateKey(cf->ssl_ctx, cf->enc_pkey)) {
ERR("TLS/SSL connection to(%s) can not be made. SSL private key problem", bu->s);
zx_report_openssl_err("open_bus_url-privkey");
goto errout;
}
if (!SSL_CTX_check_private_key(cf->ssl_ctx)) {
ERR("TLS/SSL connection to(%s) can not be made. SSL certificate-private key consistency problem", bu->s);
zx_report_openssl_err("open_bus_url-chk-privkey");
goto errout;
}
/*SSL_CTX_add_extra_chain_cert(cf->ssl_ctx, ca_cert);*/
}
bu->ssl = SSL_new(cf->ssl_ctx);
if (!bu->ssl) {
ERR("TLS/SSL connection to(%s) can not be made. SSL object initialization problem", bu->s);
zx_report_openssl_err("open_bus_url-ssl");
goto errout;
}
if (!SSL_set_fd(bu->ssl, (int)bu->fd)) {
ERR("TLS/SSL connection to(%s) can not be made. SSL fd(%x) initialization problem", bu->s, bu->fd);
zx_report_openssl_err("open_bus_url-set_fd");
goto sslerrout;
}
switch (vfy_err = SSL_get_error(bu->ssl, SSL_connect(bu->ssl))) {
case SSL_ERROR_NONE: break;
/*case SSL_ERROR_WANT_ACCEPT: documented, but undeclared */
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_WANT_WRITE:
default:
ERR("TLS/SSL connection to(%s) can not be made. SSL connect or handshake problem (%ld)", bu->s, vfy_err);
zx_report_openssl_err("open_bus_url-ssl_connect");
send((SOCKET)bu->fd, SSL_ENCRYPTED_HINT, sizeof(SSL_ENCRYPTED_HINT)-1, 0);
goto sslerrout;
}
if (errmac_debug>1) D("SSL_version(%s) cipher(%s)",SSL_get_version(bu->ssl),SSL_get_cipher(bu->ssl));
vfy_err = SSL_get_verify_result(bu->ssl);
switch (vfy_err) {
case X509_V_OK: break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
D("TLS/SSL connection to(%s) made, but certificate err. (%ld)", bu->s, vfy_err);
zx_report_openssl_err("open_bus_url-verify_res");
break;
default:
ERR("TLS/SSL connection to(%s) made, but certificate not acceptable. (%ld)", bu->s, vfy_err);
zx_report_openssl_err("open_bus_url-verify_res");
goto sslerrout;
}
if (!(peer_cert = SSL_get_peer_certificate(bu->ssl))) {
ERR("TLS/SSL connection to(%s) made, but peer did not send certificate", bu->s);
zx_report_openssl_err("open_bus_url-peer_cert");
goto sslerrout;
}
meta = zxid_get_ent(cf, bu->eid);
if (!meta) {
ERR("Unable to find metadata for eid(%s) in verify peer cert", bu->eid);
goto sslerrout;
}
if (!meta->enc_cert) {
ERR("Metadata for eid(%s) does not contain enc cert", bu->eid);
goto sslerrout;
}
( run in 2.291 seconds using v1.01-cache-2.11-cpan-ad19def0cd9 )