/* cyassl_adds.c
 *
 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

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

#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[80];

    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);
}

