Пример #1
0
static int NonBlockingSSL_Accept(SSL* ssl)
{
#ifndef CYASSL_CALLBACKS
    int ret = SSL_accept(ssl);
#else
    int ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo);
#endif
    int error = SSL_get_error(ssl, 0);
    SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl);
    int select_ret;

    while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
                                  error == SSL_ERROR_WANT_WRITE)) {
        int currTimeout = 1;

        if (error == SSL_ERROR_WANT_READ) {
            /* printf("... server would read block\n"); */
        } else {
            /* printf("... server would write block\n"); */
        }

#ifdef CYASSL_DTLS
        currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
#endif
        select_ret = tcp_select(sockfd, currTimeout);

        if ((select_ret == TEST_RECV_READY) ||
                                        (select_ret == TEST_ERROR_READY)) {
            #ifndef CYASSL_CALLBACKS
                ret = SSL_accept(ssl);
            #else
                ret = CyaSSL_accept_ex(ssl,
                                    srvHandShakeCB, srvTimeoutCB, srvTo);
            #endif
            error = SSL_get_error(ssl, 0);
        }
        else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) {
            error = SSL_ERROR_WANT_READ;
        }
#ifdef CYASSL_DTLS
        else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) &&
                                            CyaSSL_dtls_got_timeout(ssl) >= 0) {
            error = SSL_ERROR_WANT_READ;
        }
#endif
        else {
            error = SSL_FATAL_ERROR;
        }
    }

    return ret;
}
Пример #2
0
static void NonBlockingSSL_Connect(CYASSL* ssl)
{
#ifndef CYASSL_CALLBACKS
    int ret = CyaSSL_connect(ssl);
#else
    int ret = CyaSSL_connect_ex(ssl, handShakeCB, timeoutCB, timeout);
#endif
    int error = CyaSSL_get_error(ssl, 0);
    SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl);
    int select_ret;

    while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
                                  error == SSL_ERROR_WANT_WRITE)) {
        int currTimeout = 1;

        if (error == SSL_ERROR_WANT_READ)
            printf("... client would read block\n");
        else
            printf("... client would write block\n");

#ifdef CYASSL_DTLS
        currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
#endif
        select_ret = tcp_select(sockfd, currTimeout);

        if ((select_ret == TEST_RECV_READY) ||
                                        (select_ret == TEST_ERROR_READY)) {
            #ifndef CYASSL_CALLBACKS
                    ret = CyaSSL_connect(ssl);
            #else
                ret = CyaSSL_connect_ex(ssl,handShakeCB,timeoutCB,timeout);
            #endif
            error = CyaSSL_get_error(ssl, 0);
        }
        else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) {
            error = SSL_ERROR_WANT_READ;
        }
#ifdef CYASSL_DTLS
        else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) &&
                                            CyaSSL_dtls_got_timeout(ssl) >= 0) {
            error = SSL_ERROR_WANT_READ;
        }
#endif
        else {
            error = SSL_FATAL_ERROR;
        }
    }
    if (ret != SSL_SUCCESS)
        err_sys("SSL_connect failed");
}
Пример #3
0
static void NonBlockingSSL_Accept(SSL* ssl)
{
#ifndef CYASSL_CALLBACKS
    int ret = SSL_accept(ssl);
#else
    int ret = CyaSSL_accept_ex(ssl, srvHandShakeCB, srvTimeoutCB, srvTo);
#endif
    int error = SSL_get_error(ssl, 0);
    SOCKET_T sockfd = (SOCKET_T)CyaSSL_get_fd(ssl);
    int select_ret;

    while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
                                  error == SSL_ERROR_WANT_WRITE)) {
        if (error == SSL_ERROR_WANT_READ)
            printf("... server would read block\n");
        else
            printf("... server would write block\n");

        if (CyaSSL_dtls(ssl))
            select_ret = tcp_select(sockfd,
                                    CyaSSL_dtls_get_current_timeout(ssl));
        else
            select_ret = tcp_select(sockfd, 1);

        if ((select_ret == TEST_RECV_READY) ||
                                        (select_ret == TEST_ERROR_READY)) {
            #ifndef CYASSL_CALLBACKS
                ret = SSL_accept(ssl);
            #else
                ret = CyaSSL_accept_ex(ssl,
                                    srvHandShakeCB, srvTimeoutCB, srvTo);
            #endif
            error = SSL_get_error(ssl, 0);
        }
        else if (select_ret == TEST_TIMEOUT &&
                    (!CyaSSL_dtls(ssl) ||
                    (CyaSSL_dtls_got_timeout(ssl) >= 0))) {
            error = SSL_ERROR_WANT_READ;
        }
        else {
            error = SSL_FATAL_ERROR;
        }
    }
    if (ret != SSL_SUCCESS)
        err_sys("SSL_accept failed");
}
/*
 * Pulled in from examples/server/server.c
 * Function to handle nonblocking. Loops until tcp_select notifies that it's
 * ready for action. 
 */
int NonBlockingSSL(CYASSL* ssl)
{
    int ret;
    int error;
    int select_ret;
    int sockfd = CyaSSL_get_fd(ssl);
    ret = CyaSSL_accept(ssl);
    error = CyaSSL_get_error(ssl, 0);
    while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
                                  error == SSL_ERROR_WANT_WRITE)) {
        int currTimeout = 1;

        /* print out for user notification */
        if (error == SSL_ERROR_WANT_READ)
            printf("... server would read block\n");
        else
            printf("... server would write block\n");

        select_ret = tcp_select(sockfd, currTimeout);
        
        /* if tcp_select signals ready try to accept otherwise continue loop*/
        if ((select_ret == TEST_RECV_READY) || 
            (select_ret == TEST_ERROR_READY)) {
            ret = CyaSSL_accept(ssl);
            error = CyaSSL_get_error(ssl, 0);
        }
        else if (select_ret == TEST_TIMEOUT) {
            error = SSL_ERROR_WANT_READ;
        }
        else {
            error = SSL_FATAL_ERROR;
        }
    }
    /* faliure to accept */
    if (ret != SSL_SUCCESS) {
        printf("Fatal error : SSL_accept failed\n");
        ret = SSL_FATAL_ERROR;
    }

    return ret;
}
/* Connect using Nonblocking - DTLS version */
static void NonBlockingDTLS_Connect(CYASSL* ssl)
{
    int ret = CyaSSL_connect(ssl);
    int error = CyaSSL_get_error(ssl, 0);
    int sockfd = (int)CyaSSL_get_fd(ssl); 
    int select_ret;
   
    while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || 
		error == SSL_ERROR_WANT_WRITE)) {
	    int currTimeout = 1;
	    if (error == SSL_ERROR_WANT_READ)
	        printf("... client would read block\n");
	    else
	        printf("... client would write block\n");
	    currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
	    select_ret = dtls_select(sockfd, currTimeout);
	    if ( ( select_ret == TEST_RECV_READY) || 
		    (select_ret == TEST_ERROR_READY)) {	
	        ret = CyaSSL_connect(ssl);
	        error = CyaSSL_get_error(ssl, 0);
	    }
	    else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) {
	        error = 2;
	    }
	    else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) && 
		    CyaSSL_dtls_got_timeout(ssl) >= 0) {
	        error = 2;
	    }
	    else{
	        error = SSL_FATAL_ERROR;
	    }
    }

    if (ret != SSL_SUCCESS) {
	    printf("SSL_connect failed with");
    }
}
Пример #6
0
/*
 *  ======== tcpHandler ========
 *  Creates new Task to handle new TCP connections.
 */
Void tcpHandler(UArg arg0, UArg arg1) {
	int sockfd;
	int ret;
	struct sockaddr_in servAddr;
	Error_Block eb;
	bool flag = true;
	bool internal_flag = true;
	int nbytes;
	char *buffer;
	char msg[] = "Hello from TM4C1294XL Connected Launchpad";
	CYASSL* ssl = (CYASSL *) arg0;

	fdOpenSession(TaskSelf());

	CyaSSL_Init();
	CYASSL_CTX* ctx = NULL;

	ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
	if (ctx == 0) {
		System_printf("tcpHandler: CyaSSL_CTX_new error.\n");
		exitApp(ctx);
	}

	if (CyaSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,
			sizeof(ca_cert_der_2048) / sizeof(char), SSL_FILETYPE_ASN1)
			!= SSL_SUCCESS) {
		System_printf("tcpHandler: Error loading ca_cert_der_2048"
				" please check the cyassl/certs_test.h file.\n");
		exitApp(ctx);
	}

	if (CyaSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048,
			sizeof(client_cert_der_2048) / sizeof(char), SSL_FILETYPE_ASN1)
			!= SSL_SUCCESS) {
		System_printf("tcpHandler: Error loading client_cert_der_2048,"
				" please check the cyassl/certs_test.h file.\n");
		exitApp(ctx);
	}

	if (CyaSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048,
			sizeof(client_key_der_2048) / sizeof(char), SSL_FILETYPE_ASN1)
			!= SSL_SUCCESS) {
		System_printf("tcpHandler: Error loading client_key_der_2048,"
				" please check the cyassl/certs_test.h file.\n");
		exitApp(ctx);
	}

	/* Init the Error_Block */
	Error_init(&eb);

	do {
		sockfd = socket(AF_INET, SOCK_STREAM, 0);
		if (sockfd < 0) {
			System_printf("tcpHandler: socket failed\n");
			Task_sleep(2000);
			continue;
		}

		memset((char *) &servAddr, 0, sizeof(servAddr));
		servAddr.sin_family = AF_INET;
		servAddr.sin_port = htons(TCPPORT);

		inet_aton(IP_ADDR, &servAddr.sin_addr);

		ret = connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr));

		if (ret < 0) {
			fdClose((SOCKET) sockfd);
			Task_sleep(2000);
			continue;
		}
	} while (ret != 0);

	if ((ssl = CyaSSL_new(ctx)) == NULL) {
		System_printf("tcpHandler: CyaSSL_new error.\n");
		exitApp(ctx);
	}

	CyaSSL_set_fd(ssl, sockfd);

	ret = CyaSSL_connect(ssl);

	/* Delete "TOP_LINE" and "END_LINE" for debugging. */

	/* TOP_LINE

	 System_printf("looked for: %d.\n", SSL_SUCCESS);
	 System_printf("return was: %d.\n", ret);
	 int err;
	 char err_buffer[80];
	 err = CyaSSL_get_error(ssl, 0);
	 System_printf("CyaSSL error: %d\n", err);
	 System_printf("CyaSSL error string: %s\n", CyaSSL_ERR_error_string(err, err_buffer));

	 END_LINE */

	if (ret == SSL_SUCCESS) {

		sockfd = CyaSSL_get_fd(ssl);

		/* Get a buffer to receive incoming packets. Use the default heap. */
		buffer = Memory_alloc(NULL, TCPPACKETSIZE, 0, &eb);

		if (buffer == NULL) {
			System_printf("tcpWorker: failed to alloc memory\n");
			exitApp(ctx);
		}

		/* Say hello to the server */
		while (flag) {
			if (CyaSSL_write(ssl, msg, strlen(msg)) != strlen(msg)) {
				ret = CyaSSL_get_error(ssl, 0);
				System_printf("Write error: %i.\n", ret);
			}
			while (internal_flag) {
				nbytes = CyaSSL_read(ssl, (char *) buffer, TCPPACKETSIZE);
				if (nbytes > 0) {
					internal_flag = false;
				}
			}
			/* success */
			System_printf("Heard: \"%s\".\n", buffer);
			CyaSSL_free(ssl);
			fdClose((SOCKET) sockfd);
			flag = false;
		}

		/* Free the buffer back to the heap */
		Memory_free(NULL, buffer, TCPPACKETSIZE);

		/*
		 *  Since deleteTerminatedTasks is set in the cfg file,
		 *  the Task will be deleted when the idle task runs.
		 */
		exitApp(ctx);

	} else {
		CyaSSL_free(ssl);
		fdClose((SOCKET) sockfd);
		System_printf("CyaSSL_connect failed.\n");
		fdCloseSession(TaskSelf());
		exitApp(ctx);
	}
}
OSStatus SocketReadHTTPSBody( mico_ssl_t ssl, HTTPHeader_t *inHeader )
{
  OSStatus err = kParamErr;
  ssize_t readResult;
  int selectResult;
  fd_set readSet;
  size_t    lastChunkLen, chunckheaderLen; 
  char *nextPackagePtr;
  struct timeval_t t;
  size_t          readLength;
  uint32_t pos = 0;
  t.tv_sec = 5;
  t.tv_usec = 0;
  int inSock = CyaSSL_get_fd( ssl );
  
  require( inHeader, exit );
  err = kNotReadableErr;
  
  FD_ZERO( &readSet );
  FD_SET( inSock, &readSet );

  /* Chunked data without content length */
  if( inHeader->chunkedData == true ){
    do{
      /* Find Chunk data length */
      while ( findChunkedDataLength( inHeader->chunkedDataBufferPtr, inHeader->extraDataLen, &inHeader->extraDataPtr ,"%llu", &inHeader->contentLength ) == false){
        require_action(inHeader->extraDataLen < inHeader->chunkedDataBufferLen, exit, err=kMalformedErr );

        selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
        require_action( selectResult >= 1, exit, err = kNotReadableErr );

        readResult = ssl_recv( ssl, inHeader->chunkedDataBufferPtr + inHeader->extraDataLen, (size_t)( inHeader->chunkedDataBufferLen - inHeader->extraDataLen ) );

        if( readResult  > 0 ) inHeader->extraDataLen += readResult;
        else { err = kConnectionErr; goto exit; }
      }

      chunckheaderLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr;

      /* Check the last chunk */
      if(inHeader->contentLength == 0){ 
        while( findCRLF( inHeader->extraDataPtr, inHeader->extraDataLen - chunckheaderLen, &nextPackagePtr ) == false){ //find CRLF
          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl,
                            (uint8_t *)( inHeader->extraDataPtr + inHeader->extraDataLen - chunckheaderLen ),
                            256 - inHeader->extraDataLen ); //Assume chunk trailer length is less than 256 (256 is the min chunk buffer, maybe dangerous

          if( readResult  > 0 ) inHeader->extraDataLen += readResult;
          else { err = kConnectionErr; goto exit; }
          (inHeader->onReceivedDataCallback)(inHeader, inHeader->extraDataLen - readResult, (uint8_t *)inHeader->extraDataPtr, readResult, inHeader->userContext);
        }

        err = kNoErr;
        goto exit;
      } 
      else{ // Read chunk data
        /* Chunk package already exist, callback, move to buffer's head */
        if( inHeader->extraDataLen >= inHeader->contentLength + chunckheaderLen + 2 ){
          require_action( *(inHeader->extraDataPtr + inHeader->contentLength ) == '\r' &&
                          *(inHeader->extraDataPtr + inHeader->contentLength + 1 ) == '\n', 
                          exit, err = kMalformedErr);

          (inHeader->onReceivedDataCallback)(inHeader,  pos, 
                                                        (uint8_t *)inHeader->extraDataPtr, 
                                                        inHeader->contentLength, 
                                                        inHeader->userContext);
          pos+=inHeader->contentLength;

          /* Move next chunk to chunked data buffer header point */
          lastChunkLen = inHeader->extraDataPtr - inHeader->chunkedDataBufferPtr + inHeader->contentLength;
          if(inHeader->contentLength) lastChunkLen += 2;  //Last chunck data has a CRLF tail
          memmove( inHeader->chunkedDataBufferPtr, inHeader->chunkedDataBufferPtr + lastChunkLen, inHeader->chunkedDataBufferLen - lastChunkLen  );
          inHeader->extraDataLen -= lastChunkLen;
        }
        /* Chunck exist without the last LF, generate callback abd recv LF */
        /* Callback , read LF */
        else if(inHeader->extraDataLen == inHeader->contentLength + chunckheaderLen +1){ //recv CR 

          require_action( *(inHeader->chunkedDataBufferPtr + inHeader->extraDataLen - 1) == '\r' ,
                          exit, err = kMalformedErr);

          (inHeader->onReceivedDataCallback)(inHeader,  pos, 
                                                        (uint8_t *)inHeader->extraDataPtr, 
                                                        inHeader->extraDataLen - chunckheaderLen-1, 
                                                        inHeader->userContext);
          pos+=inHeader->extraDataLen - chunckheaderLen-1;
          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, 1);

          if( readResult  > 0 ) {}
          else { err = kConnectionErr; goto exit; }

          require_action( *(inHeader->extraDataPtr) == '\n', exit, err = kMalformedErr);
          inHeader->extraDataLen = 0;
        }
        else{
          /* Callback , read , callback , read CRLF */
          (inHeader->onReceivedDataCallback)(inHeader, pos, 
                                                       (uint8_t *)inHeader->extraDataPtr, 
                                                       inHeader->extraDataLen - chunckheaderLen, 
                                                       inHeader->userContext);
          pos += inHeader->extraDataLen - chunckheaderLen;

          while ( inHeader->extraDataLen < inHeader->contentLength + chunckheaderLen  ){
            selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
            require_action( selectResult >= 1, exit, err = kNotReadableErr );

            if( inHeader->contentLength - (inHeader->extraDataLen - chunckheaderLen) > inHeader->chunkedDataBufferLen - chunckheaderLen)
              //Data needed is greater than valid buffer size
              readLength = inHeader->chunkedDataBufferLen - chunckheaderLen; 
            else
              //Data needed is less than valid buffer size
              readLength = inHeader->contentLength - (inHeader->extraDataLen - chunckheaderLen) ; 

            readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, readLength);
            
            if( readResult  > 0 ) inHeader->extraDataLen += readResult;
            else { err = kConnectionErr; goto exit; }

            (inHeader->onReceivedDataCallback)(inHeader, pos, 
                                                         (uint8_t *)inHeader->extraDataPtr, 
                                                         readResult, 
                                                         inHeader->userContext);
            pos += readResult;
          } 

          selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
          require_action( selectResult >= 1, exit, err = kNotReadableErr );

          readResult = ssl_recv( ssl, (uint8_t *)inHeader->extraDataPtr, 2);

          if( readResult  > 0 ) {}
          else { err = kConnectionErr; goto exit; }


          require_action( *(inHeader->extraDataPtr) == '\r' &&
                          *(inHeader->extraDataPtr+1 ) == '\n', 
                          exit, err = kMalformedErr);

          inHeader->extraDataLen = 0;
        }
      }
    }while(inHeader->contentLength != 0);
  }

  /* We has extra data but total length is not clear, store them to 1500 bytes buffer 
     return when connection is disconnected by remote server */
  // if( inHeader->dataEndedbyClose == true){ 
  //   if(inHeader->contentLength == 0) { //First read body, return using data received by SocketReadHTTPHeader
  //     inHeader->contentLength = inHeader->extraDataLen;
  //   }else{
  //     selectResult = select( inSock + 1, &readSet, NULL, NULL, NULL );
  //     require_action( selectResult >= 1, exit, err = kNotReadableErr );
      
  //     readResult = read( inSock,
  //                       (uint8_t*)( inHeader->extraDataPtr ),
  //                       1500 );
  //     if( readResult  > 0 ) inHeader->contentLength = readResult;
  //     else { err = kConnectionErr; goto exit; }
  //   }
  //   err = kNoErr;
  //   goto exit;
  // }

  while ( inHeader->extraDataLen < inHeader->contentLength )
  {
    selectResult = select( inSock + 1, &readSet, NULL, NULL, &t );
    require_action( selectResult >= 1, exit, err = kNotReadableErr );

    if(inHeader->isCallbackSupported == true){
      /* We has extra data, and we give these data to application by onReceivedDataCallback function */
      readLength = inHeader->contentLength - inHeader->extraDataLen > READ_LENGTH? READ_LENGTH:inHeader->contentLength - inHeader->extraDataLen;
      readResult = ssl_recv( ssl,
                        (uint8_t*)( inHeader->extraDataPtr),
                        readLength );
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }      
      (inHeader->onReceivedDataCallback)(inHeader, inHeader->extraDataLen - readResult, (uint8_t *)inHeader->extraDataPtr, readResult, inHeader->userContext);
    }else{
      /* We has extra data and we has a predefined buffer to store the total extra data return when all data has received*/
      readResult = ssl_recv( ssl,
                        (uint8_t*)( inHeader->extraDataPtr + inHeader->extraDataLen ),
                        ( inHeader->contentLength - inHeader->extraDataLen ) );
      
      if( readResult  > 0 ) inHeader->extraDataLen += readResult;
      else { err = kConnectionErr; goto exit; }
    }
  }
  err = kNoErr;
  
exit:
  if(err != kNoErr) inHeader->len = 0;
  return err;
}