Exemple #1
0
int main(int argc, char **argv)
{

	mygetopt(argc, argv);

	char *auth = read_auth(authfile);
	if (auth == NULL) {
		fprintf(stderr, "Null auth or file not found\n");
		exit(1);
	}

	char *cookie = parse_cookie(gcookie(auth, site));
	if (cookie != NULL) {
		printf("\n%s\n", cookie);

	}

	return 0;

}
Exemple #2
0
int main(int argc, char *argv[])
{
    int rc = -1;
    int index_cmd;

    index_cmd = mygetopt(argc, argv);
    if (optH) {
        usage();
        return 0;
    }
    if (index_cmd >= argc || !logname) {
        fprintf(stderr, "Type 'TEECON -?' to help.\n");
        return 1;
    }

    if (optA) {
        rc = _dos_open(logname, O_RDWR, &tee_handle);
        if (rc == 0) my_doslseek(tee_handle, 0L, 2);
        else if (rc == 2) optO = 1; /* retry with creat when the file is not found */
        else optO = 0;
    }
    if (optO && tee_handle == -1) rc = _dos_creat(logname, _A_NORMAL, &tee_handle);

    if (rc != 0) {
        fprintf(stderr, "FATAL: can't open the log file '%s'\n", logname);
        return -1;
    }

    my_psp = my_getpsp();
    org_int21 = _dos_getvect(0x21);
    _dos_setvect(0x21, Int21Handler);
    if (argv[index_cmd]) {
        rc = spawnvp(P_WAIT, argv[index_cmd], (char const * const *)(argv + index_cmd));
    }
    _dos_setvect(0x21, org_int21);
    fprintf(stderr, "%s : result=%d\n", argv[index_cmd], rc);
    if (tee_handle != -1) _dos_close(tee_handle);

    return rc;
}
Exemple #3
0
THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
{
    WOLFSSH_CTX* ctx = NULL;
    WOLFSSH* ssh = NULL;
    SOCKET_T sockFd = WOLFSSH_SOCKET_INVALID;
    SOCKADDR_IN_T clientAddr;
    socklen_t clientAddrSz = sizeof(clientAddr);
    char rxBuf[80];
    int ret;
    int ch;
    word16 port = wolfSshPort;
    char* host = (char*)wolfSshIp;
    const char* username = NULL;
    const char* password = NULL;
    const char* cmd      = NULL;
    byte imExit = 0;
    byte nonBlock = 0;
    byte keepOpen = 0;
#ifdef USE_WINDOWS_API
    byte rawMode = 0;
#endif

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;
    ((func_args*)args)->return_code = 0;

    while ((ch = mygetopt(argc, argv, "?NP:h:p:u:xc:Rtz")) != -1) {
        switch (ch) {
            case 'h':
                host = myoptarg;
                break;

            case 'z':
            #ifdef WOLFSSH_SHOW_SIZES
                wolfSSH_ShowSizes();
                exit(EXIT_SUCCESS);
            #endif
                break;

            case 'p':
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'u':
                username = myoptarg;
                break;

            case 'P':
                password = myoptarg;
                break;

            case 'x':
                /* exit after successful connection without read/write */
                imExit = 1;
                break;

            case 'N':
                nonBlock = 1;
                break;

        #if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS)
            case 'c':
                cmd = myoptarg;
                break;
        #ifdef USE_WINDOWS_API
           case 'R':
                rawMode = 1;
                break;
        #endif /* USE_WINDOWS_API */
        #endif

        #ifdef WOLFSSH_TERM
            case 't':
                keepOpen = 1;
                break;
        #endif
            case '?':
                ShowUsage();
                exit(EXIT_SUCCESS);

            default:
                ShowUsage();
                exit(MY_EX_USAGE);
        }
    }
    myoptind = 0;      /* reset for test cases */

    if (username == NULL)
        err_sys("client requires a username parameter.");

#ifdef SINGLE_THREADED
    if (keepOpen)
        err_sys("Threading needed for terminal session\n");
#endif

    ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
    if (ctx == NULL)
        err_sys("Couldn't create wolfSSH client context.");

    if (((func_args*)args)->user_auth == NULL)
        wolfSSH_SetUserAuth(ctx, wsUserAuth);
    else
        wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth);

    ssh = wolfSSH_new(ctx);
    if (ssh == NULL)
        err_sys("Couldn't create wolfSSH session.");

    if (password != NULL)
        wolfSSH_SetUserAuthCtx(ssh, (void*)password);

    wolfSSH_CTX_SetPublicKeyCheck(ctx, wsPublicKeyCheck);
    wolfSSH_SetPublicKeyCheckCtx(ssh, (void*)"You've been sampled!");

    ret = wolfSSH_SetUsername(ssh, username);
    if (ret != WS_SUCCESS)
        err_sys("Couldn't set the username.");

    build_addr(&clientAddr, host, port);
    tcp_socket(&sockFd);
    ret = connect(sockFd, (const struct sockaddr *)&clientAddr, clientAddrSz);
    if (ret != 0)
        err_sys("Couldn't connect to server.");

    if (nonBlock)
        tcp_set_nonblocking(&sockFd);

    ret = wolfSSH_set_fd(ssh, (int)sockFd);
    if (ret != WS_SUCCESS)
        err_sys("Couldn't set the session's socket.");

    if (cmd != NULL) {
        ret = wolfSSH_SetChannelType(ssh, WOLFSSH_SESSION_EXEC,
                            (byte*)cmd, (word32)WSTRLEN((char*)cmd));
        if (ret != WS_SUCCESS)
            err_sys("Couldn't set the channel type.");
    }

#ifdef WOLFSSH_TERM
    if (keepOpen) {
        ret = wolfSSH_SetChannelType(ssh, WOLFSSH_SESSION_TERMINAL, NULL, 0);
        if (ret != WS_SUCCESS)
            err_sys("Couldn't set the terminal channel type.");
    }
#endif

    if (!nonBlock)
        ret = wolfSSH_connect(ssh);
    else
        ret = NonBlockSSH_connect(ssh);
    if (ret != WS_SUCCESS) {
        printf("err = %s\n", wolfSSH_get_error_name(ssh));
        err_sys("Couldn't connect SSH stream.");
    }

#if !defined(SINGLE_THREADED) && !defined(WOLFSSL_NUCLEUS)
    if (keepOpen) /* set up for psuedo-terminal */
        SetEcho(2);

    if (cmd != NULL || keepOpen == 1) {
    #if defined(_POSIX_THREADS)
        thread_args arg;
        pthread_t   thread[2];

        arg.ssh = ssh;
        wc_InitMutex(&arg.lock);
        pthread_create(&thread[0], NULL, readInput, (void*)&arg);
        pthread_create(&thread[1], NULL, readPeer, (void*)&arg);
        pthread_join(thread[1], NULL);
        pthread_cancel(thread[0]);
    #elif defined(_MSC_VER)
        thread_args arg;
        HANDLE thread[2];

        arg.ssh     = ssh;
        arg.rawMode = rawMode;
        wc_InitMutex(&arg.lock);
        thread[0] = CreateThread(NULL, 0, readInput, (void*)&arg, 0, 0);
        thread[1] = CreateThread(NULL, 0, readPeer, (void*)&arg, 0, 0);
        WaitForSingleObject(thread[1], INFINITE);
        CloseHandle(thread[0]);
        CloseHandle(thread[1]);
    #else
        err_sys("No threading to use");
    #endif
        if (keepOpen)
            SetEcho(1);
    }
    else
#endif
    if (!imExit) {
        ret = wolfSSH_stream_send(ssh, (byte*)testString,
                                  (word32)strlen(testString));
        if (ret <= 0)
            err_sys("Couldn't send test string.");

        do {
            ret = wolfSSH_stream_read(ssh, (byte*)rxBuf, sizeof(rxBuf) - 1);
            if (ret <= 0) {
                ret = wolfSSH_get_error(ssh);
                if (ret != WS_WANT_READ && ret != WS_WANT_WRITE)
                    err_sys("Stream read failed.");
            }
        } while (ret == WS_WANT_READ || ret == WS_WANT_WRITE);

        rxBuf[ret] = '\0';
        printf("Server said: %s\n", rxBuf);
    }
    ret = wolfSSH_shutdown(ssh);
    WCLOSESOCKET(sockFd);
    wolfSSH_free(ssh);
    wolfSSH_CTX_free(ctx);
    if (ret != WS_SUCCESS)
        err_sys("Closing stream failed. Connection could have been closed by peer");

#if defined(HAVE_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

    return 0;
}
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    int      clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[1024];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

    while ((ch = mygetopt(argc, argv, "?dbsnup:v:l:A:c:k:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                version = -1;  /* DTLS flag */
                break;

            case 'p' :
                port = atoi(myoptarg);
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                if (doDTLS)
                    version = -1;  /* stay with DTLS */
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    argc -= myoptind;
    argv += myoptind;
    myoptind = 0;      /* reset for test cases */

    switch (version) {
        case 0:
            method = SSLv3_server_method();
            break;

        case 1:
            method = TLSv1_server_method();
            break;

        case 2:
            method = TLSv1_1_server_method();
            break;

        case 3:
            method = TLSv1_2_server_method();
            break;

#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("can't set cipher list");

    if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                     != SSL_SUCCESS)
        err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");


#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

    if (!useNtruKey) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }

#ifndef NO_PSK
    if (usePsk) {
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL)
            if (SSL_CTX_set_cipher_list(ctx,"PSK-AES256-CBC-SHA") !=SSL_SUCCESS)
                err_sys("can't set cipher list");
    }
#endif

    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
        err_sys("can't set cipher list");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
        CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #else
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

#ifdef NON_BLOCKING
    tcp_set_nonblocking(&clientfd);
    NonBlockingSSL_Accept(ssl);
#else
    #ifndef CYASSL_CALLBACKS
        if (SSL_accept(ssl) != SSL_SUCCESS) {
            int err = SSL_get_error(ssl, 0);
            char buffer[80];
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }
    #else
        NonBlockingSSL_Accept(ssl);
    #endif
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input));
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);
    }
    
    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;
    return 0;
}
Exemple #5
0
void client_test(void* args)
{
    SOCKET_T sockfd = 0;

    CYASSL_METHOD*  method  = 0;
    CYASSL_CTX*     ctx     = 0;
    CYASSL*         ssl     = 0;
    
#ifdef TEST_RESUME
    CYASSL*         sslResume = 0;
    CYASSL_SESSION* session = 0;
    char         resumeMsg[] = "resuming cyassl!";
    int          resumeSz    = sizeof(resumeMsg);
#endif

    char msg[64] = "hello cyassl!";
    char reply[1024];
    int  input;
    int  msgSz = strlen(msg);

    int   port   = yasslPort;
    char* host   = (char*)yasslIP;
    char* domain = "www.yassl.com";

    int    ch;
    int    version = CLIENT_DEFAULT_VERSION;
    int    usePsk   = 0;
    int    sendGET  = 0;
    int    benchmark = 0;
    int    doDTLS    = 0;
    int    matchName = 0;
    int    doPeerCheck = 1;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)caCert;
    char*  ourCert    = (char*)cliCert;
    char*  ourKey     = (char*)cliKey;

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

    while ((ch = mygetopt(argc, argv, "?gdusmh:p:v:l:A:c:k:b:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'g' :
                sendGET = 1;
                break;

            case 'd' :
                doPeerCheck = 0;
                break;

            case 'u' :
                doDTLS  = 1;
                version = -1;  /* DTLS flag */
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'm' :
                matchName = 1;
                break;

            case 'h' :
                host   = myoptarg;
                domain = myoptarg;
                break;

            case 'p' :
                port = atoi(myoptarg);
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                if (doDTLS)
                    version = -1;   /* DTLS flag */
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'b' :
                benchmark = atoi(myoptarg);
                if (benchmark < 0 || benchmark > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    argc -= myoptind;
    argv += myoptind;
    myoptind = 0;      /* reset for test cases */

    switch (version) {
        case 0:
            method = CyaSSLv3_client_method();
            break;

        case 1:
            method = CyaTLSv1_client_method();
            break;

        case 2:
            method = CyaTLSv1_1_client_method();
            break;

        case 3:
            method = CyaTLSv1_2_client_method();
            break;

#ifdef CYASSL_DTLS
        case -1:
            method = CyaDTLSv1_client_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = CyaSSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (CyaSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("can't set cipher list");

#ifndef NO_PSK
    if (usePsk)
        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
#endif

#ifdef OPENSSL_EXTRA
    CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL)
        if (CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
            err_sys("can't set cipher list");
#endif

#ifdef USER_CA_CB
    CyaSSL_CTX_SetCACb(ctx, CaCb);
#endif

#ifdef VERIFY_CALLBACK
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
#endif

    if (CyaSSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                     != SSL_SUCCESS)
        err_sys("can't load client cert file, check file and run from"
                " CyaSSL home dir");

    if (CyaSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                     != SSL_SUCCESS)
        err_sys("can't load client cert file, check file and run from"
                " CyaSSL home dir");    

    if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");

    if (doPeerCheck == 0)
        CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);

    if (benchmark) {
        /* time passed in number of connects give average */
        int times = benchmark;
        int i = 0;

        double start = current_time(), avg;

        for (i = 0; i < times; i++) {
            tcp_connect(&sockfd, host, port, doDTLS);
            ssl = CyaSSL_new(ctx);
            CyaSSL_set_fd(ssl, sockfd);
            if (CyaSSL_connect(ssl) != SSL_SUCCESS)
                err_sys("SSL_connect failed");

            CyaSSL_shutdown(ssl);
            CyaSSL_free(ssl);
            CloseSocket(sockfd);
        }
        avg = current_time() - start;
        avg /= times;
        avg *= 1000;   /* milliseconds */
        printf("CyaSSL_connect avg took: %8.3f milliseconds\n", avg);

        CyaSSL_CTX_free(ctx);
        ((func_args*)args)->return_code = 0;

        exit(EXIT_SUCCESS);
    }

    tcp_connect(&sockfd, host, port, doDTLS);
    ssl = CyaSSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL object");
    CyaSSL_set_fd(ssl, sockfd);
#ifdef HAVE_CRL
    if (CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL) != SSL_SUCCESS)
        err_sys("can't enable crl check");
    if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
        err_sys("can't load crl, check crlfile and date validity");
    if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
        err_sys("can't set crl callback");
#endif
    if (matchName && doPeerCheck)
        CyaSSL_check_domain_name(ssl, domain);
#ifdef NON_BLOCKING
    tcp_set_nonblocking(&sockfd);
    NonBlockingSSL_Connect(ssl);
#else
    #ifndef CYASSL_CALLBACKS
        if (CyaSSL_connect(ssl) != SSL_SUCCESS) {/* see note at top of README */
            int  err = CyaSSL_get_error(ssl, 0);
            char buffer[80];
            printf("err = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer));
            err_sys("SSL_connect failed");/* if you're getting an error here  */
        }
    #else
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;
        NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
    #endif
#endif
    showPeer(ssl);

    if (sendGET) {
        printf("SSL connect ok, sending GET...\n");
        msgSz = 28;
        strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
    }
    if (CyaSSL_write(ssl, msg, msgSz) != msgSz)
        err_sys("SSL_write failed");

    input = CyaSSL_read(ssl, reply, sizeof(reply));
    if (input > 0) {
        reply[input] = 0;
        printf("Server response: %s\n", reply);

        if (sendGET) {  /* get html */
            while (1) {
                input = CyaSSL_read(ssl, reply, sizeof(reply));
                if (input > 0) {
                    reply[input] = 0;
                    printf("%s\n", reply);
                }
                else
                    break;
            }
        }
    }
  
#ifdef TEST_RESUME
    if (doDTLS) {
        strncpy(msg, "break", 6);
        msgSz = (int)strlen(msg);
        /* try to send session close */
        CyaSSL_write(ssl, msg, msgSz);
    }
    session   = CyaSSL_get_session(ssl);
    sslResume = CyaSSL_new(ctx);
#endif

    if (doDTLS == 0)            /* don't send alert after "break" command */
        CyaSSL_shutdown(ssl);  /* echoserver will interpret as new conn */
    CyaSSL_free(ssl);
    CloseSocket(sockfd);

#ifdef TEST_RESUME
    if (doDTLS) {
        #ifdef USE_WINDOWS_API 
            Sleep(500);
        #else
            sleep(1);
        #endif
    }
    tcp_connect(&sockfd, host, port, doDTLS);
    CyaSSL_set_fd(sslResume, sockfd);
    CyaSSL_set_session(sslResume, session);
   
    showPeer(sslResume);
#ifdef NON_BLOCKING
    tcp_set_nonblocking(&sockfd);
    NonBlockingSSL_Connect(sslResume);
#else
    #ifndef CYASSL_CALLBACKS
        if (CyaSSL_connect(sslResume) != SSL_SUCCESS)
            err_sys("SSL resume failed");
    #else
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;
        NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
    #endif
#endif

#ifdef OPENSSL_EXTRA
    if (CyaSSL_session_reused(sslResume))
        printf("reused session id\n");
    else
        printf("didn't reuse session id!!!\n");
#endif
  
    if (CyaSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
        err_sys("SSL_write failed");

#ifdef NON_BLOCKING
    /* need to give server a chance to bounce a message back to client */
    #ifdef USE_WINDOWS_API
        Sleep(500);
    #else
        sleep(1);
    #endif
#endif

    input = CyaSSL_read(sslResume, reply, sizeof(reply));
    if (input > 0) {
        reply[input] = 0;
        printf("Server resume response: %s\n", reply);
    }

    /* try to send session break */
    CyaSSL_write(sslResume, msg, msgSz); 

    CyaSSL_shutdown(sslResume);
    CyaSSL_free(sslResume);
#endif /* TEST_RESUME */

    CyaSSL_CTX_free(ctx);
    CloseSocket(sockfd);

    ((func_args*)args)->return_code = 0;
}
Exemple #6
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = WOLFSSL_SOCKET_INVALID;
    SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    const char msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = wolfSSLPort;
    int    usePsk = 0;
    int    usePskPlus = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    needDH = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    wc_shutdown     = 0;
    int    resume = 0;
    int    resumeCount = 0;
    int    loopIndefinitely = 0;
    int    echoData = 0;
    int    throughput = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    short  minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
    short  minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
    int    doListen = 1;
    int    crlFlags = 0;
    int    ret;
    int    err = 0;
    char*  serverReadyFile = NULL;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    const char* ourDhParam = dhParam;
    tcp_ready*  readySignal = NULL;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef WOLFSSL_TRUST_PEER_CERT
    const char* trustCert  = NULL;
#endif

#ifndef NO_PSK
    int sendPskIdentityHint = 1;
#endif

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;
    (void)needDH;
    (void)ourKey;
    (void)ourCert;
    (void)ourDhParam;
    (void)verifyCert;
    (void)useNtruKey;
    (void)doCliCertCheck;
    (void)minDhKeyBits;
    (void)minRsaKeyBits;
    (void)minEccKeyBits;
    (void)alpnList;
    (void)alpn_opt;
    (void)crlFlags;
    (void)readySignal;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#ifdef WOLFSSL_VXWORKS
    useAnyAddr = 1;
#else
    while ((ch = mygetopt(argc, argv, "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:"))
                         != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'j' :
                usePskPlus = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'R' :
                serverReadyFile = myoptarg;
                break;

            case 'r' :
                #ifndef NO_SESSION_CACHE
                    resume = 1;
                #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'D' :
                #ifndef NO_DH
                    ourDhParam = myoptarg;
                #endif
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;
            case 'I':
                #ifndef NO_PSK
                    sendPskIdentityHint = 0;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            case 'i' :
                loopIndefinitely = 1;
                break;

            case 'e' :
                echoData = 1;
                break;

            case 'B':
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            #ifdef WOLFSSL_TRUST_PEER_CERT
            case 'E' :
                 trustCert = myoptarg;
                break;
            #endif

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = SSLv3_server_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif

#ifdef CYASSL_DTLS
    #ifndef NO_OLD_TLS
        case -1:
            method = DTLSv1_server_method();
            break;
    #endif

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    if (TicketInit() != 0)
        err_sys("unable to setup Session Ticket Key context");
    wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    if (!usePsk) {
        usePsk = 1;
    }
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    if (!usePsk) {
        usePsk = 1;
    }
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if ((!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " wolfSSL home dir");
    }
#endif

#ifndef NO_DH
    if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) {
        err_sys("Error setting minimum DH key size");
    }
#endif
#ifndef NO_RSA
    if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum RSA key size");
    }
#endif
#ifdef HAVE_ECC
    if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum ECC key size");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from wolfSSL home dir");
    }
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from wolfSSL home dir");
    }
#endif

    if (usePsk || usePskPlus) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);

        if (sendPskIdentityHint == 1)
            SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

        if (cipherList == NULL && !usePskPlus) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
                needDH = 1;
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs
       if using PSK Plus then verify peer certs except PSK suites */
    if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK :
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        #ifdef WOLFSSL_TRUST_PEER_CERT
        if (trustCert) {
            if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
                                            SSL_FILETYPE_PEM)) != SSL_SUCCESS) {
                err_sys("can't load trusted peer cert file");
            }
        }
        #endif /* WOLFSSL_TRUST_PEER_CERT */
   }
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

#ifdef USE_WINDOWS_API
    if (port == 0) {
        /* Generate random port for testing */
        port = GetRandomPort();
    }
#endif /* USE_WINDOWS_API */

    while (1) {
        /* allow resume option */
        if(resumeCount > 1) {
            if (doDTLS == 0) {
                SOCKADDR_IN_T client;
                socklen_t client_len = sizeof(client);
                clientfd = accept(sockfd, (struct sockaddr*)&client,
                                 (ACCEPT_THIRD_T)&client_len);
            } else {
                tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
                clientfd = sockfd;
            }
            if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
                err_sys("tcp accept failed");
            }
        }

        ssl = SSL_new(ctx);
        if (ssl == NULL)
            err_sys("unable to get SSL");

#ifndef NO_HANDSHAKE_DONE_CB
        wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
#ifdef HAVE_CRL
#ifdef HAVE_CRL_MONITOR
        crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON;
#endif
        if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS)
            err_sys("unable to enable CRL");
        if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags)
                                                                 != SSL_SUCCESS)
            err_sys("unable to load CRL");
        if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("unable to set CRL callback url");
#endif
#ifdef HAVE_OCSP
        if (useOcsp) {
            if (ocspUrl != NULL) {
                CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                        | CYASSL_OCSP_URL_OVERRIDE);
            }
            else
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
        }
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
        if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
            err_sys("can't enable OCSP Stapling Certificate Manager");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#endif
#ifdef HAVE_PK_CALLBACKS
        if (pkCallbacks)
            SetupPkCallbacks(ctx, ssl);
#endif

        /* do accept */
        readySignal = ((func_args*)args)->signal;
        if (readySignal) {
            readySignal->srfName = serverReadyFile;
        }
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
                       doDTLS, serverReadyFile ? 1 : 0, doListen);
        doListen = 0; /* Don't listen next time */

        if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
            err_sys("error in setting fd");
        }

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
        }
#endif

#ifdef WOLFSSL_DTLS
        if (doDTLS) {
            SOCKADDR_IN_T cliaddr;
            byte          b[1500];
            int           n;
            socklen_t     len = sizeof(cliaddr);

            /* For DTLS, peek at the next datagram so we can get the client's
             * address and set it into the ssl object later to generate the
             * cookie. */
            n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                              (struct sockaddr*)&cliaddr, &len);
            if (n <= 0)
                err_sys("recvfrom failed");

            wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
        }
#endif
        if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
                                                               || needDH == 1) {
            #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
                CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
            #elif !defined(NO_DH)
                SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
            #endif
        }

#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(ssl, 1);
            tcp_set_nonblocking(&clientfd);
        }
#endif

        do {
#ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_PENDING_E) {
                ret = AsyncCryptPoll(ssl);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
#endif

            err = 0; /* Reset error */
#ifndef CYASSL_CALLBACKS
            if (nonBlocking) {
                ret = NonBlockingSSL_Accept(ssl);
            }
            else {
                ret = SSL_accept(ssl);
            }
#else
            ret = NonBlockingSSL_Accept(ssl);
#endif
            if (ret != SSL_SUCCESS) {
                err = SSL_get_error(ssl, 0);
            }
        } while (ret != SSL_SUCCESS && err == WC_PENDING_E);

        if (ret != SSL_SUCCESS) {
            char buffer[CYASSL_MAX_ERROR_SZ];
            err = SSL_get_error(ssl, 0);
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }

        showPeer(ssl);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            char *protocol_name = NULL, *list = NULL;
            word16 protocol_nameSz = 0, listSz = 0;

            err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Sent ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("No ALPN response sent (no match)\n");
            else
                printf("Getting ALPN protocol name failed\n");

            err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
            if (err == SSL_SUCCESS)
                printf("List of protocol names sent by Client: %s (%d)\n",
                       list, listSz);
            else
                printf("Get list of client's protocol name failed\n");

            free(list);
        }
#endif
        if(echoData == 0 && throughput == 0) {
            ret = SSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = 0;
                printf("Client message: %s\n", input);

            }
            else if (ret < 0) {
                int readErr = SSL_get_error(ssl, 0);
                if (readErr != SSL_ERROR_WANT_READ)
                    err_sys("SSL_read failed");
            }

            if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
                err_sys("SSL_write failed");
        }
        else {
            ServerEchoData(ssl, clientfd, echoData, throughput);
        }

#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
        Task_yield();
#endif

        if (doDTLS == 0) {
            ret = SSL_shutdown(ssl);
            if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
                SSL_shutdown(ssl);    /* bidirectional shutdown */
        }
        SSL_free(ssl);

        CloseSocket(clientfd);

        if (resume == 1 && resumeCount == 0) {
            resumeCount++;           /* only do one resume for testing */
            continue;
        }
        resumeCount = 0;

        if(!loopIndefinitely) {
            break;  /* out of while loop, done with normal and resume option */
        }
    } /* while(1) */

    CloseSocket(sockfd);
    SSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    TicketCleanup();
#endif

    /* There are use cases  when these assignments are not read. To avoid
     * potential confusion those warnings have been handled here.
     */
    (void) ourKey;
    (void) verifyCert;
    (void) doCliCertCheck;
    (void) useNtruKey;
    (void) ourDhParam;
    (void) ourCert;
#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
/* Main entry point for the program.
 *
 * argc  The count of command line arguments.
 * argv  The command line arguments.
 * returns 0 on success and 1 otherwise.
 */
int main(int argc, char* argv[])
{
    int                 i;
    int                 ch;

    /* Parse the command line arguments. */
    while ((ch = mygetopt(argc, argv, OPTIONS)) != -1) {
        switch (ch) {
            /* Help with command line options. */
            case '?':
                Usage();
                exit(EXIT_SUCCESS);

            /* Port number to listen on. */
            case 'p':
                port = (word16)atoi(myoptarg);
                break;

            /* Version of SSL/TLS to use. */
            case 'v':
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* List of cipher suites to use. */
            case 'l':
                cipherList = myoptarg;
                break;

            /* File name of server certificate for authentication. */
            case 'c':
                ourCert = myoptarg;
                break;

            /* File name of server private key for authentication. */
            case 'k':
                ourKey = myoptarg;
                break;

            /* File name of client certificate/CA for peer verification. */
            case 'A':
                verifyCert = myoptarg;
                break;

            /* Number of connections to make. */
            case 't':
                numThreads  = atoi(myoptarg);
                if (numThreads < 0 || numThreads > 100) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Number of connections to make. */
            case 'n':
                maxConns  = atoi(myoptarg);
                if (maxConns < 0 || maxConns > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                maxBytes = 0;
                break;

            /* Number of conncurrent connections to use. */
            case 'N':
                numConns  = atoi(myoptarg);
                if (numConns < 0 || numConns > 100000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Number of bytes to read each call. */
            case 'R':
                numBytesRead = atoi(myoptarg);
                if (numBytesRead <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Number of bytes to write each call. */
            case 'W':
                numBytesWrite = atoi(myoptarg);
                if (numBytesWrite <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Maximum number of read and write bytes (separate counts). */
            case 'B':
                maxBytes = atoi(myoptarg);
                if (maxBytes <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                maxConns = 0;
                break;

            /* Unrecognized command line argument. */
            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

#ifdef DEBUG_WOLFSSL
    wolfSSL_Debugging_ON();
#endif

    /* Initialize wolfSSL */
    wolfSSL_Init();

    RandomReply(reply, sizeof(reply));

    /* Create SSL/TLS connection data object. */
    sslConnCtx = SSLConn_New(numThreads, numConns, numBytesRead, numBytesWrite,
                             maxConns, maxBytes);
    if (sslConnCtx == NULL)
        exit(EXIT_FAILURE);

    for (i = 0; i < numThreads; i++) {
        if (pthread_create(&sslConnCtx->threadData[i].thread_id, NULL,
                           ThreadHandler, &sslConnCtx->threadData[i]) < 0) {
            perror("ERRROR: could not create thread");
        }
    }

    /* Start all the threads. */
    for (i = 0; i < numThreads; i++)
        pthread_join(sslConnCtx->threadData[i].thread_id, NULL) ;

    sslConnCtx->totalTime = current_time(0) - sslConnCtx->totalTime;

    SSLConn_PrintStats(sslConnCtx);
    SSLConn_Free(sslConnCtx);

    wolfSSL_Cleanup();

    exit(EXIT_SUCCESS);
}
Exemple #8
0
int mqttclient_test(void* args)
{
    int rc;
    MqttClient client;
    MqttNet net;
    word16 port = 0;
    const char* host = DEFAULT_MQTT_HOST;
    int use_tls = 0;
    MqttQoS qos = DEFAULT_MQTT_QOS;
    byte clean_session = 1;
    word16 keep_alive_sec = DEFAULT_KEEP_ALIVE_SEC;
    const char* client_id = DEFAULT_CLIENT_ID;
    int enable_lwt = 0;
    const char* username = NULL;
    const char* password = NULL;
    byte *tx_buf = NULL, *rx_buf = NULL;
    const char* topicName = DEFAULT_TOPIC_NAME;
    word32 cmd_timeout_ms = DEFAULT_CMD_TIMEOUT_MS;
    byte test_mode = 0;

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

    while ((rc = mygetopt(argc, argv, "?h:p:tc:q:sk:i:lu:w:n:C:T")) != -1) {
        switch ((char)rc) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'h' :
                host = myoptarg;
                break;

            case 'p' :
                port = (word16)XATOI(myoptarg);
                if (port == 0) {
                    return err_sys("Invalid Port Number!");
                }
                break;

            case 't':
                use_tls = 1;
                break;

            case 'c':
                mTlsFile = myoptarg;
                break;

            case 'q' :
                qos = (MqttQoS)((byte)XATOI(myoptarg));
                if (qos > MQTT_QOS_2) {
                    return err_sys("Invalid QoS value!");
                }
                break;

            case 's':
                clean_session = 0;
                break;

            case 'k':
                keep_alive_sec = XATOI(myoptarg);
                break;

            case 'i':
                client_id = myoptarg;
                break;

            case 'l':
                enable_lwt = 1;
                break;

            case 'u':
                username = myoptarg;
                break;

            case 'w':
                password = myoptarg;
                break;

            case 'n':
                topicName = myoptarg;
                break;

            case 'C':
                cmd_timeout_ms = XATOI(myoptarg);
                break;

            case 'T':
                test_mode = 1;
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0; /* reset for test cases */

    /* Start example MQTT Client */
    PRINTF("MQTT Client: QoS %d", qos);

    /* Initialize Network */
    rc = MqttClientNet_Init(&net);
    PRINTF("MQTT Net Init: %s (%d)",
        MqttClient_ReturnCodeToString(rc), rc);
    if (rc != MQTT_CODE_SUCCESS) {
        goto exit;
    }

    /* Initialize MqttClient structure */
    tx_buf = (byte*)WOLFMQTT_MALLOC(MAX_BUFFER_SIZE);
    rx_buf = (byte*)WOLFMQTT_MALLOC(MAX_BUFFER_SIZE);
    rc = MqttClient_Init(&client, &net, mqttclient_message_cb,
        tx_buf, MAX_BUFFER_SIZE, rx_buf, MAX_BUFFER_SIZE,
        cmd_timeout_ms);
    PRINTF("MQTT Init: %s (%d)",
        MqttClient_ReturnCodeToString(rc), rc);
    if (rc != MQTT_CODE_SUCCESS) {
        goto exit;
    }

    /* Connect to broker */
    rc = MqttClient_NetConnect(&client, host, port,
        DEFAULT_CON_TIMEOUT_MS, use_tls, mqttclient_tls_cb);
    PRINTF("MQTT Socket Connect: %s (%d)",
        MqttClient_ReturnCodeToString(rc), rc);
    if (rc == MQTT_CODE_SUCCESS) {
        /* Define connect parameters */
        MqttConnect connect;
        MqttMessage lwt_msg;
        XMEMSET(&connect, 0, sizeof(MqttConnect));
        connect.keep_alive_sec = keep_alive_sec;
        connect.clean_session = clean_session;
        connect.client_id = client_id;
        /* Last will and testament sent by broker to subscribers
            of topic when broker connection is lost */
        XMEMSET(&lwt_msg, 0, sizeof(lwt_msg));
        connect.lwt_msg = &lwt_msg;
        connect.enable_lwt = enable_lwt;
        if (enable_lwt) {
            /* Send client id in LWT payload */
            lwt_msg.qos = qos;
            lwt_msg.retain = 0;
            lwt_msg.topic_name = WOLFMQTT_TOPIC_NAME"lwttopic";
            lwt_msg.buffer = (byte*)client_id;
            lwt_msg.total_len = (word16)XSTRLEN(client_id);
        }
        /* Optional authentication */
        connect.username = username;
        connect.password = password;

        /* Send Connect and wait for Connect Ack */
        rc = MqttClient_Connect(&client, &connect);
        PRINTF("MQTT Connect: %s (%d)",
            MqttClient_ReturnCodeToString(rc), rc);
        if (rc == MQTT_CODE_SUCCESS) {
            MqttSubscribe subscribe;
            MqttUnsubscribe unsubscribe;
            MqttTopic topics[1], *topic;
            MqttPublish publish;
            int i;

            /* Build list of topics */
            topics[0].topic_filter = topicName;
            topics[0].qos = qos;

            /* Validate Connect Ack info */
            PRINTF("MQTT Connect Ack: Return Code %u, Session Present %d",
                connect.ack.return_code,
                (connect.ack.flags & MQTT_CONNECT_ACK_FLAG_SESSION_PRESENT) ?
                    1 : 0
            );

            /* Subscribe Topic */
            XMEMSET(&subscribe, 0, sizeof(MqttSubscribe));
            subscribe.packet_id = mqttclient_get_packetid();
            subscribe.topic_count = sizeof(topics)/sizeof(MqttTopic);
            subscribe.topics = topics;
            rc = MqttClient_Subscribe(&client, &subscribe);
            PRINTF("MQTT Subscribe: %s (%d)",
                MqttClient_ReturnCodeToString(rc), rc);
            if (rc != MQTT_CODE_SUCCESS) {
                goto exit;
            }
            for (i = 0; i < subscribe.topic_count; i++) {
                topic = &subscribe.topics[i];
                PRINTF("  Topic %s, Qos %u, Return Code %u",
                    topic->topic_filter, topic->qos, topic->return_code);
            }

            /* Publish Topic */
            XMEMSET(&publish, 0, sizeof(MqttPublish));
            publish.retain = 0;
            publish.qos = qos;
            publish.duplicate = 0;
            publish.topic_name = topicName;
            publish.packet_id = mqttclient_get_packetid();
            publish.buffer = (byte*)TEST_MESSAGE;
            publish.total_len = (word16)XSTRLEN(TEST_MESSAGE);
            rc = MqttClient_Publish(&client, &publish);
            PRINTF("MQTT Publish: Topic %s, %s (%d)",
                publish.topic_name, MqttClient_ReturnCodeToString(rc), rc);
            if (rc != MQTT_CODE_SUCCESS) {
                goto exit;
            }

            /* Read Loop */
            PRINTF("MQTT Waiting for message...");
            while (mStopRead == 0) {
                /* Try and read packet */
                rc = MqttClient_WaitMessage(&client, cmd_timeout_ms);
                if (rc == MQTT_CODE_ERROR_TIMEOUT) {
                    /* Check to see if command data (stdin) is available */
                    rc = MqttClientNet_CheckForCommand(&net, rx_buf, MAX_BUFFER_SIZE);
                    if (rc > 0) {
                        /* Publish Topic */
                        XMEMSET(&publish, 0, sizeof(MqttPublish));
                        publish.retain = 0;
                        publish.qos = qos;
                        publish.duplicate = 0;
                        publish.topic_name = topicName;
                        publish.packet_id = mqttclient_get_packetid();
                        publish.buffer = rx_buf;
                        publish.total_len = (word16)rc;
                        rc = MqttClient_Publish(&client, &publish);
                        PRINTF("MQTT Publish: Topic %s, %s (%d)",
                            publish.topic_name, MqttClient_ReturnCodeToString(rc), rc);
                    }
                    /* Keep Alive */
                    else {
                        rc = MqttClient_Ping(&client);
                        if (rc != MQTT_CODE_SUCCESS) {
                            PRINTF("MQTT Ping Keep Alive Error: %s (%d)",
                                MqttClient_ReturnCodeToString(rc), rc);
                            break;
                        }
                    }
                }
                else if (rc != MQTT_CODE_SUCCESS) {
                    /* There was an error */
                    PRINTF("MQTT Message Wait: %s (%d)",
                        MqttClient_ReturnCodeToString(rc), rc);
                    break;
                }

                /* Exit if test mode */
                if (test_mode) {
                    break;
                }
            }
            /* Check for error */
            if (rc != MQTT_CODE_SUCCESS) {
                goto exit;
            }

            /* Unsubscribe Topics */
            XMEMSET(&unsubscribe, 0, sizeof(MqttUnsubscribe));
            unsubscribe.packet_id = mqttclient_get_packetid();
            unsubscribe.topic_count = sizeof(topics)/sizeof(MqttTopic);
            unsubscribe.topics = topics;
            rc = MqttClient_Unsubscribe(&client, &unsubscribe);
            PRINTF("MQTT Unsubscribe: %s (%d)",
                MqttClient_ReturnCodeToString(rc), rc);
            if (rc != MQTT_CODE_SUCCESS) {
                goto exit;
            }

            /* Disconnect */
            rc = MqttClient_Disconnect(&client);
            PRINTF("MQTT Disconnect: %s (%d)",
                MqttClient_ReturnCodeToString(rc), rc);
        }

        rc = MqttClient_NetDisconnect(&client);
        PRINTF("MQTT Socket Disconnect: %s (%d)",
             MqttClient_ReturnCodeToString(rc), rc);
    }

exit:
    /* Free resources */
    if (tx_buf) WOLFMQTT_FREE(tx_buf);
    if (rx_buf) WOLFMQTT_FREE(rx_buf);

    /* Cleanup network */
    MqttClientNet_DeInit(&net);

    /* Set return code */
    ((func_args*)args)->return_code = (rc == 0) ? 0 : EXIT_FAILURE;

    return 0;
}
Exemple #9
0
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
{
    SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID;

    WOLFSSL_METHOD*  method  = 0;
    WOLFSSL_CTX*     ctx     = 0;
    WOLFSSL*         ssl     = 0;

    WOLFSSL*         sslResume = 0;
    WOLFSSL_SESSION* session = 0;
    char         resumeMsg[32] = "resuming wolfssl!";
    int          resumeSz    = (int)strlen(resumeMsg);

    char msg[32] = "hello wolfssl!";   /* GET may make bigger */
    char reply[80];
    int  input;
    int  msgSz = (int)strlen(msg);

    word16 port   = wolfSSLPort;
    char* host   = (char*)wolfSSLIP;
    const char* domain = "localhost";  /* can't default to www.wolfssl.com
                                          because can't tell if we're really
                                          going there to detect old chacha-poly
                                       */
    int    ch;
    int    version = CLIENT_INVALID_VERSION;
    int    usePsk   = 0;
    int    useAnon  = 0;
    int    sendGET  = 0;
    int    benchmark = 0;
    int    throughput = 0;
    int    doDTLS    = 0;
    int    matchName = 0;
    int    doPeerCheck = 1;
    int    nonBlocking = 0;
    int    resumeSession = 0;
    int    wc_shutdown   = 0;
    int    disableCRL    = 0;
    int    externalTest  = 0;
    int    ret;
    int    scr           = 0;    /* allow secure renegotiation */
    int    forceScr      = 0;    /* force client initiaed scr */
    int    trackMemory   = 0;
    int    useClientCert = 1;
    int    fewerPackets  = 0;
    int    atomicUser    = 0;
    int    pkCallbacks   = 0;
    int    overrideDateErrors = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = caCert;
    const char* ourCert    = cliCert;
    const char* ourKey     = cliKey;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif
#ifdef HAVE_MAX_FRAGMENT
    byte maxFragment = 0;
#endif
#ifdef HAVE_TRUNCATED_HMAC
    byte truncatedHMAC = 0;
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
    byte statusRequest = 0;
#endif


#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)eccCert;
    ourCert    = (char*)cliEccCert;
    ourKey     = (char*)cliEccKey;
#endif
    (void)resumeSz;
    (void)session;
    (void)sslResume;
    (void)trackMemory;
    (void)atomicUser;
    (void)pkCallbacks;
    (void)scr;
    (void)forceScr;
    (void)ourKey;
    (void)ourCert;
    (void)verifyCert;
    (void)useClientCert;
    (void)overrideDateErrors;
    (void)disableCRL;
    (void)minDhKeyBits;
    (void)alpnList;
    (void)alpn_opt;

    StackTrap();

#ifndef WOLFSSL_VXWORKS
    while ((ch = mygetopt(argc, argv,
            "?gdeDusmNrwRitfxXUPCVh:p:v:l:A:c:k:Z:b:zS:F:L:ToO:aB:W:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'g' :
                sendGET = 1;
                break;

            case 'd' :
                doPeerCheck = 0;
                break;

            case 'e' :
                ShowCiphers();
                exit(EXIT_SUCCESS);

            case 'D' :
                overrideDateErrors = 1;
                break;

            case 'C' :
                #ifdef HAVE_CRL
                    disableCRL = 1;
                #endif
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'm' :
                matchName = 1;
                break;

            case 'x' :
                useClientCert = 0;
                break;

            case 'X' :
                externalTest = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'U' :
            #ifdef ATOMIC_USER
                atomicUser = 1;
            #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'h' :
                host   = myoptarg;
                domain = myoptarg;
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'V' :
                ShowVersions();
                exit(EXIT_SUCCESS);

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'b' :
                benchmark = atoi(myoptarg);
                if (benchmark < 0 || benchmark > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'B' :
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'N' :
                nonBlocking = 1;
                break;

            case 'r' :
                resumeSession = 1;
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'R' :
                #ifdef HAVE_SECURE_RENEGOTIATION
                    scr = 1;
                #endif
                break;

            case 'i' :
                #ifdef HAVE_SECURE_RENEGOTIATION
                    scr      = 1;
                    forceScr = 1;
                #endif
                break;

            case 'z' :
                #ifndef WOLFSSL_LEANPSK
                    wolfSSL_GetObjectSize();
                #endif
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'F' :
                #ifdef HAVE_MAX_FRAGMENT
                    maxFragment = atoi(myoptarg);
                    if (maxFragment < WOLFSSL_MFL_2_9 ||
                                                maxFragment > WOLFSSL_MFL_2_13) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'T' :
                #ifdef HAVE_TRUNCATED_HMAC
                    truncatedHMAC = 1;
                #endif
                break;

            case 'W' :
                #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
                 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
                    statusRequest = atoi(myoptarg);
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    if (externalTest) {
        /* detect build cases that wouldn't allow test against wolfssl.com */
        int done = 0;
        (void)done;

        #ifdef NO_RSA
            done = 1;
        #endif

        /* www.globalsign.com does not respond to ipv6 ocsp requests */
        #if defined(TEST_IPV6) && defined(HAVE_OCSP)
            done = 1;
        #endif

        /* www.globalsign.com has limited supported cipher suites */
        #if defined(NO_AES) && defined(HAVE_OCSP)
            done = 1;
        #endif

        /* www.globalsign.com only supports static RSA or ECDHE with AES */
        /* We cannot expect users to have on static RSA so test for ECC only
         * as some users will most likely be on 32-bit systems where ECC
         * is not enabled by default */
        #if defined(HAVE_OCSP) && !defined(HAVE_ECC)
            done = 1;
        #endif

        #ifndef NO_PSK
            done = 1;
        #endif

        #ifdef NO_SHA
            done = 1;  /* external cert chain most likely has SHA */
        #endif

        #if !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA)
            if (!XSTRNCMP(domain, "www.google.com", 14) ||
                !XSTRNCMP(domain, "www.wolfssl.com", 15)) {
                done = 1;  /* google/wolfssl need ECDHE or static RSA */
            }
        #endif

        #if !defined(WOLFSSL_SHA384)
            if (!XSTRNCMP(domain, "www.wolfssl.com", 15)) {
                done = 1;  /* wolfssl need sha384 for cert chain verify */
            }
        #endif

        #if !defined(HAVE_AESGCM) && defined(NO_AES) && \
            !(defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
            done = 1;  /* need at least on of these for external tests */
        #endif

        if (done) {
            printf("external test can't be run in this mode");

            ((func_args*)args)->return_code = 0;
            exit(EXIT_SUCCESS);
        }
    }

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = wolfSSLv3_client_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = wolfTLSv1_client_method();
            break;

        case 2:
            method = wolfTLSv1_1_client_method();
            break;
    #endif /* NO_TLS */

#endif  /* NO_OLD_TLS */

#ifndef NO_TLS
        case 3:
            method = wolfTLSv1_2_client_method();
            break;
#endif

#ifdef WOLFSSL_DTLS
        #ifndef NO_OLD_TLS
        case -1:
            method = wolfDTLSv1_client_method();
            break;
        #endif

        case -2:
            method = wolfDTLSv1_2_client_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
            break;
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = wolfSSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList) {
        if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("client can't set cipher list 1");
    }

#ifdef WOLFSSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        wolfSSL_CTX_set_group_messages(ctx);

#ifndef NO_DH
    wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
#endif

    if (usePsk) {
#ifndef NO_PSK
        wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
                                                                  !=SSL_SUCCESS)
                err_sys("client can't set cipher list 2");
        }
#endif
        useClientCert = 0;
    }

    if (useAnon) {
#ifdef HAVE_ANON
        if (cipherList == NULL) {
            wolfSSL_CTX_allow_anon_cipher(ctx);
            if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("client can't set cipher list 4");
        }
#endif
        useClientCert = 0;
    }

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(WOLFSSL_SNIFFER)
    if (cipherList == NULL) {
        /* don't use EDH, can't sniff tmp keys */
        if (wolfSSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS) {
            err_sys("client can't set cipher list 3");
        }
    }
#endif

#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
                                                    | WOLFSSL_OCSP_URL_OVERRIDE);
        }
        else
            wolfSSL_CTX_EnableOCSP(ctx, 0);
    }
#endif

#ifdef USER_CA_CB
    wolfSSL_CTX_SetCACb(ctx, CaCb);
#endif

#ifdef VERIFY_CALLBACK
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (useClientCert){
        if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS)
            err_sys("can't load client cert file, check file and run from"
                    " wolfSSL home dir");

        if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load client private key file, check file and run "
                    "from wolfSSL home dir");
    }

    if (!usePsk && !useAnon) {
        if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#ifdef HAVE_ECC
        /* load ecc verify too, echoserver uses it by default w/ ecc */
        if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ecc ca file, Please run from wolfSSL home dir");
#endif /* HAVE_ECC */
    }
#endif /* !NO_FILESYSTEM && !NO_CERTS */
#if !defined(NO_CERTS)
    if (!usePsk && !useAnon && doPeerCheck == 0)
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    if (!usePsk && !useAnon && overrideDateErrors == 1)
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb);
#endif

#ifdef HAVE_CAVIUM
    wolfSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName))
                                                                 != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif
#ifdef HAVE_MAX_FRAGMENT
    if (maxFragment)
        if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS)
            err_sys("UseMaxFragment failed");
#endif
#ifdef HAVE_TRUNCATED_HMAC
    if (truncatedHMAC)
        if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
            err_sys("UseTruncatedHMAC failed");
#endif
#ifdef HAVE_SESSION_TICKET
    if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
        err_sys("UseSessionTicket failed");
#endif

    if (benchmark) {
        ((func_args*)args)->return_code =
            ClientBenchmarkConnections(ctx, host, port, doDTLS, benchmark, resumeSession);
        wolfSSL_CTX_free(ctx);
        exit(EXIT_SUCCESS);
    }

    if(throughput) {
        ((func_args*)args)->return_code =
            ClientBenchmarkThroughput(ctx, host, port, doDTLS, throughput);
        wolfSSL_CTX_free(ctx);
        exit(EXIT_SUCCESS);
    }

    #if defined(WOLFSSL_MDK_ARM)
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif

    ssl = wolfSSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL object");

    #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp256r1");
        }
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP384R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp384r1");
        }
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP521R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp521r1");
        }
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP224R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp224r1");
        }
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP192R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp192r1");
        }
        if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP160R1)
                != SSL_SUCCESS) {
            err_sys("unable to set curve secp160r1");
        }
    #endif

    #ifdef HAVE_SESSION_TICKET
    wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session");
    #endif

#ifdef HAVE_ALPN
    if (alpnList != NULL) {
       printf("ALPN accepted protocols list : %s\n", alpnList);
       wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
    }
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
    if (statusRequest) {
        switch (statusRequest) {
            case WOLFSSL_CSR_OCSP:
                if (wolfSSL_UseOCSPStapling(ssl, WOLFSSL_CSR_OCSP,
                                     WOLFSSL_CSR_OCSP_USE_NONCE) != SSL_SUCCESS)
                    err_sys("UseCertificateStatusRequest failed");

            break;
        }

        wolfSSL_CTX_EnableOCSP(ctx, 0);
    }
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
    if (statusRequest) {
        switch (statusRequest) {
            case WOLFSSL_CSR2_OCSP:
                if (wolfSSL_UseOCSPStaplingV2(ssl,
                    WOLFSSL_CSR2_OCSP, WOLFSSL_CSR2_OCSP_USE_NONCE)
                                                                 != SSL_SUCCESS)
                    err_sys("UseCertificateStatusRequest failed");
            break;
            case WOLFSSL_CSR2_OCSP_MULTI:
                if (wolfSSL_UseOCSPStaplingV2(ssl,
                    WOLFSSL_CSR2_OCSP_MULTI, 0)
                                                                 != SSL_SUCCESS)
                    err_sys("UseCertificateStatusRequest failed");
            break;

        }

        wolfSSL_CTX_EnableOCSP(ctx, 0);
    }
#endif

    tcp_connect(&sockfd, host, port, doDTLS, ssl);
    wolfSSL_set_fd(ssl, sockfd);
#ifdef HAVE_CRL
    if (disableCRL == 0) {
        if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != SSL_SUCCESS)
            err_sys("can't enable crl check");
        if (wolfSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
            err_sys("can't load crl, check crlfile and date validity");
        if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("can't set crl callback");
    }
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
    if (scr) {
        if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
            err_sys("can't enable secure renegotiation");
    }
#endif
#ifdef ATOMIC_USER
    if (atomicUser)
        SetupAtomicUser(ctx, ssl);
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif
    if (matchName && doPeerCheck)
        wolfSSL_check_domain_name(ssl, domain);
#ifndef WOLFSSL_CALLBACKS
    if (nonBlocking) {
        wolfSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&sockfd);
        NonBlockingSSL_Connect(ssl);
    }
    else if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
        /* see note at top of README */
        int  err = wolfSSL_get_error(ssl, 0);
        char buffer[WOLFSSL_MAX_ERROR_SZ];
        printf("err = %d, %s\n", err,
                                wolfSSL_ERR_error_string(err, buffer));
        err_sys("SSL_connect failed");
        /* if you're getting an error here  */
    }
#else
    timeout.tv_sec  = 2;
    timeout.tv_usec = 0;
    NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif
    showPeer(ssl);

#ifdef HAVE_ALPN
    if (alpnList != NULL) {
        int err;
        char *protocol_name = NULL;
        word16 protocol_nameSz = 0;

        err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
        if (err == SSL_SUCCESS)
            printf("Received ALPN protocol : %s (%d)\n",
                   protocol_name, protocol_nameSz);
        else if (err == SSL_ALPN_NOT_FOUND)
            printf("No ALPN response received (no match with server)\n");
        else
            printf("Getting ALPN protocol name failed\n");
    }
#endif

#ifdef HAVE_SECURE_RENEGOTIATION
    if (scr && forceScr) {
        if (nonBlocking) {
            printf("not doing secure renegotiation on example with"
                   " nonblocking yet");
        } else {
            if (wolfSSL_Rehandshake(ssl) != SSL_SUCCESS) {
                int  err = wolfSSL_get_error(ssl, 0);
                char buffer[WOLFSSL_MAX_ERROR_SZ];
                printf("err = %d, %s\n", err,
                                wolfSSL_ERR_error_string(err, buffer));
                err_sys("wolfSSL_Rehandshake failed");
            }
        }
    }
#endif /* HAVE_SECURE_RENEGOTIATION */

    if (sendGET) {
        printf("SSL connect ok, sending GET...\n");
        msgSz = 28;
        strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
        msg[msgSz] = '\0';

        resumeSz = msgSz;
        strncpy(resumeMsg, "GET /index.html HTTP/1.0\r\n\r\n", resumeSz);
        resumeMsg[resumeSz] = '\0';
    }
    if (wolfSSL_write(ssl, msg, msgSz) != msgSz)
        err_sys("SSL_write failed");

    input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = 0;
        printf("Server response: %s\n", reply);

        if (sendGET) {  /* get html */
            while (1) {
                input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
                if (input > 0) {
                    reply[input] = 0;
                    printf("%s\n", reply);
                }
                else
                    break;
            }
        }
    }
    else if (input < 0) {
        int readErr = wolfSSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("wolfSSL_read failed");
    }

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        session   = wolfSSL_get_session(ssl);
        sslResume = wolfSSL_new(ctx);
        if (sslResume == NULL)
            err_sys("unable to get SSL object");
    }
#endif

    if (doDTLS == 0) {           /* don't send alert after "break" command */
        ret = wolfSSL_shutdown(ssl);
        if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
            wolfSSL_shutdown(ssl);    /* bidirectional shutdown */
    }
#ifdef ATOMIC_USER
    if (atomicUser)
        FreeAtomicUser(ssl);
#endif
    wolfSSL_free(ssl);
    CloseSocket(sockfd);

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        if (doDTLS) {
#ifdef USE_WINDOWS_API
            Sleep(500);
#elif defined(WOLFSSL_TIRTOS)
            Task_sleep(1);
#else
            sleep(1);
#endif
        }
        tcp_connect(&sockfd, host, port, doDTLS, sslResume);
        wolfSSL_set_fd(sslResume, sockfd);
#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(sslResume, alpnList, (word32)XSTRLEN(alpnList),
                            alpn_opt);
        }
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
        if (scr) {
            if (wolfSSL_UseSecureRenegotiation(sslResume) != SSL_SUCCESS)
                err_sys("can't enable secure renegotiation");
        }
#endif
        wolfSSL_set_session(sslResume, session);
#ifdef HAVE_SESSION_TICKET
        wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
                                    (void*)"resumed session");
#endif

#ifndef WOLFSSL_CALLBACKS
        if (nonBlocking) {
            wolfSSL_set_using_nonblock(sslResume, 1);
            tcp_set_nonblocking(&sockfd);
            NonBlockingSSL_Connect(sslResume);
        }
        else if (wolfSSL_connect(sslResume) != SSL_SUCCESS)
            err_sys("SSL resume failed");
#else
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;
        NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif
        showPeer(sslResume);

        if (wolfSSL_session_reused(sslResume))
            printf("reused session id\n");
        else
            printf("didn't reuse session id!!!\n");

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            int err;
            char *protocol_name = NULL;
            word16 protocol_nameSz = 0;

            printf("Sending ALPN accepted list : %s\n", alpnList);
            err = wolfSSL_ALPN_GetProtocol(sslResume, &protocol_name,
                                           &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Received ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("Not received ALPN response (no match with server)\n");
            else
                printf("Getting ALPN protocol name failed\n");
        }
#endif
        if (wolfSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
            err_sys("SSL_write failed");

        if (nonBlocking) {
            /* give server a chance to bounce a message back to client */
            #ifdef USE_WINDOWS_API
                Sleep(500);
            #elif defined(WOLFSSL_TIRTOS)
                Task_sleep(1);
            #else
                sleep(1);
            #endif
        }

    input = wolfSSL_read(sslResume, reply, sizeof(reply)-1);

    if (input > 0) {
        reply[input] = 0;
        printf("Server resume response: %s\n", reply);

        if (sendGET) {  /* get html */
            while (1) {
                input = wolfSSL_read(sslResume, reply, sizeof(reply)-1);
                if (input > 0) {
                    reply[input] = 0;
                    printf("%s\n", reply);
                }
                else
                    break;
            }
        }
    } else if (input < 0) {
        int readErr = wolfSSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("wolfSSL_read failed");
    }

        /* try to send session break */
        wolfSSL_write(sslResume, msg, msgSz);

        ret = wolfSSL_shutdown(sslResume);
        if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
            wolfSSL_shutdown(sslResume);    /* bidirectional shutdown */

        wolfSSL_free(sslResume);
        CloseSocket(sockfd);
    }
#endif /* NO_SESSION_CACHE */

    wolfSSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_WOLFSSL_MEMORY */

#if !defined(WOLFSSL_TIRTOS)
    return 0;
#endif
}
Exemple #10
0
int
main(int argc, char *argv[])
{
	int port = 2344;
	const char *config = "sys161.conf";
	const char *kernel = NULL;
	int usetcp=0;
	char *argstr = NULL;
	int j, opt;
	size_t argsize=0;
	int debugwait=0;
	int pass_signals=0;
#ifdef USE_TRACE
	int profiling=0;
#endif
	int use_second_console=0;
	const char *second_console = NULL;
	unsigned ncpus;

	/* This must come absolutely first so msg() can be used. */
	console_earlyinit();
	
	if (sizeof(u_int32_t)!=4) {
		/*
		 * Just in case.
		 */
		msg("sys161 requires sizeof(u_int32_t)==4");
		die();
	}

	while ((opt = mygetopt(argc, argv, "c:f:p:Pst:wk:"))!=-1) {
		switch (opt) {
		    case 'c': config = myoptarg; break;
		    case 'f':
#ifdef USE_TRACE
			set_tracefile(myoptarg);
#endif
			break;
		    case 'p': port = atoi(myoptarg); usetcp=1; break;
		    case 'P':
#ifdef USE_TRACE
			profiling = 1;
#endif
			break;
		    case 's': pass_signals = 1; break;
		    case 't': 
#ifdef USE_TRACE
			set_traceflags(myoptarg); 
#endif
			break;
		    case 'w': debugwait = 1; break;
		    case 'k':
		    use_second_console = 1;
		    second_console = myoptarg;
		    break;
		    default: usage(); break;
		}
	}
	if (myoptind==argc) {
		usage();
	}
	kernel = argv[myoptind++];
	
	for (j=myoptind; j<argc; j++) {
		argsize += strlen(argv[j])+1;
	}
	argstr = malloc(argsize+1);
	if (!argstr) {
		msg("malloc failed");
		die();
	}
	*argstr = 0;
	for (j=myoptind; j<argc; j++) {
		strcat(argstr, argv[j]);
		if (j<argc-1) strcat(argstr, " ");
	}

	/* This must come before bus_config in case a network card needs it */
	mkdir(".sockets", 0700);
	
	console_init(pass_signals, use_second_console, second_console);
	clock_init();
	ncpus = bus_config(config);

	initstats(ncpus);
	cpu_init(ncpus);

	if (usetcp) {
		gdb_inet_init(port);
	}
	else {
		unlink(".sockets/gdb");
		gdb_unix_init(".sockets/gdb");
	}

	unlink(".sockets/meter");
	meter_init(".sockets/meter");

	load_kernel(kernel, argstr);

	msg("System/161 %s, compiled %s %s", VERSION, __DATE__, __TIME__);
#ifdef USE_TRACE
	print_traceflags();
	if (profiling) {
		prof_setup();
	}
#endif

	if (debugwait) {
		stoploop();
	}
	
	run();

#ifdef USE_TRACE
	if (profiling) {
		prof_write();
	}
#endif

	bus_cleanup();
	console_cleanup();
	clock_cleanup();
	
	return 0;
}
/* Main entry point for the program.
 *
 * argc  The count of command line arguments.
 * argv  The command line arguments.
 * returns 0 on success and 1 otherwise.
 */
int main(int argc, char* argv[])
{
    socklen_t    socketfd = -1;
    int          ch;
    WOLFSSL_CTX* ctx = NULL;
    SSLConn_CTX* sslConnCtx;
    word16       port = wolfSSLPort;
    int          resumeSession = 0;
    char*        cipherList = NULL;
    char*        ourCert       = CLI_CERT;
    char*        ourKey        = CLI_KEY;
    char*        verifyCert    = CA_CERT;
    int          version       = SERVER_DEFAULT_VERSION;
    int          numConns      = SSL_NUM_CONN;
    int          numBytesRead  = NUM_READ_BYTES;
    int          numBytesWrite = NUM_WRITE_BYTES;
    int          maxBytes      = MAX_BYTES;
    int          maxConns      = MAX_CONNECTIONS;
    int          i;

    /* Parse the command line arguments. */
    while ((ch = mygetopt(argc, argv, OPTIONS)) != -1) {
        switch (ch) {
            /* Help with command line options. */
            case '?':
                Usage();
                exit(EXIT_SUCCESS);

            /* Port number to connect to. */
            case 'p':
                port = (word16)atoi(myoptarg);
                break;

            /* Version of SSL/TLS to use. */
            case 'v':
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* List of cipher suites to use. */
            case 'l':
                cipherList = myoptarg;
                break;

            /* File name of client certificate for client authentication. */
            case 'c':
                ourCert = myoptarg;
                break;

            /* File name of client private key for client authentication. */
            case 'k':
                ourKey = myoptarg;
                break;

            /* File name of server certificate/CA for peer verification. */
            case 'A':
                verifyCert = myoptarg;
                break;

            /* Resume sessions. */
            case 'r':
                resumeSession = 1;
                break;

            /* Number of connections to make. */
            case 'n':
                maxConns = atoi(myoptarg);
                if (maxConns < 0 || maxConns > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                maxBytes = 0;
                break;

            /* Number of conncurrent connections to use. */
            case 'N':
                numConns  = atoi(myoptarg);
                if (numConns < 0 || numConns > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Number of bytes to read each call. */
            case 'R':
                numBytesRead = atoi(myoptarg);
                if (numBytesRead <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Number of bytes to write each call. */
            case 'W':
                numBytesWrite = atoi(myoptarg);
                if (numBytesWrite <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            /* Maximum number of read and write bytes (separate counts). */
            case 'B':
                maxBytes = atoi(myoptarg);
                if (maxBytes <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                maxConns = 0;
                break;

            /* Unrecognized command line argument. */
            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }


#ifdef DEBUG_WOLFSSL
    wolfSSL_Debugging_ON();
#endif

    /* Initialize wolfSSL */
    wolfSSL_Init();

    /* Initialize wolfSSL and create a context object. */
    if (WolfSSLCtx_Init(version, ourCert, ourKey, verifyCert, cipherList, &ctx)
            == EXIT_FAILURE)
        exit(EXIT_FAILURE);

    /* Create SSL/TLS connection data object. */
    sslConnCtx = SSLConn_New(numConns, numBytesRead, numBytesWrite,
                             maxConns, maxBytes, resumeSession);
    if (sslConnCtx == NULL)
        exit(EXIT_FAILURE);

    /* Keep handling connections until all done. */
    for (i = 0; !SSLConn_Done(sslConnCtx); i = (i + 1) % numConns) {
        SSLConn* sslConn = &sslConnCtx->sslConn[i];

        /* Perform close if in CLOSE state. */
        if (sslConn->state == CLOSE) {
            if (sslConnCtx->numConnections == 0) {
                WOLFSSL_CIPHER* cipher;
                cipher = wolfSSL_get_current_cipher(sslConn->ssl);
                printf("SSL cipher suite is %s\n",
                       wolfSSL_CIPHER_get_name(cipher));
            }
            SSLConn_Close(sslConnCtx, sslConn);
        }

        /* Create TCP connection and connect if in INIT state. */
        if ((sslConn->state == INIT) &&
            ((sslConnCtx->maxConnections <= 0) ||
             (sslConnCtx->numCreated < sslConnCtx->maxConnections))) {
            if (CreateSocketConnect(port, &socketfd) == EXIT_FAILURE) {
                printf("ERROR: failed to connect to server\n");
                exit(EXIT_FAILURE);
            }

            SSLConn_Connect(sslConnCtx, ctx, socketfd, sslConn);
        }

#ifdef WOLFSSL_ASYNC_CRYPT
        if (sslConn->err == 4) {
            int ret;
            double start;

            start = current_time(1);
            ret = wolfSSL_AsyncPoll(sslConn->ssl, WOLF_POLL_FLAG_CHECK_HW);
            sslConnCtx->asyncTime += current_time(0) - start;
            if (ret < 0) {
                printf("ERROR: failed in async polling\n");
                break;
            }
            if (ret == 0)
                continue;
        }
        sslConn->err = 0;
#endif

        /* Handle other SSL states. */
        if (sslConnCtx->totalTime == 0)
            sslConnCtx->totalTime = current_time(1);
        if (SSLConn_ReadWrite(sslConnCtx, sslConn) == EXIT_FAILURE) {
            if (sslConnCtx->maxConnections > 0)
                sslConn->state = CLOSE;
        }
    }

    sslConnCtx->totalTime = current_time(0) - sslConnCtx->totalTime;

    SSLConn_PrintStats(sslConnCtx);
    SSLConn_Free(sslConnCtx);

    WolfSSLCtx_Final(ctx);

    wolfSSL_Cleanup();

    exit(EXIT_SUCCESS);
}
Exemple #12
0
int mygetopt(int argc, char * argv[], const char *opts)
{
    static int charind=0;
    const char *s;
    char mode, colon_mode;
    int off = 0, opt = -1;

    if (my_optreset)
    {
        my_optind = 1;
        my_opterr = 1;
        my_optopt = 0;
        my_optarg = 0;
        my_optreset = 0;
    }
    if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
    else {
        if((colon_mode = *opts) == ':') off ++;
        if(((mode = opts[off]) == '+') || (mode == '-')) {
            off++;
            if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
                off ++;
        }
    }
    my_optarg = 0;
    if(charind) {
        my_optopt = argv[my_optind][charind];
        for(s=opts+off; *s; s++) if(my_optopt == *s) {
            charind++;
            if((*(++s) == ':') || ((my_optopt == 'W') && (*s == ';'))) {
                if(argv[my_optind][charind]) {
                    my_optarg = &(argv[my_optind++][charind]);
                    charind = 0;
                } else if(*(++s) != ':') {
                    charind = 0;
                    if(++my_optind >= argc) {
                        if(my_opterr) fprintf(stderr,
                                              "%s: option requires an argument -- %c\n",
                                              argv[0], my_optopt);
                        opt = (colon_mode == ':') ? ':' : '?';
                        goto mygetopt_ok;
                    }
                    my_optarg = argv[my_optind++];
                }
            }
            opt = my_optopt;
            goto mygetopt_ok;
        }
        if(my_opterr) fprintf(stderr,
                              "%s: illegal option -- %c\n",
                              argv[0], my_optopt);
        opt = '?';
        if(argv[my_optind][++charind] == '\0') {
            my_optind++;
            charind = 0;
        }
      mygetopt_ok:
        if(charind && ! argv[my_optind][charind]) {
            my_optind++;
            charind = 0;
        }
    } else if((my_optind >= argc) ||
              ((argv[my_optind][0] == '-') &&
               (argv[my_optind][1] == '-') &&
               (argv[my_optind][2] == '\0'))) {
        my_optind++;
        opt = -1;
    } else if((argv[my_optind][0] != '-') ||
              (argv[my_optind][1] == '\0')) {
        char *tmp;
        int i, j, k;

        if(mode == '+') opt = -1;
        else if(mode == '-') {
            my_optarg = argv[my_optind++];
            charind = 0;
            opt = 1;
        } else {
            for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
                                               (argv[i][1] != '\0')) {
                my_optind=i;
                opt=mygetopt(argc, argv, opts);
                while(i > j) {
                    tmp=argv[--i];
                    for(k=i; k+1<my_optind; k++) argv[k]=argv[k+1];
                    argv[--my_optind]=tmp;
                }
                break;
            }
            if(i == argc) opt = -1;
        }
    } else {
        charind++;
        opt = mygetopt(argc, argv, opts);
    }
    if (my_optind > argc) my_optind = argc;
    return opt;
}
Exemple #13
0
int _mygetopt_internal(int argc, char * argv[], const char *shortopts,
                       const struct option *longopts, int *longind,
                       int long_only)
{
    char mode, colon_mode = *shortopts;
    int shortoff = 0, opt = -1;

    if (my_optreset)
    {
        my_optind = 1;
        my_opterr = 1;
        my_optopt = 0;
        my_optarg = 0;
        my_optreset = 0;
    }
    if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
    else {
        if((colon_mode = *shortopts) == ':') shortoff ++;
        if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
            shortoff++;
            if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
                shortoff ++;
        }
    }
    my_optarg = 0;
    if((my_optind >= argc) ||
       ((argv[my_optind][0] == '-') &&
        (argv[my_optind][1] == '-') &&
        (argv[my_optind][2] == '\0'))) {
        my_optind++;
        opt = -1;
    } else if((argv[my_optind][0] != '-') ||
              (argv[my_optind][1] == '\0')) {
        char *tmp;
        int i, j, k;

        opt = -1;
        if(mode == '+') return -1;
        else if(mode == '-') {
            my_optarg = argv[my_optind++];
            return 1;
        }
        for(i=j=my_optind; i<argc; i++) if((argv[i][0] == '-') &&
                                           (argv[i][1] != '\0')) {
            my_optind=i;
            opt=_mygetopt_internal(argc, argv, shortopts,
                                   longopts, longind,
                                   long_only);
            while(i > j) {
                tmp=argv[--i];
                for(k=i; k+1<my_optind; k++)
                    argv[k]=argv[k+1];
                argv[--my_optind]=tmp;
            }
            break;
        }
    } else if((!long_only) && (argv[my_optind][1] != '-'))
        opt = mygetopt(argc, argv, shortopts);
    else {
        int charind, offset;
        int found = 0, ind, hits = 0;

        if(((my_optopt = argv[my_optind][1]) != '-') && ! argv[my_optind][2]) {
            int c;
      
            ind = shortoff;
            while (1)
            {
                c = shortopts[ind++];
                if (! c) break;
                if(((shortopts[ind] == ':') ||
                    ((c == 'W') && (shortopts[ind] == ';'))) &&
                   (shortopts[++ind] == ':'))
                    ind ++;
                if(my_optopt == c) return mygetopt(argc, argv, shortopts);
            }
        }
        offset = 2 - (argv[my_optind][1] != '-');
        for(charind = offset;
            (argv[my_optind][charind] != '\0') &&
                (argv[my_optind][charind] != '=');
            charind++)
        {
        }
        for(ind = 0; longopts[ind].name && !hits; ind++)
            if((strlen(longopts[ind].name) == (size_t) (charind - offset)) &&
               (strncmp(longopts[ind].name,
                        argv[my_optind] + offset, charind - offset) == 0))
                found = ind, hits++;
        if(!hits) for(ind = 0; longopts[ind].name; ind++)
            if(strncmp(longopts[ind].name,
                       argv[my_optind] + offset, charind - offset) == 0)
                found = ind, hits++;
        if(hits == 1) {
            opt = 0;

            if(argv[my_optind][charind] == '=') {
                if(longopts[found].has_arg == 0) {
                    opt = '?';
                    if(my_opterr) fprintf(stderr,
                                          "%s: option `--%s' doesn't allow an argument\n",
                                          argv[0], longopts[found].name);
                } else {
                    my_optarg = argv[my_optind] + ++charind;
                    charind = 0;
                }
            } else if(longopts[found].has_arg == 1) {
                if(++my_optind >= argc) {
                    opt = (colon_mode == ':') ? ':' : '?';
                    if(my_opterr) fprintf(stderr,
                                          "%s: option `--%s' requires an argument\n",
                                          argv[0], longopts[found].name);
                } else my_optarg = argv[my_optind];
            }
            if(!opt) {
                if (longind) *longind = found;
                if(!longopts[found].flag) opt = longopts[found].val;
                else *(longopts[found].flag) = longopts[found].val;
            }
            my_optind++;
        } else if(!hits) {
            if(offset == 1) opt = mygetopt(argc, argv, shortopts);
            else {
                opt = '?';
                if(my_opterr) fprintf(stderr,
                                      "%s: unrecognized option `%s'\n",
                                      argv[0], argv[my_optind++]);
            }
        } else {
            opt = '?';
            if(my_opterr) fprintf(stderr,
                                  "%s: option `%s' is ambiguous\n",
                                  argv[0], argv[my_optind++]);
        }
    }
    if (my_optind > argc) my_optind = argc;
    return opt;
}
Exemple #14
0
int main (int argc,char* argv[])
{
  int c;
  int digit_optind = 0;

  while (1)
    {
      int this_option_optind = myoptind ? myoptind : 1;

      c = mygetopt (argc, argv, "abc:d:0123456789");
      if (c == EOF)
	break;

      switch (c)
	{
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	  if (digit_optind != 0 && digit_optind != this_option_optind)
	    printf ("digits occur in two different argv-elements.\n");
	  digit_optind = this_option_optind;
	  printf ("option %c\n", c);
	  break;

	case 'a':
	  printf ("option a\n");
	  break;

	case 'b':
	  printf ("option b\n");
	  break;

	case 'c':
	  printf ("option c with value `%s'\n", myoptarg);
	  break;

	case BAD_OPTION:
	  break;

	default:
	  printf ("?? getopt returned character code 0%o ??\n", c);
	}
    }

  if (myoptind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (myoptind < argc)
	printf ("%s ", argv[myoptind++]);
      printf ("\n");
    }

  exit (0);
}
Exemple #15
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = yasslPort;
    int    usePsk = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    serverReadyFile = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    while ((ch = mygetopt(argc, argv, "?dbstnNufraPp:v:l:A:c:k:S:oO:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'r' :
                serverReadyFile = 1;
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS 
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk && !useAnon) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0 && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                    | CYASSL_OCSP_URL_OVERRIDE);
        }
        else
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
    }
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif

    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS,
               serverReadyFile);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0 || useAnon == 1 || cipherList != NULL) {
        #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_DH)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }

#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[CYASSL_MAX_ERROR_SZ];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    #if defined(CYASSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
    #elif defined (CYASSL_TIRTOS)
        Task_yield();
    #endif

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
Exemple #16
0
THREAD_RETURN CYASSL_THREAD client_test(void* args)
{
    SOCKET_T sockfd = 0;

    CYASSL_METHOD*  method  = 0;
    CYASSL_CTX*     ctx     = 0;
    CYASSL*         ssl     = 0;
    
    CYASSL*         sslResume = 0;
    CYASSL_SESSION* session = 0;
    char         resumeMsg[] = "resuming cyassl!";
    int          resumeSz    = sizeof(resumeMsg);

    char msg[32] = "hello cyassl!";   /* GET may make bigger */
    char reply[80];
    int  input;
    int  msgSz = (int)strlen(msg);

    int   port   = yasslPort;
    char* host   = (char*)yasslIP;
    char* domain = (char*)"www.yassl.com";

    int    ch;
    int    version = CLIENT_INVALID_VERSION;
    int    usePsk   = 0;
    int    sendGET  = 0;
    int    benchmark = 0;
    int    doDTLS    = 0;
    int    matchName = 0;
    int    doPeerCheck = 1;
    int    nonBlocking = 0;
    int    resumeSession = 0;
    int    trackMemory   = 0;
    int    useClientCert = 1;
    int    fewerPackets  = 0;
    int    atomicUser    = 0;
    int    pkCallbacks   = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)caCert;
    char*  ourCert    = (char*)cliCert;
    char*  ourKey     = (char*)cliKey;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif
#ifdef HAVE_MAX_FRAGMENT
    byte maxFragment = 0;
#endif
#ifdef HAVE_TRUNCATED_HMAC
    byte  truncatedHMAC = 0;
#endif


#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)eccCert;
    ourCert    = (char*)cliEccCert;
    ourKey     = (char*)cliEccKey;
#endif
    (void)resumeSz;
    (void)session;
    (void)sslResume;
    (void)trackMemory;
    (void)atomicUser;
    (void)pkCallbacks;

    StackTrap();

    while ((ch = mygetopt(argc, argv,
                          "?gdusmNrtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'g' :
                sendGET = 1;
                break;

            case 'd' :
                doPeerCheck = 0;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'm' :
                matchName = 1;
                break;

            case 'x' :
                useClientCert = 0;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'U' :
            #ifdef ATOMIC_USER
                atomicUser = 1;
            #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS 
                pkCallbacks = 1;
            #endif
                break;

            case 'h' :
                host   = myoptarg;
                domain = myoptarg;
                break;

            case 'p' :
                port = atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'b' :
                benchmark = atoi(myoptarg);
                if (benchmark < 0 || benchmark > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'N' :
                nonBlocking = 1;
                break;

            case 'r' :
                resumeSession = 1;
                break;

            case 'z' :
                #ifndef CYASSL_LEANPSK
                    CyaSSL_GetObjectSize();
                #endif
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_MAX_FRAGMENT
                    maxFragment = atoi(myoptarg);
                    if (maxFragment < CYASSL_MFL_2_9 ||
                                                maxFragment > CYASSL_MFL_2_13) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'T' :
                #ifdef HAVE_TRUNCATED_HMAC
                    truncatedHMAC = 1;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = CyaSSLv3_client_method();
            break;
                
                
    #ifndef NO_TLS
        case 1:
            method = CyaTLSv1_client_method();
            break;

        case 2:
            method = CyaTLSv1_1_client_method();
            break;
    #endif /* NO_TLS */
                
#endif  /* NO_OLD_TLS */
                
#ifndef NO_TLS
        case 3:
            method = CyaTLSv1_2_client_method();
            break;
#endif

#ifdef CYASSL_DTLS
        case -1:
            method = CyaDTLSv1_client_method();
            break;

        case -2:
            method = CyaDTLSv1_2_client_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
            break;
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = CyaSSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (CyaSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("client can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

    if (usePsk) {
#ifndef NO_PSK
        CyaSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (CyaSSL_CTX_set_cipher_list(ctx,defaultCipherList) !=SSL_SUCCESS)
                err_sys("client can't set cipher list 2");
        }
#endif
        useClientCert = 0;
    }

#ifdef OPENSSL_EXTRA
    CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    if (cipherList == NULL) {
        /* don't use EDH, can't sniff tmp keys */
        if (CyaSSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS) {
            err_sys("client can't set cipher list 3");
        }
    }
#endif

#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                    | CYASSL_OCSP_URL_OVERRIDE);
        }
        else
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
    }
#endif

#ifdef USER_CA_CB
    CyaSSL_CTX_SetCACb(ctx, CaCb);
#endif

#ifdef VERIFY_CALLBACK
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (useClientCert){
        if (CyaSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS)
            err_sys("can't load client cert file, check file and run from"
                    " CyaSSL home dir");

        if (CyaSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load client private key file, check file and run "
                    "from CyaSSL home dir");
    }

    if (!usePsk) {
        if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
                err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif
#if !defined(NO_CERTS)
    if (!usePsk && doPeerCheck == 0)
        CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
#endif

#ifdef HAVE_CAVIUM
    CyaSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName))
                                                                 != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif
#ifdef HAVE_MAX_FRAGMENT
    if (maxFragment)
        if (CyaSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS)
            err_sys("UseMaxFragment failed");
#endif
#ifdef HAVE_TRUNCATED_HMAC
    if (truncatedHMAC)
        if (CyaSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
            err_sys("UseTruncatedHMAC failed");
#endif

    if (benchmark) {
        /* time passed in number of connects give average */
        int times = benchmark;
        int i = 0;

        double start = current_time(), avg;

        for (i = 0; i < times; i++) {
            tcp_connect(&sockfd, host, port, doDTLS);

            ssl = CyaSSL_new(ctx);
            CyaSSL_set_fd(ssl, sockfd);
            if (CyaSSL_connect(ssl) != SSL_SUCCESS)
                err_sys("SSL_connect failed");

            CyaSSL_shutdown(ssl);
            CyaSSL_free(ssl);
            CloseSocket(sockfd);
        }
        avg = current_time() - start;
        avg /= times;
        avg *= 1000;   /* milliseconds */
        printf("CyaSSL_connect avg took: %8.3f milliseconds\n", avg);

        CyaSSL_CTX_free(ctx);
        ((func_args*)args)->return_code = 0;

        exit(EXIT_SUCCESS);
    }
    
    #if defined(CYASSL_MDK_ARM)
    CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif
    
    ssl = CyaSSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL object");
    if (doDTLS) {
        SOCKADDR_IN_T addr;
        build_addr(&addr, host, port, 1);
        CyaSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
        tcp_socket(&sockfd, 1);
    }
    else {
        tcp_connect(&sockfd, host, port, 0);
    }
    CyaSSL_set_fd(ssl, sockfd);
#ifdef HAVE_CRL
    if (CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL) != SSL_SUCCESS)
        err_sys("can't enable crl check");
    if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
        err_sys("can't load crl, check crlfile and date validity");
    if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
        err_sys("can't set crl callback");
#endif
#ifdef ATOMIC_USER
    if (atomicUser)
        SetupAtomicUser(ctx, ssl);
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif
    if (matchName && doPeerCheck)
        CyaSSL_check_domain_name(ssl, domain);
#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&sockfd);
        NonBlockingSSL_Connect(ssl);
    }
    else if (CyaSSL_connect(ssl) != SSL_SUCCESS) {
        /* see note at top of README */
        int  err = CyaSSL_get_error(ssl, 0);
        char buffer[CYASSL_MAX_ERROR_SZ];
        printf("err = %d, %s\n", err,
                                CyaSSL_ERR_error_string(err, buffer));
        err_sys("SSL_connect failed");
        /* if you're getting an error here  */
    }
#else
    timeout.tv_sec  = 2;
    timeout.tv_usec = 0;
    NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif
    showPeer(ssl);

    if (sendGET) {
        printf("SSL connect ok, sending GET...\n");
        msgSz = 28;
        strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
        msg[msgSz] = '\0';
    }
    if (CyaSSL_write(ssl, msg, msgSz) != msgSz)
        err_sys("SSL_write failed");

    input = CyaSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = 0;
        printf("Server response: %s\n", reply);

        if (sendGET) {  /* get html */
            while (1) {
                input = CyaSSL_read(ssl, reply, sizeof(reply)-1);
                if (input > 0) {
                    reply[input] = 0;
                    printf("%s\n", reply);
                }
                else
                    break;
            }
        }
    }
    else if (input < 0) {
        int readErr = CyaSSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("CyaSSL_read failed");
    }

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        if (doDTLS) {
            strncpy(msg, "break", 6);
            msgSz = (int)strlen(msg);
            /* try to send session close */
            CyaSSL_write(ssl, msg, msgSz);
        }
        session   = CyaSSL_get_session(ssl);
        sslResume = CyaSSL_new(ctx);
    }
#endif

    if (doDTLS == 0)            /* don't send alert after "break" command */
        CyaSSL_shutdown(ssl);  /* echoserver will interpret as new conn */
#ifdef ATOMIC_USER
    if (atomicUser)
        FreeAtomicUser(ssl);
#endif
    CyaSSL_free(ssl);
    CloseSocket(sockfd);

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        if (doDTLS) {
            SOCKADDR_IN_T addr;
            #ifdef USE_WINDOWS_API 
                Sleep(500);
            #else
                sleep(1);
            #endif
            build_addr(&addr, host, port, 1);
            CyaSSL_dtls_set_peer(sslResume, &addr, sizeof(addr));
            tcp_socket(&sockfd, 1);
        }
        else {
            tcp_connect(&sockfd, host, port, 0);
        }
        CyaSSL_set_fd(sslResume, sockfd);
        CyaSSL_set_session(sslResume, session);
       
        showPeer(sslResume);
#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(sslResume, 1);
            tcp_set_nonblocking(&sockfd);
            NonBlockingSSL_Connect(sslResume);
        }
        else if (CyaSSL_connect(sslResume) != SSL_SUCCESS)
            err_sys("SSL resume failed");
#else
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;
        NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif

        if (CyaSSL_session_reused(sslResume))
            printf("reused session id\n");
        else
            printf("didn't reuse session id!!!\n");

        if (CyaSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
            err_sys("SSL_write failed");

        if (nonBlocking) {
            /* give server a chance to bounce a message back to client */
            #ifdef USE_WINDOWS_API
                Sleep(500);
            #else
                sleep(1);
            #endif
        }

        input = CyaSSL_read(sslResume, reply, sizeof(reply)-1);
        if (input > 0) {
            reply[input] = 0;
            printf("Server resume response: %s\n", reply);
        }

        /* try to send session break */
        CyaSSL_write(sslResume, msg, msgSz); 

        CyaSSL_shutdown(sslResume);
        CyaSSL_free(sslResume);
        CloseSocket(sockfd);
    }
#endif /* NO_SESSION_CACHE */

    CyaSSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_CYASSL_MEMORY */

    return 0;
}
Exemple #17
0
THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
{
    SOCKET_T sockfd = 0;

    WOLFSSL_METHOD*  method  = 0;
    WOLFSSL_CTX*     ctx     = 0;
    WOLFSSL*         ssl     = 0;
    
    WOLFSSL*         sslResume = 0;
    WOLFSSL_SESSION* session = 0;
    char         resumeMsg[] = "resuming wolfssl!";
    int          resumeSz    = sizeof(resumeMsg);

    char msg[32] = "hello wolfssl!";   /* GET may make bigger */
    char reply[80];
    int  input;
    int  msgSz = (int)strlen(msg);

    word16 port   = wolfSSLPort;
    char* host   = (char*)wolfSSLIP;
    const char* domain = "www.wolfssl.com";

    int    ch;
    int    version = CLIENT_INVALID_VERSION;
    int    usePsk   = 0;
    int    useAnon  = 0;
    int    sendGET  = 0;
    int    benchmark = 0;
    int    doDTLS    = 0;
    int    matchName = 0;
    int    doPeerCheck = 1;
    int    nonBlocking = 0;
    int    resumeSession = 0;
    int    wc_shutdown   = 0;
    int    disableCRL    = 0;
    int    externalTest  = 0;
    int    ret;
    int    scr           = 0;    /* allow secure renegotiation */
    int    forceScr      = 0;    /* force client initiaed scr */
    int    trackMemory   = 0;
    int    useClientCert = 1;
    int    fewerPackets  = 0;
    int    atomicUser    = 0;
    int    pkCallbacks   = 0;
    int    overrideDateErrors = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    char*  cipherList = NULL;
    const char* verifyCert = caCert;
    const char* ourCert    = cliCert;
    const char* ourKey     = cliKey;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif
#ifdef HAVE_MAX_FRAGMENT
    byte maxFragment = 0;
#endif
#ifdef HAVE_TRUNCATED_HMAC
    byte  truncatedHMAC = 0;
#endif


#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    int     argc = ((func_args*)args)->argc;
    char**  argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)eccCert;
    ourCert    = (char*)cliEccCert;
    ourKey     = (char*)cliEccKey;
#endif
    (void)resumeSz;
    (void)session;
    (void)sslResume;
    (void)trackMemory;
    (void)atomicUser;
    (void)pkCallbacks;
    (void)scr;
    (void)forceScr;
    (void)ourKey;
    (void)ourCert;
    (void)verifyCert;
    (void)useClientCert;
    (void)overrideDateErrors;
    (void)disableCRL;
    (void)minDhKeyBits;

    StackTrap();

    while ((ch = mygetopt(argc, argv,
                          "?gdDusmNrwRitfxXUPCh:p:v:l:A:c:k:Z:b:zS:L:ToO:a"))
                                                                        != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'g' :
                sendGET = 1;
                break;

            case 'd' :
                doPeerCheck = 0;
                break;

            case 'D' :
                overrideDateErrors = 1;
                break;

            case 'C' :
                #ifdef HAVE_CRL
                    disableCRL = 1;
                #endif
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'm' :
                matchName = 1;
                break;

            case 'x' :
                useClientCert = 0;
                break;

            case 'X' :
                externalTest = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'U' :
            #ifdef ATOMIC_USER
                atomicUser = 1;
            #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS 
                pkCallbacks = 1;
            #endif
                break;

            case 'h' :
                host   = myoptarg;
                domain = myoptarg;
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'b' :
                benchmark = atoi(myoptarg);
                if (benchmark < 0 || benchmark > 1000000) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'N' :
                nonBlocking = 1;
                break;

            case 'r' :
                resumeSession = 1;
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'R' :
                #ifdef HAVE_SECURE_RENEGOTIATION
                    scr = 1;
                #endif
                break;

            case 'i' :
                #ifdef HAVE_SECURE_RENEGOTIATION
                    scr      = 1;
                    forceScr = 1;
                #endif
                break;

            case 'z' :
                #ifndef WOLFSSL_LEANPSK
                    wolfSSL_GetObjectSize();
                #endif
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_MAX_FRAGMENT
                    maxFragment = atoi(myoptarg);
                    if (maxFragment < WOLFSSL_MFL_2_9 ||
                                                maxFragment > WOLFSSL_MFL_2_13) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'T' :
                #ifdef HAVE_TRUNCATED_HMAC
                    truncatedHMAC = 1;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    if (externalTest) {
        /* detect build cases that wouldn't allow test against wolfssl.com */
        int done = 0;
        (void)done;

        #ifdef NO_RSA
            done = 1;
        #endif

        #ifndef NO_PSK
            done = 1;
        #endif

        #ifdef NO_SHA
            done = 1;  /* external cert chain most likely has SHA */
        #endif

        if (done) {
            printf("external test can't be run in this mode");

            ((func_args*)args)->return_code = 0;
            exit(EXIT_SUCCESS);
        }
    }

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = wolfSSLv3_client_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = wolfTLSv1_client_method();
            break;

        case 2:
            method = wolfTLSv1_1_client_method();
            break;
    #endif /* NO_TLS */

#endif  /* NO_OLD_TLS */

#ifndef NO_TLS
        case 3:
            method = wolfTLSv1_2_client_method();
            break;
#endif

#ifdef WOLFSSL_DTLS
        #ifndef NO_OLD_TLS
        case -1:
            method = wolfDTLSv1_client_method();
            break;
        #endif

        case -2:
            method = wolfDTLSv1_2_client_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
            break;
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = wolfSSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("client can't set cipher list 1");

#ifdef WOLFSSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        wolfSSL_CTX_set_group_messages(ctx);

#ifndef NO_DH
    wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits);
#endif

    if (usePsk) {
#ifndef NO_PSK
        wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
                                                                  !=SSL_SUCCESS)
                err_sys("client can't set cipher list 2");
        }
#endif
        useClientCert = 0;
    }

    if (useAnon) {
#ifdef HAVE_ANON
        if (cipherList == NULL) {
            wolfSSL_CTX_allow_anon_cipher(ctx);
            if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("client can't set cipher list 4");
        }
#endif
        useClientCert = 0;
    }

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(WOLFSSL_SNIFFER)
    if (cipherList == NULL) {
        /* don't use EDH, can't sniff tmp keys */
        if (wolfSSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS) {
            err_sys("client can't set cipher list 3");
        }
    }
#endif

#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
                                                    | WOLFSSL_OCSP_URL_OVERRIDE);
        }
        else
            wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE);
    }
#endif

#ifdef USER_CA_CB
    wolfSSL_CTX_SetCACb(ctx, CaCb);
#endif

#ifdef VERIFY_CALLBACK
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify);
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (useClientCert){
        if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS)
            err_sys("can't load client cert file, check file and run from"
                    " wolfSSL home dir");

        if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load client private key file, check file and run "
                    "from wolfSSL home dir");
    }

    if (!usePsk && !useAnon) {
        if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#ifdef HAVE_ECC
        /* load ecc verify too, echoserver uses it by default w/ ecc */
        if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS)
            err_sys("can't load ecc ca file, Please run from wolfSSL home dir");
#endif /* HAVE_ECC */
    }
#endif /* !NO_FILESYSTEM && !NO_CERTS */
#if !defined(NO_CERTS)
    if (!usePsk && !useAnon && doPeerCheck == 0)
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    if (!usePsk && !useAnon && overrideDateErrors == 1)
        wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb);
#endif

#ifdef HAVE_CAVIUM
    wolfSSL_CTX_UseCavium(ctx, CAVIUM_DEV_ID);
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName))
                                                                 != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif
#ifdef HAVE_MAX_FRAGMENT
    if (maxFragment)
        if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS)
            err_sys("UseMaxFragment failed");
#endif
#ifdef HAVE_TRUNCATED_HMAC
    if (truncatedHMAC)
        if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
            err_sys("UseTruncatedHMAC failed");
#endif
#ifdef HAVE_SESSION_TICKET
    if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
        err_sys("UseSessionTicket failed");
#endif

    if (benchmark) {
        /* time passed in number of connects give average */
        int times = benchmark;
        int loops = resumeSession ? 2 : 1;
        int i = 0;
        WOLFSSL_SESSION* benchSession = NULL;

        while (loops--) {
            int benchResume = resumeSession && loops == 0;
            double start = current_time(), avg;

            for (i = 0; i < times; i++) {
                tcp_connect(&sockfd, host, port, doDTLS);

                ssl = wolfSSL_new(ctx);
                if (benchResume)
                    wolfSSL_set_session(ssl, benchSession);
                wolfSSL_set_fd(ssl, sockfd);
                if (wolfSSL_connect(ssl) != SSL_SUCCESS)
                    err_sys("SSL_connect failed");

                wolfSSL_shutdown(ssl);
                if (i == (times-1) && resumeSession) {
                    benchSession = wolfSSL_get_session(ssl);
                }
                wolfSSL_free(ssl);
                CloseSocket(sockfd);
            }
            avg = current_time() - start;
            avg /= times;
            avg *= 1000;   /* milliseconds */
            if (benchResume)
                printf("wolfSSL_resume  avg took: %8.3f milliseconds\n", avg);
            else
                printf("wolfSSL_connect avg took: %8.3f milliseconds\n", avg);
        }

        wolfSSL_CTX_free(ctx);
        ((func_args*)args)->return_code = 0;

        exit(EXIT_SUCCESS);
    }
    
    #if defined(WOLFSSL_MDK_ARM)
    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
    #endif
    
    ssl = wolfSSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL object");
    #ifdef HAVE_SESSION_TICKET
    wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session");
    #endif
    if (doDTLS) {
        SOCKADDR_IN_T addr;
        build_addr(&addr, host, port, 1);
        wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr));
        tcp_socket(&sockfd, 1);
    }
    else {
        tcp_connect(&sockfd, host, port, 0);
    }

#ifdef HAVE_POLY1305
    /* use old poly to connect with google server */
    if (!XSTRNCMP(domain, "www.google.com", 14)) {
        if (wolfSSL_use_old_poly(ssl, 1) != 0)
            err_sys("unable to set to old poly");
    }
#endif

    wolfSSL_set_fd(ssl, sockfd);
#ifdef HAVE_CRL
    if (disableCRL == 0) {
        if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != SSL_SUCCESS)
            err_sys("can't enable crl check");
        if (wolfSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS)
            err_sys("can't load crl, check crlfile and date validity");
        if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("can't set crl callback");
    }
#endif
#ifdef HAVE_SECURE_RENEGOTIATION
    if (scr) {
        if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS)
            err_sys("can't enable secure renegotiation");
    }
#endif
#ifdef ATOMIC_USER
    if (atomicUser)
        SetupAtomicUser(ctx, ssl);
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif
    if (matchName && doPeerCheck)
        wolfSSL_check_domain_name(ssl, domain);
#ifndef WOLFSSL_CALLBACKS
    if (nonBlocking) {
        wolfSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&sockfd);
        NonBlockingSSL_Connect(ssl);
    }
    else if (wolfSSL_connect(ssl) != SSL_SUCCESS) {
        /* see note at top of README */
        int  err = wolfSSL_get_error(ssl, 0);
        char buffer[WOLFSSL_MAX_ERROR_SZ];
        printf("err = %d, %s\n", err,
                                wolfSSL_ERR_error_string(err, buffer));
        err_sys("SSL_connect failed");
        /* if you're getting an error here  */
    }
#else
    timeout.tv_sec  = 2;
    timeout.tv_usec = 0;
    NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif
    showPeer(ssl);

#ifdef HAVE_SECURE_RENEGOTIATION
    if (scr && forceScr) {
        if (nonBlocking) {
            printf("not doing secure renegotiation on example with"
                   " nonblocking yet");
        } else {
            if (wolfSSL_Rehandshake(ssl) != SSL_SUCCESS) {
                int  err = wolfSSL_get_error(ssl, 0);
                char buffer[WOLFSSL_MAX_ERROR_SZ];
                printf("err = %d, %s\n", err,
                                wolfSSL_ERR_error_string(err, buffer));
                err_sys("wolfSSL_Rehandshake failed");
            }
        }
    }
#endif /* HAVE_SECURE_RENEGOTIATION */

    if (sendGET) {
        printf("SSL connect ok, sending GET...\n");
        msgSz = 28;
        strncpy(msg, "GET /index.html HTTP/1.0\r\n\r\n", msgSz);
        msg[msgSz] = '\0';
    }
    if (wolfSSL_write(ssl, msg, msgSz) != msgSz)
        err_sys("SSL_write failed");

    input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
    if (input > 0) {
        reply[input] = 0;
        printf("Server response: %s\n", reply);

        if (sendGET) {  /* get html */
            while (1) {
                input = wolfSSL_read(ssl, reply, sizeof(reply)-1);
                if (input > 0) {
                    reply[input] = 0;
                    printf("%s\n", reply);
                }
                else
                    break;
            }
        }
    }
    else if (input < 0) {
        int readErr = wolfSSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("wolfSSL_read failed");
    }

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        session   = wolfSSL_get_session(ssl);
        sslResume = wolfSSL_new(ctx);
    }
#endif

    if (doDTLS == 0) {           /* don't send alert after "break" command */
        ret = wolfSSL_shutdown(ssl);
        if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
            wolfSSL_shutdown(ssl);    /* bidirectional shutdown */
    }
#ifdef ATOMIC_USER
    if (atomicUser)
        FreeAtomicUser(ssl);
#endif
    wolfSSL_free(ssl);
    CloseSocket(sockfd);

#ifndef NO_SESSION_CACHE
    if (resumeSession) {
        if (doDTLS) {
            SOCKADDR_IN_T addr;
            #ifdef USE_WINDOWS_API 
                Sleep(500);
            #elif defined(WOLFSSL_TIRTOS)
                Task_sleep(1);
            #else
                sleep(1);
            #endif
            build_addr(&addr, host, port, 1);
            wolfSSL_dtls_set_peer(sslResume, &addr, sizeof(addr));
            tcp_socket(&sockfd, 1);
        }
        else {
            tcp_connect(&sockfd, host, port, 0);
        }
        wolfSSL_set_fd(sslResume, sockfd);
#ifdef HAVE_SECURE_RENEGOTIATION
        if (scr) {
            if (wolfSSL_UseSecureRenegotiation(sslResume) != SSL_SUCCESS)
                err_sys("can't enable secure renegotiation");
        }
#endif
        wolfSSL_set_session(sslResume, session);
#ifdef HAVE_SESSION_TICKET
        wolfSSL_set_SessionTicket_cb(sslResume, sessionTicketCB,
                                    (void*)"resumed session");
#endif
       
        showPeer(sslResume);
#ifndef WOLFSSL_CALLBACKS
        if (nonBlocking) {
            wolfSSL_set_using_nonblock(sslResume, 1);
            tcp_set_nonblocking(&sockfd);
            NonBlockingSSL_Connect(sslResume);
        }
        else if (wolfSSL_connect(sslResume) != SSL_SUCCESS)
            err_sys("SSL resume failed");
#else
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;
        NonBlockingSSL_Connect(ssl);  /* will keep retrying on timeout */
#endif

        if (wolfSSL_session_reused(sslResume))
            printf("reused session id\n");
        else
            printf("didn't reuse session id!!!\n");

        if (wolfSSL_write(sslResume, resumeMsg, resumeSz) != resumeSz)
            err_sys("SSL_write failed");

        if (nonBlocking) {
            /* give server a chance to bounce a message back to client */
            #ifdef USE_WINDOWS_API
                Sleep(500);
            #elif defined(WOLFSSL_TIRTOS)
                Task_sleep(1);
            #else
                sleep(1);
            #endif
        }

        input = wolfSSL_read(sslResume, reply, sizeof(reply)-1);
        if (input > 0) {
            reply[input] = 0;
            printf("Server resume response: %s\n", reply);
        }

        /* try to send session break */
        wolfSSL_write(sslResume, msg, msgSz); 

        ret = wolfSSL_shutdown(sslResume);
        if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
            wolfSSL_shutdown(sslResume);    /* bidirectional shutdown */

        wolfSSL_free(sslResume);
        CloseSocket(sockfd);
    }
#endif /* NO_SESSION_CACHE */

    wolfSSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_WOLFSSL_MEMORY */

#if !defined(WOLFSSL_TIRTOS)
    return 0;
#endif
}