Ejemplo n.º 1
0
static int openssl_ssl_current_cipher(lua_State *L)
{
  SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl");
  const SSL_CIPHER* c = SSL_get_current_cipher(s);
  if (c)
  {
    int bits, algbits;
    char err[LUAL_BUFFERSIZE] = {0};;

    lua_newtable(L);

    AUXILIAR_SET(L, -1, "name",     SSL_CIPHER_get_name(c), string);
    AUXILIAR_SET(L, -1, "version",  SSL_CIPHER_get_version(c), string);

#if OPENSSL_VERSION_NUMBER > 0x10000000L
    AUXILIAR_SET(L, -1, "id", SSL_CIPHER_get_id(c), integer);
#endif
    bits = SSL_CIPHER_get_bits(c, &algbits);
    AUXILIAR_SET(L, -1, "bits", bits, integer);
    AUXILIAR_SET(L, -1, "algbits", algbits, integer);

    AUXILIAR_SET(L, -1, "description", SSL_CIPHER_description((SSL_CIPHER*)c, err, sizeof(err)), string);

    return 1;
  }
  return 0;
}
Ejemplo n.º 2
0
/**
 * Adds Ciphers to the Cipher List structure
 *
 * @param options Options for this run
 * @param ssl_method SSL method to populate ciphers for.
 * @return Boolean: true = success | false = error
 */
int populate_ciphers(struct sslCheckOptions *options, const SSL_METHOD *ssl_method)
{
	struct sslCipher *cipher_ptr;
	int i;
	// STACK_OF is a sign that you should be using C++ :)
	STACK_OF(SSL_CIPHER) *cipher_list;
	SSL_CTX *ctx;
	SSL *ssl = NULL;

	ctx = SSL_CTX_new(ssl_method);
	if (ctx == NULL) {
		printf("%sERROR: Could not create CTX object.%s\n", COL_RED, RESET);
		return false;
	}

	SSL_CTX_set_cipher_list(ctx, "ALL:COMPLEMENTOFALL");

	ssl = SSL_new(ctx);
	if (ssl == NULL) {
		printf("%sERROR: Could not create SSL object.%s\n", COL_RED, RESET);
		SSL_CTX_free(ctx);
		return false;
	}

	cipher_list = SSL_get_ciphers(ssl);

	if (options->ciphers != NULL) {
		cipher_ptr = options->ciphers;
		while (cipher_ptr->next != NULL)
			cipher_ptr = cipher_ptr->next;
	}

	// Create Cipher Struct Entries...
	for (i = 0; i < sk_SSL_CIPHER_num(cipher_list); i++) {
		if (options->ciphers == NULL) {
			options->ciphers = malloc(sizeof(struct sslCipher));
			cipher_ptr = options->ciphers;
		} else {
			cipher_ptr->next = malloc(sizeof(struct sslCipher));
			cipher_ptr = cipher_ptr->next;
		}

		memset(cipher_ptr, 0, sizeof(struct sslCipher));
		cipher_ptr->next = NULL;

		// Add cipher information...
		cipher_ptr->sslMethod = ssl_method;
		cipher_ptr->name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(cipher_list, i));
		cipher_ptr->version = SSL_CIPHER_get_version(sk_SSL_CIPHER_value(cipher_list, i));
		SSL_CIPHER_description(sk_SSL_CIPHER_value(cipher_list, i), cipher_ptr->description, sizeof(cipher_ptr->description) - 1);
		cipher_ptr->bits = SSL_CIPHER_get_bits(sk_SSL_CIPHER_value(cipher_list, i), &cipher_ptr->alg_bits);
	}

	SSL_free(ssl);
	SSL_CTX_free(ctx);

	return true;
}
Ejemplo n.º 3
0
CAMLprim value ocaml_ssl_get_cipher_version(value vcipher)
{
  char *version;
  SSL_CIPHER *cipher = (SSL_CIPHER*)vcipher;

  caml_enter_blocking_section();
  version = SSL_CIPHER_get_version(cipher);
  caml_leave_blocking_section();

  return caml_copy_string(version);
}
Ejemplo n.º 4
0
bool pn_ssl_get_protocol_name(pn_ssl_t *ssl, char *buffer, size_t size )
{
  const SSL_CIPHER *c;

  *buffer = '\0';
  if (ssl->ssl && (c = SSL_get_current_cipher( ssl->ssl ))) {
    const char *v = SSL_CIPHER_get_version(c);
    if (v) {
      snprintf( buffer, size, "%s", v );
      return true;
    }
  }
  return false;
}
Ejemplo n.º 5
0
/* SSL info callback, this is used to trace engine state changes
 * and to check when the handshake is finished, so we can display
 * some cipher and session information and process callbacks.
 */
void ssl_info(SSL *ssl, int where, int ret)
{
  int sock;
  X509 *cert;
  char buf[256];
  ssl_appdata *data;
  SSL_CIPHER *cipher;
  int secret, processed;
  
  /* We're doing non-blocking IO, so we check here if the handshake has
     finished */
  if (where & SSL_CB_HANDSHAKE_DONE) {
    if (!(data = (ssl_appdata *) SSL_get_app_data(ssl)))
      return;
    /* Callback for completed handshake. Cheaper and more convenient than
       using H_tls */
    sock = SSL_get_fd(ssl);    
    if (data->cb)
      data->cb(sock);
    /* Call TLS binds. We allow scripts to take over or disable displaying of
       certificate information. */
    if (check_tcl_tls(sock))
      return;

    putlog(data->loglevel, "*", "TLS: handshake successful. Secure connection "
           "established.");

    if ((cert = SSL_get_peer_certificate(ssl))) 
      ssl_showcert(cert, data->loglevel);
    else
      putlog(data->loglevel, "*", "TLS: peer did not present a certificate");

    /* Display cipher information */
    cipher = SSL_get_current_cipher(ssl);
    processed = SSL_CIPHER_get_bits(cipher, &secret);
    putlog(data->loglevel, "*", "TLS: cipher used: %s %s; %d bits (%d secret)",
           SSL_CIPHER_get_name(cipher), SSL_CIPHER_get_version(cipher),
           processed, secret);
    /* secret are the actually secret bits. If processed and secret differ,
       the rest of the bits are fixed, i.e. for limited export ciphers */

    /* More verbose information, for debugging only */
    SSL_CIPHER_description(cipher, buf, sizeof buf);
    debug1("TLS: cipher details: %s", buf);
  }

  /* Display the state of the engine for debugging purposes */
  debug1("TLS: state change: %s", SSL_state_string_long(ssl));
}
Ejemplo n.º 6
0
int tls_init_data_session(const int fd, const int passive)
{
    const SSL_CIPHER *cipher;
    int ret;
    int ret_;

    (void) passive;
    if (tls_ctx == NULL) {
        logfile(LOG_ERR, MSG_TLS_NO_CTX);
        tls_error(__LINE__, 0);
    }
    if (tls_data_cnx != NULL) {
        tls_close_session(&tls_data_cnx);
    } else if ((tls_data_cnx = SSL_new(tls_ctx)) == NULL) {
        tls_error(__LINE__, 0);
    }
    if (SSL_set_fd(tls_data_cnx, fd) != 1) {
        tls_error(__LINE__, 0);
    }
    SSL_set_accept_state(tls_data_cnx);
    for (;;) {
        ret = SSL_accept(tls_data_cnx);
        if (ret <= 0) {
            ret_ = SSL_get_error(tls_data_cnx, ret);
            if (ret == -1 && (ret_ == SSL_ERROR_WANT_READ ||
                              ret_ == SSL_ERROR_WANT_WRITE)) {
                continue;
            }
            logfile(LOG_INFO, MSG_LOGOUT);
            _EXIT(EXIT_FAILURE);
        }
        break;
    }
# if ONLY_ACCEPT_REUSED_SSL_SESSIONS
    if (broken_client_compat == 0 && SSL_session_reused(tls_data_cnx) == 0) {
        tls_error(__LINE__, 0);
    }
# endif
    if ((cipher = SSL_get_current_cipher(tls_data_cnx)) != NULL) {
        int strength_bits = SSL_CIPHER_get_bits(cipher, NULL);

        logfile(LOG_INFO, MSG_TLS_INFO, SSL_CIPHER_get_version(cipher),
                SSL_CIPHER_get_name(cipher), strength_bits);
        if (strength_bits < MINIMAL_CIPHER_STRENGTH_BITS) {
            die(534, LOG_ERR, MSG_TLS_WEAK);
        }
    }
    return 0;
}
Ejemplo n.º 7
0
static VALUE
ossl_ssl_cipher_to_ary(SSL_CIPHER *cipher)
{
    VALUE ary;
    int bits, alg_bits;

    ary = rb_ary_new2(4);
    rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_name(cipher)));
    rb_ary_push(ary, rb_str_new2(SSL_CIPHER_get_version(cipher)));
    bits = SSL_CIPHER_get_bits(cipher, &alg_bits);
    rb_ary_push(ary, INT2FIX(bits));
    rb_ary_push(ary, INT2FIX(alg_bits));

    return ary;
}
Ejemplo n.º 8
0
struct chiper_info *
_SSL_get_cipher_info (SSL * ssl)
{
	SSL_CIPHER *c;


	c = SSL_get_current_cipher (ssl);
	strncpy (chiper_info.version, SSL_CIPHER_get_version (c),
				sizeof (chiper_info.version));
	strncpy (chiper_info.chiper, SSL_CIPHER_get_name (c),
				sizeof (chiper_info.chiper));
	SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);

	return (&chiper_info);
}
Ejemplo n.º 9
0
return the certificate even if it wasn't validated.");

static PyObject *PySSL_cipher (PySSLObject *self) {

	PyObject *retval, *v;
	SSL_CIPHER *current;
	char *cipher_name;
	char *cipher_protocol;

	if (self->ssl == NULL)
		return Py_None;
	current = SSL_get_current_cipher(self->ssl);
	if (current == NULL)
		return Py_None;

	retval = PyTuple_New(3);
	if (retval == NULL)
		return NULL;

	cipher_name = (char *) SSL_CIPHER_get_name(current);
	if (cipher_name == NULL) {
		PyTuple_SET_ITEM(retval, 0, Py_None);
	} else {
		v = PyUnicode_FromString(cipher_name);
		if (v == NULL)
			goto fail0;
		PyTuple_SET_ITEM(retval, 0, v);
	}
	cipher_protocol = SSL_CIPHER_get_version(current);
	if (cipher_protocol == NULL) {
		PyTuple_SET_ITEM(retval, 1, Py_None);
	} else {
		v = PyUnicode_FromString(cipher_protocol);
		if (v == NULL)
			goto fail0;
		PyTuple_SET_ITEM(retval, 1, v);
	}
	v = PyLong_FromLong(SSL_CIPHER_get_bits(current, NULL));
	if (v == NULL)
		goto fail0;
	PyTuple_SET_ITEM(retval, 2, v);
	return retval;

  fail0:
	Py_DECREF(retval);
	return NULL;
}
Ejemplo n.º 10
0
void SSLGetSessionCipher(SSL* pSSLSession,
                         char* pszBuffer,
                         int iBufferSize)
{
    SSL_CIPHER* pCipher = SSL_get_current_cipher(pSSLSession);
    SetEmptyString(pszBuffer);

    if(pCipher)
    {
        SysSNPrintf(pszBuffer,
                    iBufferSize,
                    "protocol=%s, cipher=%s(%d)",
                    SSL_CIPHER_get_version(pCipher),
                    SSL_CIPHER_get_name(pCipher),
                    SSL_CIPHER_get_bits(pCipher, NULL));
    }
}
Ejemplo n.º 11
0
static void print_details(SSL *c_ssl, const char *prefix)
	{
	SSL_CIPHER *ciph;
	X509 *cert;
		
	ciph=SSL_get_current_cipher(c_ssl);
	BIO_printf(bio_stdout,"%s%s, cipher %s %s",
		prefix,
		SSL_get_version(c_ssl),
		SSL_CIPHER_get_version(ciph),
		SSL_CIPHER_get_name(ciph));
	cert=SSL_get_peer_certificate(c_ssl);
	if (cert != NULL)
		{
		EVP_PKEY *pkey = X509_get_pubkey(cert);
		if (pkey != NULL)
			{
			if (0) 
				;
#ifndef OPENSSL_NO_RSA
			else if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
				&& pkey->pkey.rsa->n != NULL)
				{
				BIO_printf(bio_stdout, ", %d bit RSA",
					BN_num_bits(pkey->pkey.rsa->n));
				}
#endif
#ifndef OPENSSL_NO_DSA
			else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
				&& pkey->pkey.dsa->p != NULL)
				{
				BIO_printf(bio_stdout, ", %d bit DSA",
					BN_num_bits(pkey->pkey.dsa->p));
				}
#endif
			EVP_PKEY_free(pkey);
			}
		X509_free(cert);
		}
	/* The SSL API does not allow us to look at temporary RSA/DH keys,
	 * otherwise we should print their lengths too */
	BIO_printf(bio_stdout,"\n");
	}
Ejemplo n.º 12
0
/* **************************************
 *
 * Information functions
 *
 * Print information for the end user.
 *
 ***************************************/
void
print_details (struct key_state_ssl * ks_ssl, const char *prefix)
{
  const SSL_CIPHER *ciph;
  X509 *cert;
  char s1[256];
  char s2[256];

  s1[0] = s2[0] = 0;
  ciph = SSL_get_current_cipher (ks_ssl->ssl);
  openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s %s",
		    prefix,
		    SSL_get_version (ks_ssl->ssl),
		    SSL_CIPHER_get_version (ciph),
		    SSL_CIPHER_get_name (ciph));
  cert = SSL_get_peer_certificate (ks_ssl->ssl);
  if (cert != NULL)
    {
      EVP_PKEY *pkey = X509_get_pubkey (cert);
      if (pkey != NULL)
	{
	  if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
	      && pkey->pkey.rsa->n != NULL)
	    {
	      openvpn_snprintf (s2, sizeof (s2), ", %d bit RSA",
				BN_num_bits (pkey->pkey.rsa->n));
	    }
	  else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
		   && pkey->pkey.dsa->p != NULL)
	    {
	      openvpn_snprintf (s2, sizeof (s2), ", %d bit DSA",
				BN_num_bits (pkey->pkey.dsa->p));
	    }
	  EVP_PKEY_free (pkey);
	}
      X509_free (cert);
    }
  /* The SSL API does not allow us to look at temporary RSA/DH keys,
   * otherwise we should print their lengths too */
  msg (D_HANDSHAKE, "%s%s", s1, s2);
}
Ejemplo n.º 13
0
static void print_cipher(CLI * c)
{				
	SSL_CIPHER *cipher;
	const COMP_METHOD *compression, *expansion;


	if (global_options.debug_level < LOG_INFO)	
		return;
	cipher = (SSL_CIPHER *) SSL_get_current_cipher(c->ssl);
	s_log(LOG_INFO, "Negotiated %s ciphersuite: %s (%d-bit encryption)",
	      SSL_CIPHER_get_version(cipher), SSL_CIPHER_get_name(cipher),
	      SSL_CIPHER_get_bits(cipher, NULL));

#if OPENSSL_VERSION_NUMBER>=0x0090800fL
	compression = SSL_get_current_compression(c->ssl);
	expansion = SSL_get_current_expansion(c->ssl);
	s_log(LOG_INFO, "Compression: %s, expansion: %s",
	      compression ? SSL_COMP_get_name(compression) : "null",
	      expansion ? SSL_COMP_get_name(expansion) : "null");
#endif
}
Ejemplo n.º 14
0
NOEXPORT void print_cipher(CLI *c) { /* print negotiated cipher */
    SSL_CIPHER *cipher;
#if !defined(OPENSSL_NO_COMP) && OPENSSL_VERSION_NUMBER>=0x0090800fL
    const COMP_METHOD *compression, *expansion;
#endif

    if(global_options.debug_level<LOG_INFO) /* performance optimization */
        return;
    cipher=(SSL_CIPHER *)SSL_get_current_cipher(c->ssl);
    s_log(LOG_INFO, "Negotiated %s ciphersuite: %s (%d-bit encryption)",
        SSL_CIPHER_get_version(cipher), SSL_CIPHER_get_name(cipher),
        SSL_CIPHER_get_bits(cipher, NULL));

#if !defined(OPENSSL_NO_COMP) && OPENSSL_VERSION_NUMBER>=0x0090800fL
    compression=SSL_get_current_compression(c->ssl);
    expansion=SSL_get_current_expansion(c->ssl);
    s_log(LOG_INFO, "Compression: %s, expansion: %s",
        compression ? SSL_COMP_get_name(compression) : "null",
        expansion ? SSL_COMP_get_name(expansion) : "null");
#endif
}
Ejemplo n.º 15
0
int tls_init_new_session(void)
{
    const SSL_CIPHER *cipher;
    int ret;
    int ret_;

    if (tls_ctx == NULL || (tls_cnx = SSL_new(tls_ctx)) == NULL) {
        tls_error(__LINE__, 0);
    }
    if (SSL_set_fd(tls_cnx, clientfd) != 1) {
        tls_error(__LINE__, 0);
    }
    SSL_set_accept_state(tls_cnx);
    for (;;) {
        ret = SSL_accept(tls_cnx);
        if (ret != 1) {
            ret_ = SSL_get_error(tls_cnx, ret);
            if (ret == -1 &&
                (ret_ == SSL_ERROR_WANT_READ ||
                 ret_ == SSL_ERROR_WANT_WRITE)) {
                continue;
            }
            die(400, LOG_WARNING, MSG_TLS_NEEDED);
        }
        break;
    }
    if ((cipher = SSL_get_current_cipher(tls_cnx)) != NULL) {
        int strength_bits = SSL_CIPHER_get_bits(cipher, NULL);

        logfile(LOG_INFO, MSG_TLS_INFO, SSL_CIPHER_get_version(cipher),
                SSL_CIPHER_get_name(cipher), strength_bits);
        if (strength_bits < MINIMAL_CIPHER_STRENGTH_BITS) {
            die(534, LOG_ERR, MSG_TLS_WEAK);
        }
    }
    return 0;
}
Ejemplo n.º 16
0
/*
 * starts SSL/TLS encryption for the current session.
 */
int starttls(int sock) {
	int retval, bits, alg_bits;/*r; */
	SSL *newssl;

	pthread_setspecific(ThreadSSL, NULL);

	if (!ssl_ctx) {
		return(1);
	}
	if (!(newssl = SSL_new(ssl_ctx))) {
		syslog(LOG_WARNING, "SSL_new failed: %s\n", ERR_reason_error_string(ERR_get_error()));
		return(2);
	}
	if (!(SSL_set_fd(newssl, sock))) {
		syslog(LOG_WARNING, "SSL_set_fd failed: %s\n", ERR_reason_error_string(ERR_get_error()));
		SSL_free(newssl);
		return(3);
	}
	retval = SSL_accept(newssl);
	if (retval < 1) {
		/*
		 * Can't notify the client of an error here; they will
		 * discover the problem at the SSL layer and should
		 * revert to unencrypted communications.
		 */
		long errval;
		const char *ssl_error_reason = NULL;

		errval = SSL_get_error(newssl, retval);
		ssl_error_reason = ERR_reason_error_string(ERR_get_error());
		if (ssl_error_reason == NULL) {
			syslog(LOG_WARNING, "SSL_accept failed: errval=%ld, retval=%d %s\n", errval, retval, strerror(errval));
		}
		else {
			syslog(LOG_WARNING, "SSL_accept failed: %s\n", ssl_error_reason);
		}
		sleeeeeeeeeep(1);
		retval = SSL_accept(newssl);
	}
	if (retval < 1) {
		long errval;
		const char *ssl_error_reason = NULL;

		errval = SSL_get_error(newssl, retval);
		ssl_error_reason = ERR_reason_error_string(ERR_get_error());
		if (ssl_error_reason == NULL) {
			syslog(LOG_WARNING, "SSL_accept failed: errval=%ld, retval=%d (%s)\n", errval, retval, strerror(errval));
		}
		else {
			syslog(LOG_WARNING, "SSL_accept failed: %s\n", ssl_error_reason);
		}
		SSL_free(newssl);
		newssl = NULL;
		return(4);
	}
	else {
		syslog(LOG_INFO, "SSL_accept success\n");
	}
	/*r = */BIO_set_close(newssl->rbio, BIO_NOCLOSE);
	bits = SSL_CIPHER_get_bits(SSL_get_current_cipher(newssl), &alg_bits);
	syslog(LOG_INFO, "SSL/TLS using %s on %s (%d of %d bits)\n",
		SSL_CIPHER_get_name(SSL_get_current_cipher(newssl)),
		SSL_CIPHER_get_version(SSL_get_current_cipher(newssl)),
		bits, alg_bits);

	pthread_setspecific(ThreadSSL, newssl);
	syslog(LOG_INFO, "SSL started\n");
	return(0);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
Archivo: tls.c Proyecto: Zabrane/SPOCP
spocp_result_t
tls_start(conn_t * conn, ruleset_t * rs)
{
	SSL            *ssl;
	SSL_CTX        *ctx = (SSL_CTX *) conn->srv->ctx;
	int             maxbits, r, n = 0;
	char           *sid_ctx = "spocp";
	SSL_CIPHER     *cipher;

	if (conn->ssl != NULL) {
		tls_error(SPOCP_WARNING, conn,
			  "STARTTLS received on already encrypted connection");
		return SPOCP_STATE_VIOLATION;
	}

	if (!(ssl = SSL_new(ctx))) {
		tls_error(SPOCP_ERR, conn, "Error creating SSL context");
		return SPOCP_OPERATIONSERROR;
	}

	/*
	 * do these never fail ?? 
	 */

	SSL_set_session_id_context(ssl, (unsigned char *) sid_ctx,
				   strlen(sid_ctx));

	if (SSL_set_fd(ssl, conn->fd) == 0) {
		traceLog(LOG_ERR,"Couldn't set filedescriptor in SSL");
		return SPOCP_OPERATIONSERROR;
	}

	n = iobuf_content(conn->in);
	traceLog(LOG_INFO,"tls_start: %d bytes in input buffer", n);
	if (n) {
		traceLog(LOG_INFO,"tls_start: %x%x%x%x", conn->in->r[0], conn->in->r[1],
			 conn->in->r[2], conn->in->r[3]);
	}

	LOG(SPOCP_DEBUG)
	    traceLog(LOG_DEBUG,"Waiting for client on %d to initiate handshake",
		     conn->fd);

	/*
	 * waits for the client to initiate the handshake 
	 */
	{
		fd_set rset ; int retval ;
	  
		FD_ZERO( &rset );
		FD_SET( conn->fd, &rset );
		traceLog(LOG_DEBUG, "Waiting for the client" ) ;
		retval = select(conn->fd+1,&rset,NULL,NULL,0) ;
	}
	if ((r = SSL_accept(ssl)) <= 0) {
		int se ;

		if ((se = SSL_get_error(ssl, r)) == SSL_ERROR_WANT_READ) {
			traceLog(LOG_DEBUG,"Want_read");
		} else if (se == SSL_ERROR_SYSCALL) {
			unsigned long err ;

			err = ERR_get_error();
			if( err == 0L && r == 0 ) {
				traceLog(LOG_DEBUG,"EOF observed") ;
			}
			else 
				traceLog(LOG_ERR,"I/O error occured (%ld/%d)", err, r);
		} else {
			traceLog(LOG_ERR,"SSL_get_error: %d", se);
			tls_error(SPOCP_ERR, conn, "SSL accept error");
			SSL_free(ssl);
		}
		conn->status = CNST_ACTIVE;
		return SPOCP_SSL_ERR;
	}
	/*
	 * } 
	 */

	LOG(SPOCP_DEBUG) {
		traceLog(LOG_DEBUG,"SSL accept done");
		traceLog(LOG_DEBUG,"Checking client certificate");
	 }

	if (!check_cert_chain(conn, ssl, rs)) {
		traceLog(LOG_ERR,"Certificate chain check failed");
		SSL_free(ssl);
		conn->status = CNST_ACTIVE;
		return SPOCP_CERT_ERR;
	}

	/*
	 * So the cert is OK and the hostname is in the DN, but do I want to
	 * talk to this guy ?? 
	 */

	cipher = SSL_get_current_cipher(ssl);

	conn->cipher = Strdup((char *) SSL_CIPHER_get_name(cipher));

	conn->ssl_vers = Strdup(SSL_CIPHER_get_version(cipher));

	if (server_access(conn) == 0) {
		traceLog(LOG_ERR,"Client not allowed access");
		SSL_free(ssl);

		conn->status = CNST_ACTIVE;
		return SPOCP_CERT_ERR;
	}

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"SSL accept done");

	/*
	 * TLS has been set up. Change input/output to read via TLS instead 
	 */

	conn->readn = ssl_socket_readn;
	conn->writen = ssl_socket_writen;
	conn->close = tls_close;

	conn->ssl = (void *) ssl;
	conn->tls_ssf = SSL_CIPHER_get_bits(cipher, &maxbits);
	conn->status = CNST_ACTIVE;

	return SPOCP_SUCCESS;
}
Ejemplo n.º 19
0
int
openssl_check_accept(openssl_con *c, struct redir_conn_t *conn) {

#ifdef HAVE_OPENSSL
  int rc;

  if (!c || !c->con) return -1;

  if (!SSL_is_init_finished(c->con)) {

    if ((rc = SSL_accept(c->con)) <= 0) {

      int err = SSL_get_error(c->con, rc);

      switch (err) {
        case SSL_ERROR_WANT_READ:
        case SSL_ERROR_WANT_WRITE:
          return 1;

        case SSL_ERROR_SYSCALL:
          if (errno != EINTR) {
#if(_debug_ > 1)
            if (errno > 0) {
              syslog(LOG_DEBUG, "%s(%d): SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]", __FUNCTION__, __LINE__);
            }
            else {
              syslog(LOG_DEBUG, "%s(%d): Spurious SSL handshake interrupt [Hint: Usually just one of those OpenSSL confusions!?]", __FUNCTION__, __LINE__);
            }
#endif
          }
          break;
      }

      return -1;

    } else {

#ifdef HAVE_OPENSSL_ENGINE
      X509 *peer_cert = SSL_get_peer_certificate(c->con);

      if (peer_cert) {
	char subj[1024];

	X509_NAME_oneline(X509_get_subject_name(peer_cert),subj,sizeof(subj));

	if (SSL_get_verify_result(c->con) != X509_V_OK) {
	  syslog(LOG_DEBUG, "%s(%d): auth_failed: %s", __FUNCTION__, __LINE__, subj);
	  X509_free(peer_cert);
	  return -1;
	}

	syslog(LOG_DEBUG, "%s(%d): auth_success: %s", __FUNCTION__, __LINE__, subj);
	if (conn) conn->s_params.flags |= ADMIN_LOGIN;

	if (_options.debug) {
	  EVP_PKEY *pktmp = X509_get_pubkey(peer_cert);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
 	  const
#endif
              SSL_CIPHER *cipher;
	  char b[512];
	  syslog(LOG_DEBUG, "%s(%d): Debugging: SSL Information:\n", __FUNCTION__, __LINE__);
	  cipher = SSL_get_current_cipher(c->con);
	  syslog(LOG_DEBUG, "%s(%d): Protocol: %s, %s with %.*s bit key\n", __FUNCTION__, __LINE__,
                 SSL_CIPHER_get_version(cipher),
                 (char*)SSL_CIPHER_get_name(cipher),
                 sprintf(b, "%d", EVP_PKEY_bits(pktmp)), b);
	  syslog(LOG_DEBUG, "%s(%d): Subject:  %s\n", __FUNCTION__, __LINE__, subj);
	  X509_NAME_oneline(X509_get_issuer_name(peer_cert),b,sizeof(b));
	  syslog(LOG_DEBUG, "%s(%d): Issuer:   %s\n", __FUNCTION__, __LINE__, b);
	  EVP_PKEY_free(pktmp);
	}

	X509_free(peer_cert);
      } else {
	syslog(LOG_DEBUG, "%s(%d): no SSL certificate", __FUNCTION__, __LINE__);
      }
#endif
    }
  }
#elif  HAVE_MATRIXSSL

  if (!c || !c->con) return -1;

  if (!SSL_is_init_finished(c->con)) {

    if (SSL_accept2(c->con) < 0) {
      return -1;
    }

    if (!SSL_is_init_finished(c->con))
      return 1;
  }

#endif

  return 0;
}
Ejemplo n.º 20
0
void ssl_barf_out(Socket_t S) {
	BIO *ebio;
	char buf[BUFSIZ], *p;
	sock_ssl_t m = XSsl(S);

  if (tb_errorlevel >= TB_NOTICE) {
		STACK      * sk;

    if ((ebio=BIO_new(BIO_s_file())) == NULL) {
      tb_warn("Cannot create new BIO\n");
      ERR_print_errors_fp(stderr);
      return;
    }
    BIO_set_fp(ebio,stderr,BIO_NOCLOSE);
    if ((sk=(STACK *)SSL_get_peer_cert_chain(m->cx)) != NULL) {
			int i;
      BIO_printf(ebio,"---\nCertificate chain\n");
      for (i=0; i<sk_num(sk); i++) {
        X509_NAME_oneline(X509_get_subject_name((X509*)sk_value(sk,i)),buf,BUFSIZ);
        BIO_printf(ebio,"%2d s:%s\n",i,buf);
        X509_NAME_oneline(X509_get_issuer_name((X509 *)sk_value(sk,i)),buf,BUFSIZ);
        BIO_printf(ebio,"   i:%s\n",buf);
      }
    }
    BIO_printf(ebio,"---\n");
    if ((m->peer=SSL_get_peer_certificate(m->cx)) != NULL) {
      BIO_printf(ebio,"Peer certificate\n");
      PEM_write_bio_X509(ebio,m->peer);
      X509_NAME_oneline(X509_get_subject_name(m->peer),buf,BUFSIZ);
      BIO_printf(ebio,"subject=%s\n",buf);
      X509_NAME_oneline(X509_get_issuer_name(m->peer),buf,BUFSIZ);
      BIO_printf(ebio,"issuer=%s\n",buf);
    }
    else
      BIO_printf(ebio,"no peer certificate available\n");
    if (((sk=SSL_get_client_CA_list(m->cx)) != NULL) && (sk_num(sk) > 0)) {
			int i;
      BIO_printf(ebio,"---\nAcceptable peer certificate CA names\n");
      for (i=0; i<sk_num(sk); i++) {
        m->xn=(X509_NAME *)sk_value(sk,i);
        X509_NAME_oneline(m->xn,buf,sizeof(buf));
        BIO_write(ebio,buf,strlen(buf));
        BIO_write(ebio,"\n",1);
      }
    }
    else {
      BIO_printf(ebio,"---\nNo peer certificate CA names sent\n");
    }
    if ((p=SSL_get_shared_ciphers(m->cx,buf,BUFSIZ)) != NULL) {
			int i, j;
      BIO_printf(ebio,"---\nCiphers common between both SSL endpoints:\n");
      j=i=0;
      while (*p) {
        if (*p != ':') {
          BIO_write(ebio,p,1);j++;
        } else {
          BIO_write(ebio,"                ",15-j%25);i++;j=0;
          BIO_write(ebio,((i%3)?" ":"\n"),1);
        }
        p++;
      }
      BIO_write(ebio,"\n",1);
    }
    BIO_printf(ebio,
               "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
               BIO_number_read(SSL_get_rbio(m->cx)),
               BIO_number_written(SSL_get_wbio(m->cx)));
    BIO_printf(ebio,((m->cx->hit)?"---\nReused, ":"---\nNew, "));
    m->sc=SSL_get_current_cipher(m->cx);
    BIO_printf(ebio,"%s, Cipher is %s\n",
               SSL_CIPHER_get_version(m->sc),SSL_CIPHER_get_name(m->sc));
    if(m->peer != NULL) {
      EVP_PKEY *pktmp;
      pktmp = X509_get_pubkey(m->peer);
      BIO_printf(ebio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp));
      EVP_PKEY_free(pktmp);
    }
    SSL_SESSION_print(ebio,SSL_get_session(m->cx));
    BIO_printf(ebio,"---\n");
    if(m->peer != NULL)
      X509_free(m->peer);
    BIO_free(ebio);
  }
}
Ejemplo n.º 21
0
static void print_stuff(BIO *bio, SSL *s, int full)
{
    X509 *peer=NULL;
    char *p;
    static const char *space="                ";
    char buf[BUFSIZ];
    STACK_OF(X509) *sk;
    STACK_OF(X509_NAME) *sk2;
    SSL_CIPHER *c;
    X509_NAME *xn;
    int j,i;
#ifndef OPENSSL_NO_COMP
    const COMP_METHOD *comp, *expansion;
#endif

    if (full)
    {
        int got_a_chain = 0;

        sk=SSL_get_peer_cert_chain(s);
        if (sk != NULL)
        {
            got_a_chain = 1; /* we don't have it for SSL2 (yet) */

            BIO_printf(bio,"---\nCertificate chain\n");
            for (i=0; i<sk_X509_num(sk); i++)
            {
                X509_NAME_oneline(X509_get_subject_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"%2d s:%s\n",i,buf);
                X509_NAME_oneline(X509_get_issuer_name(
                                      sk_X509_value(sk,i)),buf,sizeof buf);
                BIO_printf(bio,"   i:%s\n",buf);
                if (c_showcerts)
                    PEM_write_bio_X509(bio,sk_X509_value(sk,i));
            }
        }

        BIO_printf(bio,"---\n");
        peer=SSL_get_peer_certificate(s);
        if (peer != NULL)
        {
            BIO_printf(bio,"Server certificate\n");
            if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
                PEM_write_bio_X509(bio,peer);
            X509_NAME_oneline(X509_get_subject_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"subject=%s\n",buf);
            X509_NAME_oneline(X509_get_issuer_name(peer),
                              buf,sizeof buf);
            BIO_printf(bio,"issuer=%s\n",buf);
        }
        else
            BIO_printf(bio,"no peer certificate available\n");

        sk2=SSL_get_client_CA_list(s);
        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
        {
            BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
            for (i=0; i<sk_X509_NAME_num(sk2); i++)
            {
                xn=sk_X509_NAME_value(sk2,i);
                X509_NAME_oneline(xn,buf,sizeof(buf));
                BIO_write(bio,buf,strlen(buf));
                BIO_write(bio,"\n",1);
            }
        }
        else
        {
            BIO_printf(bio,"---\nNo client certificate CA names sent\n");
        }
        p=SSL_get_shared_ciphers(s,buf,sizeof buf);
        if (p != NULL)
        {
            /* This works only for SSL 2.  In later protocol
             * versions, the client does not know what other
             * ciphers (in addition to the one to be used
             * in the current connection) the server supports. */

            BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
            j=i=0;
            while (*p)
            {
                if (*p == ':')
                {
                    BIO_write(bio,space,15-j%25);
                    i++;
                    j=0;
                    BIO_write(bio,((i%3)?" ":"\n"),1);
                }
                else
                {
                    BIO_write(bio,p,1);
                    j++;
                }
                p++;
            }
            BIO_write(bio,"\n",1);
        }

        BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
                   BIO_number_read(SSL_get_rbio(s)),
                   BIO_number_written(SSL_get_wbio(s)));
    }
    BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
    c=SSL_get_current_cipher(s);
    BIO_printf(bio,"%s, Cipher is %s\n",
               SSL_CIPHER_get_version(c),
               SSL_CIPHER_get_name(c));
    if (peer != NULL) {
        EVP_PKEY *pktmp;
        pktmp = X509_get_pubkey(peer);
        BIO_printf(bio,"Server public key is %d bit\n",
                   EVP_PKEY_bits(pktmp));
        EVP_PKEY_free(pktmp);
    }
#ifndef OPENSSL_NO_COMP
    comp=SSL_get_current_compression(s);
    expansion=SSL_get_current_expansion(s);
    BIO_printf(bio,"Compression: %s\n",
               comp ? SSL_COMP_get_name(comp) : "NONE");
    BIO_printf(bio,"Expansion: %s\n",
               expansion ? SSL_COMP_get_name(expansion) : "NONE");
#endif
    SSL_SESSION_print(bio,SSL_get_session(s));
    BIO_printf(bio,"---\n");
    if (peer != NULL)
        X509_free(peer);
    /* flush, or debugging output gets mixed with http response */
    (void)BIO_flush(bio);
}
Ejemplo n.º 22
0
static void
print_stuff(BIO * bio, SSL * s, int full)
{
	X509 *peer = NULL;
	char *p;
	static const char *space = "                ";
	char buf[BUFSIZ];
	STACK_OF(X509) * sk;
	STACK_OF(X509_NAME) * sk2;
	const SSL_CIPHER *c;
	X509_NAME *xn;
	int j, i;
	unsigned char *exportedkeymat;

	if (full) {
		int got_a_chain = 0;

		sk = SSL_get_peer_cert_chain(s);
		if (sk != NULL) {
			got_a_chain = 1;	/* we don't have it for SSL2
						 * (yet) */

			BIO_printf(bio, "---\nCertificate chain\n");
			for (i = 0; i < sk_X509_num(sk); i++) {
				X509_NAME_oneline(X509_get_subject_name(
					sk_X509_value(sk, i)), buf, sizeof buf);
				BIO_printf(bio, "%2d s:%s\n", i, buf);
				X509_NAME_oneline(X509_get_issuer_name(
					sk_X509_value(sk, i)), buf, sizeof buf);
				BIO_printf(bio, "   i:%s\n", buf);
				if (c_showcerts)
					PEM_write_bio_X509(bio, sk_X509_value(sk, i));
			}
		}
		BIO_printf(bio, "---\n");
		peer = SSL_get_peer_certificate(s);
		if (peer != NULL) {
			BIO_printf(bio, "Server certificate\n");
			if (!(c_showcerts && got_a_chain))	/* Redundant if we
								 * showed the whole
								 * chain */
				PEM_write_bio_X509(bio, peer);
			X509_NAME_oneline(X509_get_subject_name(peer),
			    buf, sizeof buf);
			BIO_printf(bio, "subject=%s\n", buf);
			X509_NAME_oneline(X509_get_issuer_name(peer),
			    buf, sizeof buf);
			BIO_printf(bio, "issuer=%s\n", buf);
		} else
			BIO_printf(bio, "no peer certificate available\n");

		sk2 = SSL_get_client_CA_list(s);
		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
			BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
			for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
				xn = sk_X509_NAME_value(sk2, i);
				X509_NAME_oneline(xn, buf, sizeof(buf));
				BIO_write(bio, buf, strlen(buf));
				BIO_write(bio, "\n", 1);
			}
		} else {
			BIO_printf(bio, "---\nNo client certificate CA names sent\n");
		}
		p = SSL_get_shared_ciphers(s, buf, sizeof buf);
		if (p != NULL) {
			/*
			 * This works only for SSL 2.  In later protocol
			 * versions, the client does not know what other
			 * ciphers (in addition to the one to be used in the
			 * current connection) the server supports.
			 */

			BIO_printf(bio, "---\nCiphers common between both SSL endpoints:\n");
			j = i = 0;
			while (*p) {
				if (*p == ':') {
					BIO_write(bio, space, 15 - j % 25);
					i++;
					j = 0;
					BIO_write(bio, ((i % 3) ? " " : "\n"), 1);
				} else {
					BIO_write(bio, p, 1);
					j++;
				}
				p++;
			}
			BIO_write(bio, "\n", 1);
		}
		BIO_printf(bio, "---\nSSL handshake has read %ld bytes and written %ld bytes\n",
		    BIO_number_read(SSL_get_rbio(s)),
		    BIO_number_written(SSL_get_wbio(s)));
	}
	BIO_printf(bio, (SSL_cache_hit(s) ? "---\nReused, " : "---\nNew, "));
	c = SSL_get_current_cipher(s);
	BIO_printf(bio, "%s, Cipher is %s\n",
	    SSL_CIPHER_get_version(c),
	    SSL_CIPHER_get_name(c));
	if (peer != NULL) {
		EVP_PKEY *pktmp;
		pktmp = X509_get_pubkey(peer);
		BIO_printf(bio, "Server public key is %d bit\n",
		    EVP_PKEY_bits(pktmp));
		EVP_PKEY_free(pktmp);
	}
	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
	    SSL_get_secure_renegotiation_support(s) ? "" : " NOT");

	/* Compression is not supported and will always be none. */
	BIO_printf(bio, "Compression: NONE\n");
	BIO_printf(bio, "Expansion: NONE\n");

#ifdef SSL_DEBUG
	{
		/* Print out local port of connection: useful for debugging */
		int sock;
		struct sockaddr_in ladd;
		socklen_t ladd_size = sizeof(ladd);
		sock = SSL_get_fd(s);
		getsockname(sock, (struct sockaddr *) & ladd, &ladd_size);
		BIO_printf(bio_c_out, "LOCAL PORT is %u\n", ntohs(ladd.sin_port));
	}
#endif

#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.status != -1) {
		const unsigned char *proto;
		unsigned int proto_len;
		SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
		BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
		BIO_write(bio, proto, proto_len);
		BIO_write(bio, "\n", 1);
	}
#endif

#ifndef OPENSSL_NO_SRTP
	{
		SRTP_PROTECTION_PROFILE *srtp_profile = SSL_get_selected_srtp_profile(s);

		if (srtp_profile)
			BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
			    srtp_profile->name);
	}
#endif

	SSL_SESSION_print(bio, SSL_get_session(s));
	if (keymatexportlabel != NULL) {
		BIO_printf(bio, "Keying material exporter:\n");
		BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
		BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
		exportedkeymat = malloc(keymatexportlen);
		if (exportedkeymat != NULL) {
			if (!SSL_export_keying_material(s, exportedkeymat,
				keymatexportlen,
				keymatexportlabel,
				strlen(keymatexportlabel),
				NULL, 0, 0)) {
				BIO_printf(bio, "    Error\n");
			} else {
				BIO_printf(bio, "    Keying material: ");
				for (i = 0; i < keymatexportlen; i++)
					BIO_printf(bio, "%02X",
					    exportedkeymat[i]);
				BIO_printf(bio, "\n");
			}
			free(exportedkeymat);
		}
	}
	BIO_printf(bio, "---\n");
	if (peer != NULL)
		X509_free(peer);
	/* flush, or debugging output gets mixed with http response */
	(void) BIO_flush(bio);
}