Пример #1
0
bool SSLSocket::setupCrypto(SSLSocket *session /* = NULL */) {
  if (m_handle) {
    raise_warning("SSL/TLS already set-up for this stream");
    return false;
  }

  /* need to do slightly different things, based on client/server method,
   * so lets remember which method was selected */
#if OPENSSL_VERSION_NUMBER < 0x00909000L
  SSL_METHOD *smethod;
#else
  const SSL_METHOD *smethod;
#endif
  switch (m_method) {
  case ClientSSLv23: m_client = true;  smethod = SSLv23_client_method(); break;
  case ClientSSLv3:  m_client = true;  smethod = SSLv3_client_method();  break;
  case ClientTLS:    m_client = true;  smethod = TLSv1_client_method();  break;
  case ServerSSLv23: m_client = false; smethod = SSLv23_server_method(); break;
  case ServerSSLv3:  m_client = false; smethod = SSLv3_server_method();  break;

  /* SSLv2 protocol might be disabled in the OpenSSL library */
#ifndef OPENSSL_NO_SSL2
  case ClientSSLv2:  m_client = true;  smethod = SSLv2_client_method();  break;
  case ServerSSLv2:  m_client = false; smethod = SSLv2_server_method();  break;
#else
  case ClientSSLv2:
  case ServerSSLv2:
    raise_warning("OpenSSL library does not support SSL2 protocol");
    return false;
  break;
#endif

  case ServerTLS:    m_client = false; smethod = TLSv1_server_method();  break;
  default:
    return false;
  }

  SSL_CTX *ctx = SSL_CTX_new(smethod);
  if (ctx == nullptr) {
    raise_warning("failed to create an SSL context");
    return false;
  }

  SSL_CTX_set_options(ctx, SSL_OP_ALL);
  m_handle = createSSL(ctx);
  if (m_handle == nullptr) {
    raise_warning("failed to create an SSL handle");
    SSL_CTX_free(ctx);
    return false;
  }

  if (!SSL_set_fd(m_handle, m_fd)) {
    handleError(0, true);
  }
  if (session) {
    SSL_copy_session_id(m_handle, session->m_handle);
  }
  return true;
}
Пример #2
0
int
SecureSocket::secureConnect(int socket)
{
	createSSL();

	// attach the socket descriptor
	SSL_set_fd(m_ssl->m_ssl, socket);
	
	LOG((CLOG_DEBUG2 "connecting secure socket"));
	int r = SSL_connect(m_ssl->m_ssl);
	
	static int retry;

	checkResult(r, retry);

	if (isFatal()) {
		LOG((CLOG_ERR "failed to connect secure socket"));
		return -1;
	}

	// If we should retry, not ready and return 0
	if (retry > 0) {
		LOG((CLOG_DEBUG2 "retry connect secure socket"));
		m_secureReady = false;
		return 0;
	}

	// No error, set ready, process and return ok
	m_secureReady = true;
	if (verifyCertFingerprint()) {
		LOG((CLOG_INFO "connected to secure socket"));
		if (!showCertificate()) {
			disconnect();
			return -1;// Cert fail, error
		}
	}
	else {
		LOG((CLOG_ERR "failed to verify server certificate fingerprint"));
		disconnect();
		return -1; // Fingerprint failed, error
	}
	LOG((CLOG_DEBUG2 "connected secure socket"));
	const SSL_CIPHER* cipher = SSL_get_current_cipher(m_ssl->m_ssl);
	if(cipher != NULL) {
		char * cipherVersion = SSL_CIPHER_description(cipher, NULL, 0);
		if(cipherVersion != NULL) {
			LOG((CLOG_INFO "%s", cipherVersion));
			OPENSSL_free(cipherVersion);
		}
	}
	return 1;
}
Пример #3
0
int
SecureSocket::secureConnect(int socket)
{
	createSSL();

	// attach the socket descriptor
	SSL_set_fd(m_ssl->m_ssl, socket);
	
	LOG((CLOG_DEBUG2 "connecting secure socket"));
	int r = SSL_connect(m_ssl->m_ssl);
	
	static int retry;

	checkResult(r, retry);

	if (isFatal()) {
		LOG((CLOG_ERR "failed to connect secure socket"));
		retry = 0;
		return -1;
	}

	// If we should retry, not ready and return 0
	if (retry > 0) {
		LOG((CLOG_DEBUG2 "retry connect secure socket"));
		m_secureReady = false;
		ARCH->sleep(s_retryDelay);
		return 0;
	}

	retry = 0;
	// No error, set ready, process and return ok
	m_secureReady = true;
	if (verifyCertFingerprint()) {
		LOG((CLOG_INFO "connected to secure socket"));
		if (!showCertificate()) {
			disconnect();
			return -1;// Cert fail, error
		}
	}
	else {
		LOG((CLOG_ERR "failed to verify server certificate fingerprint"));
		disconnect();
		return -1; // Fingerprint failed, error
	}
	LOG((CLOG_DEBUG2 "connected secure socket"));
	if (CLOG->getFilter() >= kDEBUG1) {
		showSecureCipherInfo();
	}
	showSecureConnectInfo();
	return 1;
}
Пример #4
0
int
SecureSocket::secureAccept(int socket)
{
	createSSL();

	// set connection socket to SSL state
	SSL_set_fd(m_ssl->m_ssl, socket);
	
	LOG((CLOG_DEBUG2 "accepting secure socket"));
	int r = SSL_accept(m_ssl->m_ssl);
	
	static int retry;

	checkResult(r, retry);

	if (isFatal()) {
		// tell user and sleep so the socket isn't hammered.
		LOG((CLOG_ERR "failed to accept secure socket"));
		LOG((CLOG_INFO "client connection may not be secure"));
		m_secureReady = false;
		ARCH->sleep(1);
		return -1; // Failed, error out
	}

	// If not fatal and no retry, state is good
	if (retry == 0) {
		m_secureReady = true;
		LOG((CLOG_INFO "accepted secure socket"));
		const SSL_CIPHER* cipher = SSL_get_current_cipher(m_ssl->m_ssl);
		if(cipher != NULL) {
			char * cipherVersion = SSL_CIPHER_description(cipher, NULL, 0);
			if(cipherVersion != NULL) {
				LOG((CLOG_INFO "%s", cipherVersion));
				OPENSSL_free(cipherVersion);
			}
		}
		return 1;
	}

	// If not fatal and retry is set, not ready, and return retry
	if (retry > 0) {
		LOG((CLOG_DEBUG2 "retry accepting secure socket"));
		m_secureReady = false;
		return 0;
	}

	// no good state exists here
	LOG((CLOG_ERR "unexpected state attempting to accept connection"));
	return -1;
}
Пример #5
0
int
SecureSocket::secureAccept(int socket)
{
	createSSL();

	// set connection socket to SSL state
	SSL_set_fd(m_ssl->m_ssl, socket);
	
	LOG((CLOG_DEBUG2 "accepting secure socket"));
	int r = SSL_accept(m_ssl->m_ssl);
	
	static int retry;

	checkResult(r, retry);

	if (isFatal()) {
		// tell user and sleep so the socket isn't hammered.
		LOG((CLOG_ERR "failed to accept secure socket"));
		LOG((CLOG_INFO "client connection may not be secure"));
		m_secureReady = false;
		ARCH->sleep(1);
		retry = 0;
		return -1; // Failed, error out
	}

	// If not fatal and no retry, state is good
	if (retry == 0) {
		m_secureReady = true;
		LOG((CLOG_INFO "accepted secure socket"));
		if (CLOG->getFilter() >= kDEBUG1) {
			showSecureCipherInfo();
		}
		showSecureConnectInfo();
		return 1;
	}

	// If not fatal and retry is set, not ready, and return retry
	if (retry > 0) {
		LOG((CLOG_DEBUG2 "retry accepting secure socket"));
		m_secureReady = false;
		ARCH->sleep(s_retryDelay);
		return 0;
	}

	// no good state exists here
	LOG((CLOG_ERR "unexpected state attempting to accept connection"));
	return -1;
}
Пример #6
0
int main(int argc, char *argv[])
{
    if(argc == 1) {
    	fprintf(stderr,"Error no arguments type -? for usage.\n");
	exit(EXIT_FAILURE);
    }
    int sockfd;
    SSL_CTX *ctx;

    //setup variables that define what the client does
    char request[LENGTH];
    memset(request, '\0', LENGTH);

    enum { SEND_MODE, FETCH_MODE, VOUCH_MODE, LIST_MODE, DEFAULT_MODE } mode = DEFAULT_MODE;
    int option = 0;
    int circumference = 0, port = 0;
    char *fileName, *hostname, *trustedname, *certificate, *certname, *msg;

    //Specifying the expected options
    while ((option = getopt(argc, argv,"a:c:f:h:ln:u:v:?")) != -1) {
        switch (option) {
            case 'a' : //upload a file
		fileName = optarg;
		//print the request to a variable that will be send later
		snprintf(request, sizeof(request), "add file %s", basename(fileName));
		//set the mode of the client
		mode = SEND_MODE;
                break;
            case 'c' : //provide circumference
                circumference = atoi(optarg);
                break;
            case 'f' : //fetch a file
                snprintf(request, sizeof(request), "fetch %s",optarg);
      		fileName = optarg;
		mode = FETCH_MODE;
                break;
            case 'h' : //specify server address
		//get the hostname and port
                hostname = strtok(optarg, ":");
                char *temp = strtok(NULL, ":");
		if(temp != NULL) port = atoi(temp);
                break;
            case 'l' : //list all files on server
		snprintf(request, sizeof(request), "list");
		mode = LIST_MODE;
		break;
            case 'n' : //require name in circle
                trustedname = optarg;
		break;
            case 'u' : //upload a cert
                fileName = optarg;
		certname = basename(fileName);
		snprintf(request, sizeof(request), "add cert %s",certname);		
		mode = SEND_MODE;
                break;
            case 'v' : //vouch
		if(argv[optind] == NULL || argv[optind][0] == '-') { //check whether certificate arg is given
			fprintf(stderr,"Please specify a certicate. Type -? for usage.\n");
			exit(EXIT_FAILURE);
		}
		fileName = argv[optind];
		certname = basename(fileName);
		snprintf(request, sizeof(request), "vouch %s %s",optarg, certname);
		mode = VOUCH_MODE;
		optind = optind+1;
		break;
	    case '?' : //print usage
		print_usage();
		exit(EXIT_SUCCESS);
		break;
            default: print_usage();
                exit(EXIT_FAILURE);
        }
}

    //no hostname specified
    if(hostname == NULL || port == 0) {
    	fprintf(stderr, "[Client] Please specify a hostname and port, type -? for usage\n");
	exit(EXIT_FAILURE);
    }
    //try and connect to the server
    if((sockfd = connectServer(hostname, port)) == -1) {
    	fprintf(stderr, "[Client] Unable to connect to the server.\n");
	exit(EXIT_FAILURE);
    }
    //SSL handshake		
    SSL *ssl = createSSL(sockfd, ctx);
    
    //ask the server to server us
    sendRequest(ssl, request); 
    int getMsg = 1; //whether or not we want to get a message from the server after all is said and done

    int result;
    //execute the requested client options
    switch (mode) {
            case SEND_MODE : 
		result = sendFile(ssl, fileName); 
		if(result == EXIT_FAILURE) {
			exit(EXIT_FAILURE);
		}
		break;

            case FETCH_MODE :
		//first send circumference then send trustedname
		sendCircumference(ssl, circumference);
		memset(request, '\0', LENGTH); //empty the request buffer, ready to send trustedname
		snprintf(request, sizeof(request), "%s",trustedname);	
		sendRequest(ssl, request); //send the trustedname as a request (only doing this because I cant be bothered writing a new method and this one works fine.
		if(getServerMessage(ssl) == EXIT_FAILURE) {
			exit(EXIT_FAILURE);
		}		
		result = receiveFile(ssl);
                break;

            case LIST_MODE : 
		result = receiveFile(ssl);
		break;

            case VOUCH_MODE : 		
		if(getServerMessage(ssl) == EXIT_FAILURE) {
			getMsg = 0; 
			break;
		}
		result = sendFile(ssl, fileName);//send the vouching cert to the server
		if(result == EXIT_FAILURE) exit(EXIT_FAILURE);
		break;
            case DEFAULT_MODE: fprintf(stderr, "[Client] Please specify a send or receive argument, type -? for usage.\n");
    		exit(EXIT_FAILURE);
    }
    //get the result of our request back from the server
    if(getMsg) getServerMessage(ssl);
    
       
    close(sockfd);
    SSL_CTX_free(ctx);        /* release context */
    fprintf(stderr,"[Client] Connection lost.\n");
    
    exit(EXIT_SUCCESS);
}