Exemple #1
0
void ERR_error_string_n(unsigned long e, char *buf, size_t len)
{
    char lsbuf[64], fsbuf[64], rsbuf[64];
    const char *ls, *fs, *rs;
    unsigned long l, f, r;

    if (len == 0)
        return;

    l = ERR_GET_LIB(e);
    f = ERR_GET_FUNC(e);
    r = ERR_GET_REASON(e);

    ls = ERR_lib_error_string(e);
    fs = ERR_func_error_string(e);
    rs = ERR_reason_error_string(e);

    if (ls == NULL)
        BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
    if (fs == NULL)
        BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
    if (rs == NULL)
        BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);

    BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf,
                 fs ? fs : fsbuf, rs ? rs : rsbuf);
    if (strlen(buf) == len - 1) {
        /*
         * output may be truncated; make sure we always have 5
         * colon-separated fields, i.e. 4 colons ...
         */
#define NUM_COLONS 4
        if (len > NUM_COLONS) { /* ... if possible */
            int i;
            char *s = buf;

            for (i = 0; i < NUM_COLONS; i++) {
                char *colon = strchr(s, ':');
                if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) {
                    /*
                     * set colon no. i at last possible position (buf[len-1]
                     * is the terminating 0)
                     */
                    colon = &buf[len - 1] - NUM_COLONS + i;
                    *colon = ':';
                }
                s = colon + 1;
            }
        }
    }
}
static void
print_err(int val)
{
	int err;
	printf("Error was %d\n", val);

	while ((err = ERR_get_error())) {
		const char *msg = (const char*)ERR_reason_error_string(err);
		const char *lib = (const char*)ERR_lib_error_string(err);
		const char *func = (const char*)ERR_func_error_string(err);

		printf("%s in %s %s\n", msg, lib, func);
	}
}
static gssize
log_transport_tls_write_method(LogTransport *s, const gpointer buf, gsize buflen)
{
  LogTransportTLS *self = (LogTransportTLS *) s;
  gint ssl_error;
  gint rc;

  /* assume that we need to poll our output for writing unless
   * SSL_ERROR_WANT_READ is specified by libssl */

  self->super.cond = G_IO_OUT;

  rc = SSL_write(self->tls_session->ssl, buf, buflen);

  if (rc < 0)
    {
      ssl_error = SSL_get_error(self->tls_session->ssl, rc);
      switch (ssl_error)
        {
        case SSL_ERROR_WANT_READ:
          /* although we are writing this fd, libssl wants to read. This
           * happens during renegotiation for example */
          self->super.cond = G_IO_IN;
          errno = EAGAIN;
          break;
        case SSL_ERROR_WANT_WRITE:
          errno = EAGAIN;
          break;
        case SSL_ERROR_SYSCALL:
          /* errno is set accordingly */
          break;
        default:
          goto tls_error;
        }
    }

  return rc;

 tls_error:

  ssl_error = ERR_get_error();
  msg_error("SSL error while writing stream",
            evt_tag_printf("tls_error", "%s:%s:%s", ERR_lib_error_string(ssl_error), ERR_func_error_string(ssl_error), ERR_reason_error_string(ssl_error)),
            NULL);
  ERR_clear_error();

  errno = EPIPE;
  return -1;
}
Exemple #4
0
static void
event_error_handler(struct bufferevent *bev, short what, void *ctx)
{
	struct bufferevent *partner = NULL;
	ssh_session_t *session = ctx;
	
	if(session == NULL || session->owner_ptr == NULL) {
		trace_err("ERROR: .....................");
	} else {
		partner= session->owner_ptr;
	}
	if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
		if (what & BEV_EVENT_ERROR) {
			unsigned long err;
			while ((err = (bufferevent_get_openssl_error(bev)))) {
				const char *msg = (const char*)ERR_reason_error_string(err);
				const char *lib = (const char*)ERR_lib_error_string(err);
				const char *func = (const char*)ERR_func_error_string(err);
				fprintf(stderr, "%s in %s %s\n", msg, lib, func);
			}
			if (errno) {
				trace_err("connection error");
			}
		}
		
		if (partner) {
			/* Flush all pending data */
			data_read_handler(bev, ctx);
			if (evbuffer_get_length(bufferevent_get_output(partner))) {
				/* We still have to flush data from the other
				 * side, but when that's done, close the other
				 * side.
				 */
				bufferevent_setcb(partner,
				    NULL, close_on_finished_writecb,
				    event_error_handler, NULL);
				bufferevent_disable(partner, EV_READ);
			} else {
				/* We have nothing left to say to the other
				 * side; close it. 
				 */
				bufferevent_free(partner);
				ssh_log(session, "\"%s:closed\"", SESSION_TYPE(session));
			}
		}
		bufferevent_free(bev);
	}
}
Exemple #5
0
static dsk_boolean
do_handshake (DskSslStream *stream_ssl, DskError **error)
{
  int rv;
  //DEBUG (stream_ssl, ("do_handshake[client=%u]: start", stream_ssl->is_client));
  rv = SSL_do_handshake (stream_ssl->ssl);
  if (rv <= 0)
    {
      int error_code = SSL_get_error (stream_ssl->ssl, rv);
      unsigned long l = ERR_peek_error();
      switch (error_code)
	{
	case SSL_ERROR_NONE:
	  stream_ssl->handshaking = 0;
          dsk_ssl_stream_update_traps (stream_ssl);
	  break;
	case SSL_ERROR_SYSCALL:
          dsk_set_error (error, "error with underlying stream");
          return DSK_FALSE;
          break;
	case SSL_ERROR_WANT_READ:
          stream_ssl->read_needed_to_handshake = 1;
          stream_ssl->write_needed_to_handshake = 0;
          dsk_ssl_stream_update_traps (stream_ssl);
	  break;
	case SSL_ERROR_WANT_WRITE:
          stream_ssl->read_needed_to_handshake = 0;
          stream_ssl->write_needed_to_handshake = 1;
          dsk_ssl_stream_update_traps (stream_ssl);
	  break;
	default:
	  {
	    dsk_set_error (error,
			 "error doing-handshake on SSL socket: %s: %s [code=%08lx (%lu)] [rv=%d]",
			 ERR_func_error_string(l),
			 ERR_reason_error_string(l),
			 l, l, error_code);
	    return DSK_FALSE;
	  }
	}
    }
  else
    {
      stream_ssl->handshaking = 0;
      dsk_ssl_stream_update_traps (stream_ssl);
    }
  return DSK_TRUE;
}
Exemple #6
0
static void
eventcb(struct bufferevent *bev, short what, void *ctx)
{
	struct bufferevent *partner = ctx;

	if (what & (BEV_EVENT_EOF|BEV_EVENT_ERROR)) {
		if (what & BEV_EVENT_ERROR) {
			unsigned long err;
			while ((err = (bufferevent_get_openssl_error(bev)))) {
				const char *msg = (const char*)
				    ERR_reason_error_string(err);
				const char *lib = (const char*)
				    ERR_lib_error_string(err);
				const char *func = (const char*)
				    ERR_func_error_string(err);
				fprintf(stderr,
				    "%s in %s %s\n", msg, lib, func);
			}
			if (errno)
				perror("connection error");
		}

		if (partner) {
			/* Flush all pending data */
			readcb(bev, ctx);

			if (evbuffer_get_length(
				    bufferevent_get_output(partner))) {
				/* We still have to flush data from the other
				 * side, but when that's done, close the other
				 * side. */
				bufferevent_setcb(partner,
				    NULL, close_on_finished_writecb,
				    eventcb, NULL);
				bufferevent_disable(partner, EV_READ);
			} else {
				/* We have nothing left to say to the other
				 * side; close it. */
				bufferevent_free(partner);
			}
		}
		bufferevent_free(bev);
	}
}
Exemple #7
0
/* XXXX copied from crypto.c */
static void
crypto_log_errors(int severity, const char *doing)
{
  unsigned long err;
  const char *msg, *lib, *func;
  while ((err = ERR_get_error()) != 0) {
    msg = (const char*)ERR_reason_error_string(err);
    lib = (const char*)ERR_lib_error_string(err);
    func = (const char*)ERR_func_error_string(err);
    if (!msg) msg = "(null)";
    if (!lib) lib = "(null)";
    if (!func) func = "(null)";
    if (doing) {
      log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
          doing, msg, lib, func);
    } else {
      log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)", msg, lib, func);
    }
  }
}
Exemple #8
0
/* Load certificate and private key */
static void tls_certkey(SSL *_tls)
{
	int ret, ret2;

	if(!_tls)
	{
		TLSERROR("Certificate cannot be loaded.");
		return;
	}

	if((!_key) || (!_cert) || (!_callback))
	{
		printf("WARNING: certificates are disabled!\n");
		return;
	}

	SSL_CTX_set_default_passwd_cb(_tlsctx, _callback);

	/*ret = SSL_CTX_load_verify_locations(_tlsctx, "/usr/lib/ssl/cacert.pem", NULL);
	if(ret != 1)
	{
		TLSERROR("Couldn't load root CA file!");
		ret2 = ERR_get_error();
		printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL),
		ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2));
	}*/

	ret = SSL_use_RSAPrivateKey_file(_tls, _key, SSL_FILETYPE_PEM);
	if(ret != 1)
	{
		TLSERROR("Error loading TLS PEM private key.");
		ret2 = ERR_get_error();
		printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL),
		ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2));
	}
	ret = SSL_use_certificate_file(_tls, _cert, SSL_FILETYPE_PEM);
	if(ret != 1) TLSERROR("Error loading TLS PEM certificate.");
	ret = SSL_check_private_key(_tls);
	if(!ret) TLSERROR("Private key doesn't match certificate public key.");
	printf("*** certificate loaded ***\n");
}
Exemple #9
0
/* BAD for multi-threaded, uses a local buffer if ret == NULL */
char *ERR_error_string(unsigned long e, char *ret)
	{
	#ifdef	NO_ERR
	if(ret != NULL) {
		strcpy(ret, "No Error String Info.");
	}
	return "No Error String info.";
	#else
	static char buf[256];
	const char *ls,*fs,*rs;
	unsigned long l,f,r;
	int i;

	l=ERR_GET_LIB(e);
	f=ERR_GET_FUNC(e);
	r=ERR_GET_REASON(e);

	ls=ERR_lib_error_string(e);
	fs=ERR_func_error_string(e);
	rs=ERR_reason_error_string(e);

	if (ret == NULL) ret=buf;

	sprintf(&(ret[0]),"error:%08lX:",e);
	i=strlen(ret);
	if (ls == NULL)
		sprintf(&(ret[i]),":lib(%lu) ",l);
	else	sprintf(&(ret[i]),"%s",ls);
	i=strlen(ret);
	if (fs == NULL)
		sprintf(&(ret[i]),":func(%lu) ",f);
	else	sprintf(&(ret[i]),":%s",fs);
	i=strlen(ret);
	if (rs == NULL)
		sprintf(&(ret[i]),":reason(%lu)",r);
	else	sprintf(&(ret[i]),":%s",rs);

	return(ret);
	#endif
	}
Exemple #10
0
/** Log TLS error(s).
 *
 * Log the TLS error specified by the error code @a e and all the errors in
 * the queue. The error code @a e implies no error, and it is not logged.
 */
static
void tls_log_errors(unsigned level, char const *s, unsigned long e)
{
  if (e == 0)
    e = ERR_get_error();

  if (!tport_log->log_init)
    su_log_init(tport_log);

  if (s == NULL) s = "tls";

  for (; e != 0; e = ERR_get_error()) {
    if (level <= tport_log->log_level) {
      const char *error = ERR_lib_error_string(e);
      const char *func = ERR_func_error_string(e);
      const char *reason = ERR_reason_error_string(e);

      su_llog(tport_log, level, "%s: %08lx:%s:%s:%s\n",
	      s, e, error, func, reason);
    }
  }
}
Exemple #11
0
/** Log all pending tls errors at level <b>severity</b>.  Use
 * <b>doing</b> to describe our current activities.
 */
static void
tls_log_errors(tor_tls_t *tls, int severity, const char *doing)
{
  unsigned long err;
  const char *msg, *lib, *func, *addr;
  addr = tls ? tls->address : NULL;
  while ((err = ERR_get_error()) != 0) {
    msg = (const char*)ERR_reason_error_string(err);
    lib = (const char*)ERR_lib_error_string(err);
    func = (const char*)ERR_func_error_string(err);
    if (!msg) msg = "(null)";
    if (doing) {
      log(severity, LD_NET, "TLS error while %s%s%s: %s (in %s:%s)",
          doing, addr?" with ":"", addr?addr:"",
          msg, lib, func);
    } else {
      log(severity, LD_NET, "TLS error%s%s: %s (in %s:%s)",
          addr?" with ":"", addr?addr:"",
          msg, lib, func);
    }
  }
}
Exemple #12
0
void wi_error_set_openssl_error(void) {
	wi_error_t		*error;
	const char		*file;
	int				line;

	if(ERR_peek_error() == 0) {
		wi_error_set_errno(errno);
	} else {
		error = _wi_get_error();
		error->domain = WI_ERROR_DOMAIN_OPENSSL;
		error->code = ERR_get_error_line(&file, &line);
		
		wi_release(error->string);

		error->string = wi_string_init_with_format(wi_string_alloc(), WI_STR("%s:%d: %s: %s (%u)"),
			file,
			line,
			ERR_func_error_string(error->code),
			ERR_reason_error_string(error->code),
			ERR_GET_REASON(error->code));
	}
}
Exemple #13
0
void wi_error_set_openssl_error(void) {
	wi_string_t		*string;
	const char		*file;
	unsigned long	code;
	int				line;

	if(ERR_peek_error() == 0) {
		wi_error_set_errno(errno);
	} else {
		code		= ERR_get_error_line(&file, &line);
		string		= wi_string_with_format(WI_STR("%s:%d: %s: %s (%u)"),
			file,
			line,
			ERR_func_error_string(code),
			ERR_reason_error_string(code),
			ERR_GET_REASON(code));
		
		wi_error_set_error_with_string(WI_ERROR_DOMAIN_OPENSSL, code, string);

	}
	
	ERR_clear_error();
}
Exemple #14
0
UtlBoolean OsEncryption::openSslError(void)
{
#if defined(OSENCRYPTION)
    unsigned long err = ERR_get_error();
    if (err != 0)
    {
        ERR_load_crypto_strings();
        ERR_load_ERR_strings();
        char errbuff[256];
        errbuff[0] = 0;
        ERR_error_string_n(err, errbuff, sizeof(errbuff));
        osPrintf("OpenSLL ERROR:\n\tlib:%s\n\tfunction:%s\n\treason:%s\n",
            ERR_lib_error_string(err),
            ERR_func_error_string(err),
            ERR_reason_error_string(err));
        ERR_free_strings();

        return TRUE;
    }
#endif

    return FALSE;
}
Exemple #15
0
void ERR_error_string_n(unsigned long e, char *buf, size_t len)
{
    char lsbuf[64], fsbuf[64], rsbuf[64];
    const char *ls, *fs, *rs;
    unsigned long l, f, r;

    if (len == 0)
        return;

    l = ERR_GET_LIB(e);
    ls = ERR_lib_error_string(e);
    if (ls == NULL) {
        BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
        ls = lsbuf;
    }

    fs = ERR_func_error_string(e);
    f = ERR_GET_FUNC(e);
    if (fs == NULL) {
        BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
        fs = fsbuf;
    }

    rs = ERR_reason_error_string(e);
    r = ERR_GET_REASON(e);
    if (rs == NULL) {
        BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
        rs = rsbuf;
    }

    BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs);
    if (strlen(buf) == len - 1) {
        /* Didn't fit; use a minimal format. */
        BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, f, r);
    }
}
Exemple #16
0
void ssl_error(char *message)
{
	int err_code = ERR_get_error();
	printf("%s: Function: %s  :  %s\n",message,ERR_func_error_string(err_code),ERR_reason_error_string(err_code));
}
void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
  char lib_buf[64], func_buf[64], reason_buf[64];
  const char *lib_str, *func_str, *reason_str;
  unsigned lib, func, reason;

  if (len == 0) {
    return;
  }

  lib = ERR_GET_LIB(packed_error);
  func = ERR_GET_FUNC(packed_error);
  reason = ERR_GET_REASON(packed_error);

  lib_str = ERR_lib_error_string(packed_error);
  func_str = ERR_func_error_string(packed_error);
  reason_str = ERR_reason_error_string(packed_error);

  if (lib_str == NULL) {
    BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib);
    lib_str = lib_buf;
  }

  if (func_str == NULL) {
    BIO_snprintf(func_buf, sizeof(func_buf), "func(%u)", func);
    func_str = func_buf;
  }

  if (reason_str == NULL) {
    BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason);
    reason_str = reason_buf;
  }

  BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:%s:%s",
               packed_error, lib_str, func_str, reason_str);

  if (strlen(buf) == len - 1) {
    /* output may be truncated; make sure we always have 5 colon-separated
     * fields, i.e. 4 colons. */
    static const unsigned num_colons = 4;
    unsigned i;
    char *s = buf;

    if (len <= num_colons) {
      /* In this situation it's not possible to ensure that the correct number
       * of colons are included in the output. */
      return;
    }

    for (i = 0; i < num_colons; i++) {
      char *colon = strchr(s, ':');
      char *last_pos = &buf[len - 1] - num_colons + i;

      if (colon == NULL || colon > last_pos) {
        /* set colon |i| at last possible position (buf[len-1] is the
         * terminating 0). If we're setting this colon, then all whole of the
         * rest of the string must be colons in order to have the correct
         * number. */
        memset(last_pos, ':', num_colons - i);
        break;
      }

      s = colon + 1;
    }
  }
}
Exemple #18
0
/* Switch on a filedescriptor */
int ggz_tls_enable_fd(int fd, GGZTLSType mode, GGZTLSVerificationType verify)
{
	int ret, ret2;
	STACK_OF(SSL_CIPHER) *stack;
	SSL_CIPHER *cipher;
	int bits;
	char *cipherlist;
	SSL *_tls;
	int _tls_active;
	struct list_entry *entry;

	_state = 1;
	_tls_active = 0;
	if((mode != GGZ_TLS_CLIENT) && (mode != GGZ_TLS_SERVER))
	{
		TLSERROR("Wrong mode.");
		return 0;
	}

	if(!_tlsctx) tls_init(verify);
		
	_tls = SSL_new(_tlsctx);
	if(_tls)
	{
		cipherlist = NULL;
		stack = SSL_get_ciphers(_tls);
		while((cipher = (SSL_CIPHER*)sk_pop(stack)) != NULL)
		{
			printf("* Cipher: %s\n", SSL_CIPHER_get_name(cipher));
			printf("  Bits: %i\n", SSL_CIPHER_get_bits(cipher, &bits));
			printf("  Used bits: %i\n", bits);
			printf("  Version: %s\n", SSL_CIPHER_get_version(cipher));
			printf("  Description: %s\n", SSL_CIPHER_description(cipher, NULL, 0));
			if(cipherlist)
			{
				cipherlist = (char*)realloc(cipherlist, (strlen(cipherlist) + 1) + strlen(SSL_CIPHER_get_name(cipher)) + 1);
				strcat(cipherlist, ":");
				strcat(cipherlist, SSL_CIPHER_get_name(cipher));
			}
			else
			{
				cipherlist = (char*)malloc(strlen(SSL_CIPHER_get_name(cipher)) + 1);
				strcpy(cipherlist, SSL_CIPHER_get_name(cipher));
			}
		}
		printf("Available ciphers: %s\n", cipherlist);
		ret = SSL_set_cipher_list(_tls, cipherlist);
		if(!ret) TLSERROR("Cipher selection failed.");
		ret = SSL_set_fd(_tls, fd);
		if(!ret) TLSERROR("Assignment to connection failed.");
		else
		{
			SSL_set_read_ahead(_tls, 1);
			if(mode == GGZ_TLS_SERVER)
			{
				tls_certkey(_tls);
				if(_state)
				{
					SSL_set_accept_state(_tls);
					ret = SSL_accept(_tls);
				}
			}
			else
			{
				SSL_set_connect_state(_tls);
				ret = SSL_connect(_tls);
			}
			if((ret != 1) || (!_state))
			{
				printf("Ret: %i, State: %i\n", ret, _state);
				TLSERROR("Handshake failed.");
				ret2 = ERR_get_error();
				printf("EXT: %s\n%s\n%s\n%s\n%s\n", tls_exterror(_tls, ret), ERR_error_string(ret2, NULL),
					ERR_lib_error_string(ret2), ERR_func_error_string(ret2), ERR_reason_error_string(ret2));
			}
			else
			{
				printf(">>>>> Handshake successful.\n");
				if((mode == GGZ_TLS_SERVER) || (verify == GGZ_TLS_VERIFY_NONE)) _tls_active = 1;
				else
				{
					printf(">>>>> Client side, thus checking Certificate.\n");
					printf("Negotiated cipher: %s\n", SSL_get_cipher(_tls));
					printf("Shared ciphers: %s\n", SSL_get_shared_ciphers(_tls, NULL, 0));
					if(SSL_get_peer_certificate(_tls))
					{
						if(SSL_get_verify_result(_tls) == X509_V_OK)
						{
							_tls_active = 1;
						}
						else
						{
							printf("Error code: %li\n", SSL_get_verify_result(_tls));
							TLSERROR("Invalid certificate, or certificate is not self-signed.");
						}
					}
					else TLSERROR("Couldn't get certificate.");
				}
			}
			entry = (struct list_entry*)ggz_malloc(sizeof(struct list_entry));
			entry->tls = _tls;
			entry->fd = fd;
			entry->active = _tls_active;
			ggz_list_insert(openssllist, entry);
			return 1;
		}
	}
	return 0;
}
Exemple #19
0
TLSSession *
tls_context_setup_session(TLSContext *self)
{
  SSL *ssl;
  TLSSession *session;
  gint ssl_error;

  if (!self->ssl_ctx)
    {
      gint verify_mode = 0;
      gint verify_flags = X509_V_FLAG_POLICY_CHECK;

      if (self->mode == TM_CLIENT)
        self->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
      else
        self->ssl_ctx = SSL_CTX_new(SSLv23_server_method());

      if (!self->ssl_ctx)
        goto error;
      if (file_exists(self->key_file) && !SSL_CTX_use_PrivateKey_file(self->ssl_ctx, self->key_file, SSL_FILETYPE_PEM))
        goto error;

      if (file_exists(self->cert_file) && !SSL_CTX_use_certificate_chain_file(self->ssl_ctx, self->cert_file))
        goto error;
      if (self->key_file && self->cert_file && !SSL_CTX_check_private_key(self->ssl_ctx))
        goto error;

      if (file_exists(self->ca_dir) && !SSL_CTX_load_verify_locations(self->ssl_ctx, NULL, self->ca_dir))
        goto error;

      if (file_exists(self->crl_dir) && !SSL_CTX_load_verify_locations(self->ssl_ctx, NULL, self->crl_dir))
        goto error;

      if (self->crl_dir)
        verify_flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;

      X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, verify_flags);

      switch (self->verify_mode)
        {
        case TVM_NONE:
          verify_mode = SSL_VERIFY_NONE;
          break;
        case TVM_OPTIONAL | TVM_UNTRUSTED:
          verify_mode = SSL_VERIFY_NONE;
          break;
        case TVM_OPTIONAL | TVM_TRUSTED:
          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
          break;
        case TVM_REQUIRED | TVM_UNTRUSTED:
          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
          break;
        case TVM_REQUIRED | TVM_TRUSTED:
          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
          break;
        default:
          g_assert_not_reached();
        }

      SSL_CTX_set_verify(self->ssl_ctx, verify_mode, tls_session_verify_callback);
      SSL_CTX_set_options(self->ssl_ctx, SSL_OP_NO_SSLv2);
      if (self->cipher_suite)
        {
          if (!SSL_CTX_set_cipher_list(self->ssl_ctx, self->cipher_suite))
            goto error;
        }
    }

  ssl = SSL_new(self->ssl_ctx);

  if (self->mode == TM_CLIENT)
    SSL_set_connect_state(ssl);
  else
    SSL_set_accept_state(ssl);

  session = tls_session_new(ssl, self);
  SSL_set_app_data(ssl, session);
  return session;

 error:
  ssl_error = ERR_get_error();
  msg_error("Error setting up TLS session context",
            evt_tag_printf("tls_error", "%s:%s:%s", ERR_lib_error_string(ssl_error), ERR_func_error_string(ssl_error), ERR_reason_error_string(ssl_error)),
            NULL);
  ERR_clear_error();
  if (self->ssl_ctx)
    {
      SSL_CTX_free(self->ssl_ctx);
      self->ssl_ctx = NULL;
    }
  return NULL;
}
/*===========================================================================*
OpcUa_P_OpenSSL_RSA_Public_Encrypt
*===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Public_Encrypt(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Byte*             a_pPlainText,
    OpcUa_UInt32            a_plainTextLen,
    OpcUa_Key*              a_publicKey,
    OpcUa_Int16             a_padding,
    OpcUa_Byte*             a_pCipherText,
    OpcUa_UInt32*           a_pCipherTextLen)
{
    EVP_PKEY*       pPublicKey      = OpcUa_Null;

    OpcUa_UInt32    uKeySize            = 0;
    OpcUa_UInt32    uEncryptedDataSize  = 0;
    OpcUa_UInt32    uPlainTextPosition  = 0;
    OpcUa_UInt32    uCipherTextPosition = 0;
    OpcUa_UInt32    uBytesToEncrypt     = 0;
    OpcUa_Int32     iEncryptedBytes     = 0;
    const unsigned char *pData;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Public_Encrypt");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_publicKey);
    OpcUa_ReturnErrorIfArgumentNull(a_publicKey->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pCipherTextLen);

    *a_pCipherTextLen = 0;

    if((OpcUa_Int32)a_plainTextLen < 1)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoErrorIfBad(uStatus);
    }

    if(a_publicKey->Type != OpcUa_Crypto_KeyType_Rsa_Public)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pData = a_publicKey->Key.Data;
    pPublicKey = d2i_PublicKey(EVP_PKEY_RSA, OpcUa_Null, &pData, a_publicKey->Key.Length);

    if ( pPublicKey != OpcUa_Null )
    {
        uKeySize = RSA_size(pPublicKey->pkey.rsa);
    }
    else
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    /* check padding type */
    switch(a_padding)
    {
    case RSA_PKCS1_PADDING:
        {
            uEncryptedDataSize = uKeySize - 11;
            break;
        }
    case RSA_PKCS1_OAEP_PADDING:
        {
            uEncryptedDataSize = uKeySize - 42;
            break;
        }
    case RSA_NO_PADDING:
        {
            uEncryptedDataSize = uKeySize;
            break;
        }
    default:
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadNotSupported);
        }
    }

    if(a_plainTextLen < uEncryptedDataSize)
    {
        uBytesToEncrypt = a_plainTextLen;
    }
    else
    {
        uBytesToEncrypt = uEncryptedDataSize;
    }

    while(uPlainTextPosition < a_plainTextLen)
    {

        /* the last part could be smaller */
        if((a_plainTextLen >= uEncryptedDataSize) && ((a_plainTextLen - uPlainTextPosition) < uEncryptedDataSize))
        {
            uBytesToEncrypt = a_plainTextLen - uPlainTextPosition;
        }

        if((a_pCipherText != OpcUa_Null) && (a_pPlainText != OpcUa_Null))
        {
            iEncryptedBytes = RSA_public_encrypt(   uBytesToEncrypt,      /* how much to encrypt  */
                                                    a_pPlainText + uPlainTextPosition,      /* what to encrypt      */
                                                    a_pCipherText + uCipherTextPosition,/* where to encrypt     */
                                                    pPublicKey->pkey.rsa,                  /* public key           */
                                                    a_padding);        /* padding mode         */
            if(iEncryptedBytes < 0)
            {
                const char*     sError          = OpcUa_Null;
                unsigned long   error           = 0;

                error = ERR_get_error();

                ERR_load_crypto_strings();

                sError = ERR_reason_error_string(error);
                sError = ERR_func_error_string(error);
                sError = ERR_lib_error_string(error);

                uStatus = OpcUa_Bad;
                OpcUa_GotoError;
            }

        }
        else
        {
            iEncryptedBytes = uKeySize;
        }

        *a_pCipherTextLen = *a_pCipherTextLen + iEncryptedBytes;
        uCipherTextPosition += uKeySize;
        uPlainTextPosition  += uBytesToEncrypt;
    }

    EVP_PKEY_free(pPublicKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pPublicKey != OpcUa_Null)
    {
        EVP_PKEY_free(pPublicKey);
    }

    *a_pCipherTextLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
Exemple #21
0
int	CSSLClient::SSLConnect(SWL_socket_t sockfd, bool bVerifyPeer, const char *pHost, const char *pCertFile, \
						   const char *pPriteKeyFile, const char *pCAPath, const char *pCAFile, const char *pPassWd)
{
	s_Lock.Lock();
	if (!s_bHasInitial)
	{
		printf("ssl not initial\n");
		s_Lock.UnLock();
		return -1;
	}
	s_Lock.UnLock();
	
	if (pCertFile!=NULL && pPriteKeyFile!=NULL)
	{
		if (pCAPath)
		{
			if(SSL_CTX_load_verify_locations(s_SSLCTX, pCAFile, NULL) <= 0)
			{
				printf("Failed to set CA location...\n");
				return -1;
			}
		}
		if (SSL_CTX_use_certificate_file(s_SSLCTX, pCertFile, SSL_FILETYPE_PEM) <= 0) 
		{
			printf("%s %s %d failed\n", __FILE__, __FUNCTION__, __LINE__);
			int errNum = ERR_get_error();
			printf("%s:%s:%d, ssl connect error:%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_reason_error_string(errNum));
			printf("%s:%s:%d, error function=%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_func_error_string(errNum));
			return -1;
		}
		if (pPassWd)
		{
			SSL_CTX_set_default_passwd_cb_userdata(s_SSLCTX, (void*)pPassWd);
		}
		if (SSL_CTX_use_PrivateKey_file(s_SSLCTX, pPriteKeyFile, SSL_FILETYPE_PEM) <= 0) 
		{
			printf("%s %s %d failed\n", __FILE__, __FUNCTION__, __LINE__);
			int errNum = ERR_get_error();
			printf("%s:%s:%d, ssl connect error:%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_reason_error_string(errNum));
			printf("%s:%s:%d, error function=%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_func_error_string(errNum));
			return -1;
		}

		if (!SSL_CTX_check_private_key(s_SSLCTX)) 
		{
			printf("%s %s %d failed\n", __FILE__, __FUNCTION__, __LINE__);
			int errNum = ERR_get_error();
			printf("%s:%s:%d, ssl connect error:%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_reason_error_string(errNum));
			printf("%s:%s:%d, error function=%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_func_error_string(errNum));
			return -1;
		}
	}

	if (NULL == m_pSSL)
	{
		if (bVerifyPeer)
		{
			SSL_CTX_set_verify(s_SSLCTX, SSL_VERIFY_PEER, VerifyCallBack);
		}
		m_pSSL = SSL_new(s_SSLCTX);
		if (NULL == m_pSSL)
		{
			printf("ssl new err\n");
			return -1;
		}
	}

	if (1 != SSL_set_fd(m_pSSL, sockfd))
	{
		int errNum = ERR_get_error();
		printf("%s:%s:%d, ssl connect error:%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_reason_error_string(errNum));
		printf("%s:%s:%d, error function=%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_func_error_string(errNum));
		return -1;
	}
	SSL_set_connect_state(m_pSSL);

	unsigned long reTry = 0; 
	int ret = 0, err = 0;
	while(reTry++ < SSL_SOCKET_CONNECT_RETRIES)
	{
		if((ret = SSL_connect(m_pSSL)) == 1)
		{
			break;
		}
		err = SSL_get_error(m_pSSL, ret);
		if(SSL_ERROR_WANT_CONNECT == err || SSL_ERROR_WANT_READ == err || SSL_ERROR_WANT_WRITE == err)
		{
			PUB_Sleep(10); // wait a while
		}
		else
		{
			printf("SSL_connect Err : %d\n", err);
			int errNum = ERR_get_error();
			printf("%s:%s:%d, ssl connect error:%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_reason_error_string(errNum));
			printf("%s:%s:%d, error function=%s\n", __FUNCTION__, __FILE__, __LINE__, ERR_func_error_string(errNum));
			FreeRsource();
			return -1;
		}
	}
	if (reTry >= SSL_SOCKET_CONNECT_RETRIES)
	{
		printf("reTry >= SSL_SOCKET_CONNECT_RETRIES\n");
		FreeRsource();
		return -1;
	}

	if (pHost)
	{
		if (PostConnectCheck(m_pSSL, pHost) < 0)
		{
			return -1;
		}
	}
	
	return 0;
}
Exemple #22
0
void raise_error(){
  unsigned long err = ERR_get_error(); //Pops earliest error from the queue
  ERR_clear_error(); //Removes additional errors (if any) from the queue
  stop("OpenSSL error in %s: %s", ERR_func_error_string(err), ERR_reason_error_string(err));
}
Exemple #23
0
ops_boolean_t ops_dsa_verify(const unsigned char *hash,size_t hash_length,
			     const ops_dsa_signature_t *sig,
			     const ops_dsa_public_key_t *dsa)
    {
    DSA_SIG *osig;
    DSA *odsa;
    int ret;

    osig=DSA_SIG_new();
    osig->r=sig->r;
    osig->s=sig->s;

	 if(BN_num_bits(dsa->q) != 160)
	 {
		 if(!already_said)
		 {
			 fprintf(stderr,"(WW) ops_dsa_verify: openssl does only supports 'q' of 160 bits. Current is %d bits.\n",BN_num_bits(dsa->q)) ;
			 already_said=ops_true ;
		 }
		 osig->r=osig->s=NULL;
		 DSA_SIG_free(osig);
		 return ops_false ;
	 }

    odsa=DSA_new();
    odsa->p=dsa->p;
    odsa->q=dsa->q;
    odsa->g=dsa->g;
    odsa->pub_key=dsa->y;

    if (debug)
        {
        fprintf(stderr,"hash passed in:\n");
        unsigned i;
        for (i=0; i<hash_length; i++)
            {
            fprintf(stderr,"%02x ", hash[i]);
            }
        fprintf(stderr,"\n");
        }
    //printf("hash_length=%ld\n", hash_length);
    //printf("Q=%d\n", BN_num_bytes(odsa->q));
    unsigned int qlen=BN_num_bytes(odsa->q);
    if (qlen < hash_length)
        hash_length=qlen;
    //    ret=DSA_do_verify(hash,hash_length,osig,odsa);
    ret=DSA_do_verify(hash,hash_length,osig,odsa);
    if (debug)
        {
        fprintf(stderr,"ret=%d\n",ret);
        }

	 if(ret < 0)
	 {
		 ERR_load_crypto_strings() ;
		 unsigned long err = 0 ;
         while((err = ERR_get_error()) > 0)
			 fprintf(stderr,"DSA_do_verify(): ERR = %ld. lib error:\"%s\", func_error:\"%s\", reason:\"%s\"\n",err,ERR_lib_error_string(err),ERR_func_error_string(err),ERR_reason_error_string(err)) ;
    	//assert(ret >= 0);
		return ops_false ;
	 }

    odsa->p=odsa->q=odsa->g=odsa->pub_key=NULL;
    DSA_free(odsa);
 
    osig->r=osig->s=NULL;
    DSA_SIG_free(osig);

    return ret != 0;
    }
Exemple #24
0
void
server_mc_event_cb(struct bufferevent *bev, short events, void *ctx)
{
    struct server *s = (struct server *)ctx;

    dump_flags(events);
    if (events & BEV_EVENT_CONNECTED)
    {
        struct mc *mc;

        /*
         * If we received the notification that the connection is established,
         * then we move the corresponding struct mc from s->pending_peers to
         * s->peers.
         */

        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            struct mc tmp;
            struct endpoint e;

            endpoint_init(&e, mc->p.address, mc->p.len);
            /* Check for certificate */
            if (mc->ssl_flags & TLS_ENABLE)
            {
                X509 *cert;
                SSL *ssl;
                EVP_PKEY *pubkey;
                char name[512];

                ssl = bufferevent_openssl_get_ssl(mc->bev);
                cert = SSL_get_peer_certificate(ssl);
                if (cert == NULL)
                {
                    log_info("[META] [TLS] %s doesn't share it's certificate.",
                             mc_presentation(mc, name, sizeof name));
                    v_mc_erase(s->pending_peers, mc);
                    mc_close(mc);
                    return ;
                }
                pubkey = X509_get_pubkey(cert); //UNUSED ?
            }
            log_info("[META] [%s] connexion established with %s",
                     mc->ssl_flags & TLS_ENABLE ? "TLS" : "TCP",
                     endpoint_presentation(&e));
            memcpy(&tmp, mc, sizeof(tmp));
            v_mc_erase(s->pending_peers, mc);
            mc = v_mc_insert(s->peers, &tmp);
            mc_hello(mc, s->udp);
            mc_establish_tunnel(mc, s->udp);
        }
    }
    else if (events & BEV_EVENT_EOF)
    {
        /* Disconnected */
        struct mc *mc;
        struct udp_peer *up;

        mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->peers))
        {
            char name[INET6_ADDRSTRLEN];
            struct sockaddr *sock = mc->p.address;

            up = v_udp_find_if(s->udp->udp_peers, find_udppeer, sock);
            if (up != v_udp_end(s->udp->udp_peers))
            {
                v_udp_erase(s->udp->udp_peers, up);
                log_debug("[%s] stop peering with %s",
                          (up->ssl_flags & DTLS_ENABLE) ? "DTLS" : "UDP",
                          endpoint_presentation(&up->peer_addr));
            }
            log_debug("[META] stop the meta-connexion with %s",
                      mc_presentation(mc, name, sizeof(name)));
            mc_close(mc);
            v_mc_erase(s->peers, mc);
        }

    }
    else if (events & BEV_EVENT_ERROR)
    {
        struct mc *mc;
        int everr;
        int sslerr;

        everr = EVUTIL_SOCKET_ERROR();

        if (everr != 0)
        {
            log_warnx("[META] unexpected shutdown of the meta-connexion: (%d) %s",
                       everr, evutil_socket_error_to_string(everr));
        }
        while ((sslerr = bufferevent_get_openssl_error(bev)) != 0)
        {
            log_warnx("[META] SSL error code (%d): %s in %s %s",
                       sslerr, ERR_reason_error_string(sslerr),
                       ERR_lib_error_string(sslerr),
                       ERR_func_error_string(sslerr));
        }
        /*
         * Find if the exception come from a pending peer or a
         * regular peer and close it.
         */
        mc = v_mc_find_if(s->pending_peers, (void *)find_bev, bev);
        if (mc != v_mc_end(s->pending_peers))
        {
            char name[128];

            log_debug("[META] %s removed from the pending list",
                      mc_presentation(mc, name, sizeof name));
            mc_close(mc);
            v_mc_erase(s->pending_peers, mc);
        }
        else
        {
            mc = v_mc_find_if(s->peers, (void *)find_bev, bev);
            if (mc != v_mc_end(s->peers))
            {
                mc_close(mc);
                v_mc_erase(s->peers, mc);
                log_debug("[META] socket removed from the peer list");
            }
        }
    }
}
/*============================================================================
 * OpcUa_P_OpenSSL_RSA_Private_Decrypt
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_Private_Decrypt(
    OpcUa_CryptoProvider*   a_pProvider,
    OpcUa_Byte*             a_pCipherText,
    OpcUa_UInt32            a_cipherTextLen,
    OpcUa_Key*              a_privateKey,
    OpcUa_Int16             a_padding,
    OpcUa_Byte*             a_pPlainText,
    OpcUa_UInt32*           a_pPlainTextLen)
{
    EVP_PKEY*       pPrivateKey     = OpcUa_Null;

    OpcUa_UInt32    keySize         = 0;
    OpcUa_Int32     decryptedBytes  = 0;
    OpcUa_UInt32    iCipherText     = 0;
    /* OpcUa_UInt32 iPlainTextLen   = 0; */
    OpcUa_UInt32    decDataSize     = 0;

    const char*     sError          = OpcUa_Null;
    const unsigned char *pData;

    OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_Private_Decrypt");

    OpcUa_ReferenceParameter(a_pProvider);

    OpcUa_ReturnErrorIfArgumentNull(a_pCipherText);
    OpcUa_ReturnErrorIfArgumentNull(a_privateKey);
    OpcUa_ReturnErrorIfArgumentNull(a_privateKey->Key.Data);
    OpcUa_ReturnErrorIfArgumentNull(a_pPlainTextLen);

    *a_pPlainTextLen = 0;

    if(a_privateKey->Type != OpcUa_Crypto_KeyType_Rsa_Private)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_BadInvalidArgument);
    }

    pData = a_privateKey->Key.Data;
    pPrivateKey = d2i_PrivateKey(EVP_PKEY_RSA,OpcUa_Null, &pData, a_privateKey->Key.Length);

    if (pPrivateKey == OpcUa_Null)
    {
        long lErr = ERR_get_error();
        char *szErr = ERR_error_string(lErr, 0);
        OpcUa_ReferenceParameter(szErr);
        return OpcUa_BadInvalidArgument;
    }

    keySize = RSA_size(pPrivateKey->pkey.rsa);

    if((a_cipherTextLen%keySize) != 0)
    {
        uStatus = OpcUa_BadInvalidArgument;
        OpcUa_GotoError;
    }

    /* check padding type */
    switch(a_padding)
    {
    case RSA_PKCS1_PADDING:
        {
            decDataSize = keySize - 11;
            break;
        }
    case RSA_PKCS1_OAEP_PADDING:
        {
            decDataSize = keySize - 42;
            break;
        }
    case RSA_NO_PADDING:
        {
            decDataSize = keySize;
            break;
        }
    default:
        {
            OpcUa_GotoErrorWithStatus(OpcUa_BadNotSupported);
        }
    }

    while(iCipherText < a_cipherTextLen)
    {
        if(a_pPlainText != OpcUa_Null)
        {
            decryptedBytes = RSA_private_decrypt(   keySize,                            /* how much to decrypt  */
                                                    a_pCipherText + iCipherText,        /* what to decrypt      */
                                                    a_pPlainText + (*a_pPlainTextLen),  /* where to decrypt     */
                                                    pPrivateKey->pkey.rsa,              /* private key          */
                                                    a_padding);                         /* padding mode         */

            /* goto error block, if decryption fails */
            if(decryptedBytes == -1)
            {
                /* const char* serror = NULL; */
                unsigned long error = ERR_get_error();

                ERR_load_crypto_strings();

                sError = ERR_reason_error_string(error);
                sError = ERR_func_error_string(error);
                sError = ERR_lib_error_string(error);

                uStatus = OpcUa_Bad;
                OpcUa_GotoError;
            }

        }
        else
        {
            decryptedBytes = decDataSize;
        }

        *a_pPlainTextLen = *a_pPlainTextLen + decryptedBytes;
        iCipherText = iCipherText + keySize;
    }


    EVP_PKEY_free(pPrivateKey);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pPrivateKey != OpcUa_Null)
    {
        EVP_PKEY_free(pPrivateKey);
    }

    *a_pPlainTextLen = (OpcUa_UInt32)-1;

OpcUa_FinishErrorHandling;
}
Exemple #26
0
void anonaes128_getopt(int* argc, char** argv[])
{
    int           c, got_key = 0, got_iv = 0;
    unsigned long ul;
    char*         p;

    while ((c = getopt(*argc, *argv, "?k:K:i:I:Dcsp:4")) != EOF) {
        switch (c) {
        case '?':
            anonaes128_usage();
            exit(1);
            break;
        case 'k':
            if (strlen(optarg) != 16) {
                usage("key must be 16 characters long");
            }
            memcpy(key, optarg, 16);
            got_key = 1;
            break;
        case 'K': {
            int     fd;
            ssize_t r;
            if ((fd = open(optarg, O_RDONLY)) < 0) {
                perror("open()");
                usage("unable to open key file");
            }
            if ((r = read(fd, key, 16)) < 0) {
                perror("read()");
                usage("unable to read from key file");
            }
            if (r != 16) {
                usage("unable to read 16 bytes from key file");
            }
            close(fd);
            got_key = 1;
            break;
        }
        case 'i':
            if (strlen(optarg) != 16) {
                usage("IV must be 16 characters long");
            }
            memcpy(iv, optarg, 16);
            got_iv = 1;
            break;
        case 'I': {
            int     fd;
            ssize_t r;
            if ((fd = open(optarg, O_RDONLY)) < 0) {
                perror("open()");
                usage("unable to open IV file");
            }
            if ((r = read(fd, iv, 16)) < 0) {
                perror("read()");
                usage("unable to read from IV file");
            }
            if (r != 16) {
                usage("unable to read 16 bytes from IV file");
            }
            close(fd);
            got_iv = 1;
            break;
        }
        case 'D':
            decrypt = 1;
            break;
        case 'c':
            only_clients = 1;
            break;
        case 's':
            only_servers = 1;
            break;
        case 'p':
            ul = strtoul(optarg, &p, 0);
            if (*p != '\0' || ul < 1U || ul > 65535U)
                usage("port must be an integer 1..65535");
            dns_port = (unsigned)ul;
            break;
        case '4':
            encrypt_v4 = 1;
            break;
        default:
            anonaes128_usage();
            exit(1);
        }
    }

    if (!got_key || !got_iv) {
        usage("must have key (-k/-K) and IV (-i/-I)");
    }
    if (decrypt && encrypt_v4) {
        usage("decryption (-D) can not be done for IPv4 addresses (-4)");
    }

#ifdef USE_OPENSSL
    if (!(ctx = EVP_CIPHER_CTX_new())) {
        usage("unable to create openssl cipher context");
    }
    if (!EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv, decrypt ? 0 : 1)) {
        unsigned long e = ERR_get_error();
        fprintf(stderr, "%s:%s:%s", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e));
        usage("unable to initialize AES128 cipher");
    }
    EVP_CIPHER_CTX_set_padding(ctx, 0);
#else
    usage("no openssl support built in, can't encrypt IP addresses");
#endif

    if (only_clients && only_servers) {
        usage("-c and -s options are mutually exclusive");
    }
}