⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mocana_ssl.c

📁 一个典型的用于嵌入式Linux环境的Webserver
💻 C
字号:
/* * mocana_ssl.c * * Mocana Embedded SSL Server *   GoAhead integration layer * * Copyright Mocana Corp 2003. All Rights Reserved. * *//******************************** Description *********************************//* *    This module implements a patch into the Mocana Embedded SSL Server. * */#ifdef __ENABLE_MOCANA_SSL_SERVER__/********************************* Includes ***********************************/#include "mocana_ssl/common/moptions.h"#include "mocana_ssl/common/mdefs.h"#include "mocana_ssl/common/mtypes.h"#include "mocana_ssl/common/merrors.h"#include "mocana_ssl/common/mrtos.h"#include "mocana_ssl/common/mtcp.h"#include "mocana_ssl/common/mocana.h"#include "mocana_ssl/common/random.h"#include "mocana_ssl/ssl/ssl.h"#include    "wsIntrn.h"#include    "webs.h"#include    "websSSL.h"#include <stdio.h>#include <stdlib.h>#include <string.h>/******************************* Definitions **********************************/#ifdef __RTOS_VXWORKS__#define SSL_CERTIFICATE_DER_FILE        "NVRAM:/ssl.der"#define SSL_RSA_HOST_KEYS               "NVRAM:/sslkey.dat"#else#define SSL_CERTIFICATE_DER_FILE        "ssl.der"#define SSL_RSA_HOST_KEYS               "sslkey.dat"#endif#define SSL_PORT                        SSL_DEFAULT_TCPIP_PORT#define MAX_SSL_CONNECTIONS_ALLOWED     (10)#define SSL_HELLO_TIMEOUT               (15000)#define SSL_RECV_TIMEOUT                (300000)#define SSL_EXAMPLE_KEY_SIZE            (1024 + 256)static int      sslListenSock   = -1;            /* Listen socket */static char*    pCertificate    = NULL;static char*    pRsaKeyBlob     = NULL;/******************************* Prototypes  **********************************/int         websSSLAccept(int sid, char *ipaddr, int port, int listenSid);static void websSSLSocketEvent(int sid, int mask, int iwp);static int  websSSLReadEvent(webs_t wp);static int  mocana_SSL_computeHostKeys(char** ppCertificate, unsigned int *pCertLength,                                       char** ppRsaKeyBlob,  unsigned int *pKeyBlobLength);static int  mocana_SSL_releaseHostKeys(char **ppCertificate, char **ppRsaKeyBlob);/******************************************************************************//* *    Start up the SSL Context for the application, and start a listen on the *    SSL port (usually 443, and defined by SSL_PORT) *    Return 0 on success, -1 on failure. */int websSSLOpen(){    unsigned int certLength;    unsigned int rsaKeyBlobLength;    if (0 > MOCANA_initMocana())        return -1;    if (0 > mocana_SSL_computeHostKeys(&pCertificate, &certLength, &pRsaKeyBlob, &rsaKeyBlobLength))        return -1;    if (0 > SSL_init(pCertificate, certLength, pRsaKeyBlob, rsaKeyBlobLength, MAX_SSL_CONNECTIONS_ALLOWED))        return -1;    SSL_sslSettings()->sslTimeOutHello      = SSL_HELLO_TIMEOUT;    SSL_sslSettings()->sslTimeOutReceive    = SSL_RECV_TIMEOUT;    sslListenSock = socketOpenConnection(NULL, SSL_PORT, websSSLAccept, SOCKET_BLOCK);    if (sslListenSock < 0) {        trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"),            SSL_PORT);        return -1;    }    return 0;}/******************************************************************************//* *    Accept a connection */int websSSLAccept(int sid, char *ipaddr, int port, int listenSid){    webs_t    wp;    int        wid;    a_assert(ipaddr && *ipaddr);    a_assert(sid >= 0);    a_assert(port >= 0);/* *    Allocate a new handle for this accepted connection. This will allocate *    a webs_t structure in the webs[] list */    if ((wid = websAlloc(sid)) < 0) {        return -1;    }    wp = webs[wid];    a_assert(wp);    wp->listenSid = listenSid;    ascToUni(wp->ipaddr, ipaddr, min(sizeof(wp->ipaddr), strlen(ipaddr)+1));/* *    Check if this is a request from a browser on this system. This is useful *    to know for permitting administrative operations only for local access */    if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 ||            gstrcmp(wp->ipaddr, websIpaddr) == 0 ||            gstrcmp(wp->ipaddr, websHost) == 0) {        wp->flags |= WEBS_LOCAL_REQUEST;    }/* *    Since the acceptance came in on this channel, it must be secure */    wp->flags |= WEBS_SECURE;/* *    Arrange for websSocketEvent to be called when read data is available */    socketCreateHandler(sid, SOCKET_READABLE, websSSLSocketEvent, (int) wp);/* *    Arrange for a timeout to kill hung requests */    wp->timeout = emfSchedCallback(WEBS_TIMEOUT, websTimeout, (void *) wp);    trace(8, T("webs: accept request\n"));    return 0;}/******************************************************************************//* *    Perform a read of the SSL socket */int websSSLRead(websSSL_t *wsp, char_t *buf, int len){    int     numBytesReceived;    int     rc;    a_assert(wsp);    a_assert(buf);    if ((rc = SSL_recv(wsp->mocanaConnectionInstance, buf, len, &numBytesReceived)) < 0)    {        if (0 > rc)            rc = -1;        return rc;    }    return numBytesReceived;}/******************************************************************************//* *    The webs socket handler.  Called in response to I/O. We just pass control *    to the relevant read or write handler. A pointer to the webs structure *    is passed as an (int) in iwp. */static void websSSLSocketEvent(int sid, int mask, int iwp){    webs_t    wp;    wp = (webs_t) iwp;    a_assert(wp);    if (! websValid(wp)) {        return;    }    if (mask & SOCKET_READABLE) {        websSSLReadEvent(wp);    }    if (mask & SOCKET_WRITABLE) {        if (wp->writeSocket) {            (*wp->writeSocket)(wp);        }    }}/******************************************************************************//* *    Handler for SSL Read Events */static int websSSLReadEvent (webs_t wp){    int            ret = 07, sock;    socket_t    *sptr;    int         connectionInstance;    a_assert (wp);    a_assert(websValid(wp));    sptr = socketPtr(wp->sid);    a_assert(sptr);    sock = sptr->sock;/* *    Create a new SSL session for this web request */    connectionInstance = SSL_acceptConnection(sock);    if (0 > connectionInstance)    {#ifdef __ENABLE_ALL_DEBUGGING__        printf("websSSLReadEvent: SSL_acceptConnection failed. %d\n", connectionInstance);#endif        /* SSL error: cleanup */        websTimeoutCancel(wp);        socketCloseConnection(wp->sid);        websFree(wp);        return -1;    }/* *    Create the SSL data structure in the wp. */    wp->wsp = balloc(B_L, sizeof(websSSL_t));    a_assert (wp->wsp);    (wp->wsp)->mocanaConnectionInstance = connectionInstance;    (wp->wsp)->wp                       = wp;/* *    Call the default Read Event */    websReadEvent(wp);    return ret;}/******************************************************************************//* *    Return TRUE if websSSL has been opened */int websSSLIsOpen(){    return (sslListenSock != -1);}/******************************************************************************//* *    Perform a gets of the SSL socket, returning an balloc'ed string * *    Get a string from a socket. This returns data in *buf in a malloced string *    after trimming the '\n'. If there is zero bytes returned, *buf will be set *    to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when *    no complete line yet read. If doing blocking I/O, it will block until an *    entire line is read. If a partial line is read socketInputBuffered or *    socketEof can be used to distinguish between EOF and partial line still *    buffered. This routine eats and ignores carriage returns. */int    websSSLGets(websSSL_t *wsp, char_t **buf){    socket_t    *sp;    ringq_t        *lq;    char        c;    int            rc, len;    webs_t      wp;    int         sid;    int         mci;    int         numBytesReceived;    a_assert(wsp);    a_assert(buf);    *buf = NULL;    wp  = wsp->wp;    sid = wp->sid;    mci = wsp->mocanaConnectionInstance;    if ((sp = socketPtr(sid)) == NULL) {        return -1;    }    lq = &sp->lineBuf;    while (1) {        if ((rc = SSL_recv(mci, &c, 1, &numBytesReceived)) < 0)        {            if (0 > rc)                rc = -1;            return rc;        }        if (numBytesReceived == 0) {/* *            If there is a partial line and we are at EOF, pretend we saw a '\n' */            if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {                c = '\n';            } else {                continue;            }        }/* *        If a newline is seen, return the data excluding the new line to the *        caller. If carriage return is seen, just eat it. */        if (c == '\n') {            len = ringqLen(lq);            if (len > 0) {                *buf = ballocAscToUni((char *)lq->servp, len);            } else {                *buf = NULL;            }            ringqFlush(lq);            return len;        } else if (c == '\r') {            continue;        }        ringqPutcA(lq, c);    }    return 0;}/******************************************************************************//* *    Perform a write to the SSL socket */int websSSLWrite(websSSL_t *wsp, char_t *buf, int len){    int sslBytesSent;    a_assert(wsp);    a_assert(buf);    if (wsp == NULL) {        return -1;    }    sslBytesSent = SSL_send(wsp->mocanaConnectionInstance, buf, len);    if (0 > sslBytesSent)        sslBytesSent = -1;    return sslBytesSent;}/******************************************************************************//* *    Return Eof for the underlying socket */int websSSLEof(websSSL_t *wsp){    webs_t      wp;    int         sid;    a_assert(wsp);    wp  = wsp->wp;    sid = wp->sid;    return socketEof(sid);}/******************************************************************************//* *   Flush stub for compatibility */int websSSLFlush(websSSL_t *wsp){    a_assert(wsp);    /* Autoflush - do nothing */    return 0;}/******************************************************************************//* *    Free SSL resources */int websSSLFree(websSSL_t *wsp){    int status;    if (NULL != wsp)    {        int mci;        mci = wsp->mocanaConnectionInstance;        status = SSL_closeConnection(mci);        if (0 > status)            status = -1;        /* Free memory here.... */        bfree(B_L, wsp);    }    return status;}/******************************************************************************//* *    Stops the SSL system */void websSSLClose(){    SSL_shutdown();    mocana_SSL_releaseHostKeys(&pCertificate, &pRsaKeyBlob);    SSL_releaseTables();    MOCANA_freeMocana();}/******************************************************************************/static intmocana_SSL_testHostKeys(char** ppCertificate, unsigned int *pCertLength,                         char** ppRsaKeyBlob,  unsigned int *pKeyBlobLength){    int             status;    if (0 > (status = MOCANA_readFile(SSL_CERTIFICATE_DER_FILE, ppCertificate, pCertLength)))        goto exit;    status = MOCANA_readFile(SSL_RSA_HOST_KEYS, ppRsaKeyBlob, pKeyBlobLength);exit:    return status;}/******************************************************************************/static intmocana_SSL_releaseHostKeys(char **ppCertificate, char **ppRsaKeyBlob){    MOCANA_freeReadFile(ppCertificate);    MOCANA_freeReadFile(ppRsaKeyBlob);    return 0;}/******************************************************************************/static intmocana_SSL_computeHostKeys(char** ppCertificate, unsigned int *pCertLength,                            char** ppRsaKeyBlob,  unsigned int *pKeyBlobLength){    int   status;    *ppCertificate = NULL;    *ppRsaKeyBlob  = NULL;    /* check for pre-existing set of host keys */    if (0 > (status = mocana_SSL_testHostKeys(ppCertificate, pCertLength, ppRsaKeyBlob, pKeyBlobLength)))    {#ifdef __ENABLE_ALL_DEBUGGING__        printf("mocana_SSL_computeHostKeys: host keys do not exist, computing new key pair.\n");#endif        /* if not, compute new host keys */        if (0 > (status = SSL_generateCertificate(ppCertificate, pCertLength, ppRsaKeyBlob, pKeyBlobLength, SSL_EXAMPLE_KEY_SIZE)))            goto exit;        if (0 > (status = MOCANA_writeFile(SSL_CERTIFICATE_DER_FILE, *ppCertificate, *pCertLength)))            goto exit;        status = MOCANA_writeFile(SSL_RSA_HOST_KEYS, *ppRsaKeyBlob, *pKeyBlobLength);#ifdef __ENABLE_ALL_DEBUGGING__        printf("mocana_SSL_computeHostKeys: host key computation completed.\n");#endif    }exit:    if (0 > status)        SSL_freeCertificate(ppCertificate, ppRsaKeyBlob);    return status;}/******************************************************************************/#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -