/* cyassl_adds.c
 *
 * Copyright (C) 2006-2014 wolfSSL Inc.
 *
 * This file is part of CyaSSL.
 *
 * CyaSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * CyaSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */

#ifdef HAVE_CONFIG_H
    #include <config.h>
#endif

#include <cyassl/ctaocrypt/settings.h>

#ifndef _WIN32
    #define HAVE_CONFIG_H
#endif

#include <cyassl/ssl.h>
#include <cyassl/ctaocrypt/rsa.h>
#include <cyassl/ctaocrypt/asn.h>

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>

#ifdef _WIN32
    #include <winsock2.h>
    #include <process.h>
    #ifdef TEST_IPV6            /* don't require newer SDK for IPV4 */
	    #include <ws2tcpip.h>
        #include <wspiapi.h>
    #endif
    #define SOCKET_T int
#else
    #include <string.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/ioctl.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <pthread.h>
    #ifdef NON_BLOCKING
        #include <fcntl.h>
    #endif
    #ifdef TEST_IPV6
        #include <netdb.h>
    #endif
    #define SOCKET_T unsigned int
#endif /* _WIN32 */

#ifdef _MSC_VER
    /* disable conversion warning */
    /* 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy */
    #pragma warning(disable:4244 4996)
#endif

#if defined(__MACH__) || defined(_WIN32)
    #ifndef _SOCKLEN_T
        typedef int socklen_t;
    #endif
#endif


/* HPUX doesn't use socklent_t for third parameter to accept */
#if !defined(__hpux__)
    typedef socklen_t* ACCEPT_THIRD_T;
#else
    typedef int*       ACCEPT_THIRD_T;
#endif


#ifdef _WIN32
    #define CloseSocket(s) closesocket(s)
    #define StartTCP() { WSADATA wsd; WSAStartup(0x0002, &wsd); }
#else
    #define CloseSocket(s) close(s)
    #define StartTCP() 
#endif


#ifdef TEST_IPV6
    typedef struct sockaddr_in6 SOCKADDR_IN_T;
    #define AF_INET_V    AF_INET6
#else
    typedef struct sockaddr_in  SOCKADDR_IN_T;
    #define AF_INET_V    AF_INET
#endif
   

enum {
    SSL_BLOCKING    = 2,
    SSL_NONBLOCKING = 4
};


static int tcp_socket(SOCKET_T* sockfd, SOCKADDR_IN_T* addr, const char* peer,
                       short port)
{
    const char* host = peer;

    /* peer could be in human readable form */
    if (isalpha(peer[0])) {
        struct hostent* entry = gethostbyname(peer);

        if (entry) {
            struct sockaddr_in tmp;
            memset(&tmp, 0, sizeof(struct sockaddr_in));
            memcpy(&tmp.sin_addr.s_addr, entry->h_addr_list[0],entry->h_length);
            host = inet_ntoa(tmp.sin_addr);
        }
        else
            return -1;   /* no entry for host */ 
    }

    *sockfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(addr, 0, sizeof(SOCKADDR_IN_T));

    addr->sin_family = AF_INET;
    addr->sin_port = htons(port);
    addr->sin_addr.s_addr = inet_addr(host);

#ifdef SO_NOSIGPIPE
    {
        int on = 1;
        socklen_t len = sizeof(on);
        setsockopt(*sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, len);
    }
#endif

    return 0;
}


static int tcp_connect(SOCKET_T* sockfd, const char* ip, short port)
{
    SOCKADDR_IN_T addr;
    int ret = tcp_socket(sockfd, &addr, ip, port);
    if (ret != 0) return ret;

    if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
        return -2; /* can't connect */

    return 0;
}
    

int CyaSSL_swig_connect(CYASSL* ssl, const char* server, int port)
{
    SOCKET_T sockfd;
    int ret = tcp_connect(&sockfd, server, port);
    if (ret != 0) return ret;
    
    CyaSSL_set_fd(ssl, sockfd);

    return CyaSSL_connect(ssl);
}


char* CyaSSL_error_string(int err)
{
    static char buffer[CYASSL_MAX_ERROR_SZ];

    return CyaSSL_ERR_error_string(err, buffer);
}


RNG* GetRng(void)
{
    RNG* rng = (RNG*)malloc(sizeof(RNG));

    if (rng)
        if (InitRng(rng) != 0) {
            free(rng);
            rng = 0;
        }

    return rng;
}


RsaKey* GetRsaPrivateKey(const char* keyFile)
{
    RsaKey* key = (RsaKey*)malloc(sizeof(RsaKey));

    if (key) {
        byte   tmp[1024];
        size_t bytes;
        int    ret;
        word32 idx = 0;
        FILE*  file = fopen(keyFile, "rb");

        if (!file) {
            free(key);
            return 0;
        }

        bytes = fread(tmp, 1, sizeof(tmp), file);
        fclose(file);
        InitRsaKey(key, 0);

        ret = RsaPrivateKeyDecode(tmp, &idx, key, (word32)bytes);
        if (ret != 0) {
            FreeRsaKey(key);
            free(key);
            return 0;
        }
    }
    return key;
}


void FillSignStr(unsigned char* dst, const char* src, int size)
{
    memcpy(dst, src, size);
}

