CyaSSL is an SSL library for devices like mbed.

Dependents:   cyassl-client Sync

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl.c Source File

ssl.c

00001 /* ssl.c
00002  *
00003  * Copyright (C) 2006-2009 Sawtooth Consulting Ltd.
00004  *
00005  * This file is part of CyaSSL.
00006  *
00007  * CyaSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * CyaSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00020  */
00021 
00022 
00023 #include "ssl.h"
00024 #include "cyassl_int.h"
00025 #include "cyassl_error.h"
00026 #include "coding.h"
00027 
00028 #ifdef OPENSSL_EXTRA
00029     /* openssl headers begin */
00030     #include "evp.h"
00031     #include "hmac.h"
00032     #include "crypto.h"
00033     #include "des.h"
00034     /* openssl headers end, cyassl internal headers next */
00035     #include "ctc_hmac.h"
00036     #include "random.h"
00037     #include "des3.h"
00038     #include "ctc_md4.h"
00039     #include "coding.h"
00040 #endif
00041 
00042 #ifdef HAVE_ERRNO_H 
00043     #include <errno.h>
00044 #endif
00045 
00046 #define TRUE  1
00047 #define FALSE 0
00048 
00049 
00050 #ifndef min
00051 
00052     static INLINE word32 min(word32 a, word32 b)
00053     {
00054         return a > b ? b : a;
00055     }
00056 
00057 #endif /* min */
00058 
00059 
00060 
00061 SSL_CTX* SSL_CTX_new(SSL_METHOD* method)
00062 {
00063     SSL_CTX* ctx = (SSL_CTX*) XMALLOC(sizeof(SSL_CTX), 0, DYNAMIC_TYPE_CTX);
00064     if (ctx)
00065         InitSSL_Ctx(ctx, method);
00066 
00067     return ctx;
00068 }
00069 
00070 
00071 void SSL_CTX_free(SSL_CTX* ctx)
00072 {
00073     if (ctx)
00074         FreeSSL_Ctx(ctx);
00075 }
00076 
00077 
00078 SSL* SSL_new(SSL_CTX* ctx)
00079 {
00080 
00081     SSL* ssl = (SSL*) XMALLOC(sizeof(SSL), ctx->heap, DYNAMIC_TYPE_SSL);
00082     if (ssl)
00083         if (InitSSL(ssl, ctx) < 0) {
00084             FreeSSL(ssl);
00085             ssl = 0;
00086         }
00087 
00088     return ssl;
00089 }
00090 
00091 
00092 void SSL_free(SSL* ssl)
00093 {
00094     CYASSL_ENTER("SSL_free");
00095     if (ssl)
00096         FreeSSL(ssl);
00097     CYASSL_LEAVE("SSL_free", 0);
00098 }
00099 
00100 
00101 int SSL_set_fd(SSL* ssl, int fd)
00102 {
00103     ssl->rfd = fd;      /* not used directly to allow IO callbacks */
00104     ssl->wfd = fd;
00105 
00106     ssl->IOCB_ReadCtx  = &ssl->rfd;
00107     ssl->IOCB_WriteCtx = &ssl->wfd;
00108 
00109     return SSL_SUCCESS;
00110 }
00111 
00112 
00113 int SSL_get_fd(const SSL* ssl)
00114 {
00115     return ssl->rfd;
00116 }
00117 
00118 
00119 int CyaSSL_negotiate(SSL* ssl)
00120 {
00121     int err = -1;
00122 
00123 #ifndef NO_CYASSL_SERVER
00124     if (ssl->options.side == SERVER_END)
00125         err = SSL_accept(ssl);
00126 #endif
00127 
00128 #ifndef NO_CYASSL_CLIENT
00129     if (ssl->options.side == CLIENT_END)
00130         err = SSL_connect(ssl);
00131 #endif
00132 
00133     if (err == SSL_SUCCESS)
00134         return 0;
00135     else
00136         return err;
00137 }
00138 
00139 
00140 int SSL_write(SSL* ssl, const void* buffer, int sz)
00141 {
00142     int ret;
00143 
00144     CYASSL_ENTER("SSL_write()");
00145 
00146 #ifdef HAVE_ERRNO_H 
00147     errno = 0;
00148 #endif
00149 
00150     ret = SendData(ssl, buffer, sz);
00151 
00152     CYASSL_LEAVE("SSL_write()", ret);
00153 
00154     if (ret < 0)
00155         return SSL_FATAL_ERROR;
00156     else
00157         return ret;
00158 }
00159 
00160 
00161 int SSL_read(SSL* ssl, void* buffer, int sz)
00162 {
00163     int ret; 
00164 
00165     CYASSL_ENTER("SSL_read()");
00166 
00167 #ifdef HAVE_ERRNO_H 
00168         errno = 0;
00169 #endif
00170 
00171     ret = ReceiveData(ssl, (byte*)buffer, min(sz, OUTPUT_RECORD_SIZE));
00172 
00173     CYASSL_LEAVE("SSL_read()", ret);
00174 
00175     if (ret < 0)
00176         return SSL_FATAL_ERROR;
00177     else
00178         return ret;
00179 }
00180 
00181 
00182 int SSL_shutdown(SSL* ssl)
00183 {
00184     CYASSL_ENTER("SSL_shutdown()");
00185 
00186     if (ssl->options.quietShutdown) {
00187         CYASSL_MSG("quiet shutdown, no close notify sent"); 
00188         return 0;
00189     }
00190 
00191     /* try to send close notify, not an error if can't */
00192     if (!ssl->options.isClosed && !ssl->options.connReset &&
00193                                   !ssl->options.sentNotify) {
00194         ssl->error = SendAlert(ssl, alert_warning, close_notify);
00195         if (ssl->error < 0) {
00196             CYASSL_ERROR(ssl->error);
00197             return SSL_FATAL_ERROR;
00198         }
00199         ssl->options.sentNotify = 1;  /* don't send close_notify twice */
00200     }
00201 
00202     CYASSL_LEAVE("SSL_shutdown()", ssl->error);
00203 
00204     ssl->error = SSL_ERROR_SYSCALL;   /* simulate OpenSSL behavior */
00205 
00206     return 0;
00207 }
00208 
00209 
00210 int SSL_get_error(SSL* ssl, int dummy)
00211 {
00212     if (ssl->error == WANT_READ)
00213         return SSL_ERROR_WANT_READ;         /* convert to OpenSSL type */
00214     else if (ssl->error == WANT_WRITE)
00215         return SSL_ERROR_WANT_WRITE;        /* convert to OpenSSL type */
00216     else if (ssl->error == ZERO_RETURN) 
00217         return SSL_ERROR_ZERO_RETURN;       /* convert to OpenSSL type */
00218     return ssl->error;
00219 }
00220 
00221 
00222 int SSL_want_read(SSL* ssl)
00223 {
00224     if (ssl->error == WANT_READ)
00225         return 1;
00226 
00227     return 0;
00228 }
00229 
00230 
00231 int SSL_want_write(SSL* ssl)
00232 {
00233     if (ssl->error == WANT_WRITE)
00234         return 1;
00235 
00236     return 0;
00237 }
00238 
00239 
00240 char* ERR_error_string(unsigned long errNumber, char* buffer)
00241 {
00242     static char* msg = "Please supply a buffer for error string";
00243 
00244     if (buffer) {
00245         SetErrorString(errNumber, buffer);
00246         return buffer;
00247     }
00248 
00249     return msg;
00250 }
00251 
00252 
00253 void ERR_error_string_n(unsigned long e, char* buf, size_t len)
00254 {
00255     if (len) ERR_error_string(e, buf);
00256 }
00257 
00258 
00259 #ifndef NO_FILESYSTEM
00260 
00261 void ERR_print_errors_fp(FILE* fp, int err)
00262 {
00263     char buffer[MAX_ERROR_SZ + 1];
00264 
00265     SetErrorString(err, buffer);
00266     fprintf(fp, "%s", buffer);
00267 }
00268 
00269 #endif
00270 
00271 
00272 int SSL_pending(SSL* ssl)
00273 {
00274     return ssl->buffers.clearOutputBuffer.length;
00275 }
00276 
00277 
00278 /* owns der */
00279 static int AddCA(SSL_CTX* ctx, buffer der)
00280 {
00281     word32      ret;
00282     DecodedCert cert;
00283     Signer*     signer = 0;
00284 
00285     InitDecodedCert(&cert, der.buffer, ctx->heap);
00286     ret = ParseCert(&cert, der.length, CA_TYPE, ctx->verifyPeer, 0);
00287 
00288     if (ret == 0) {
00289         /* take over signer parts */
00290         signer = MakeSigner(ctx->heap);
00291         if (!signer)
00292             ret = MEMORY_ERROR;
00293         else {
00294             signer->keyOID     = cert.keyOID;
00295             signer->publicKey  = cert.publicKey;
00296             signer->pubKeySize = cert.pubKeySize;
00297             signer->name = cert.subjectCN;
00298             XMEMCPY(signer->hash, cert.subjectHash, SHA_DIGEST_SIZE);
00299 
00300             cert.publicKey = 0;  /* don't free here */
00301             cert.subjectCN = 0;
00302 
00303             signer->next = ctx->caList;
00304             ctx->caList  = signer;   /* takes ownership */
00305         }
00306     }
00307 
00308     FreeDecodedCert(&cert);
00309     XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_CA);
00310 
00311     if (ret == 0) return SSL_SUCCESS;
00312     return ret;
00313 }
00314 
00315 
00316 #ifndef NO_SESSION_CACHE
00317 
00318     /* basic config gives a cache with 33 sessions, adequate for clients and
00319        embedded servers
00320 
00321        BIG_SESSION_CACHE allows 1055 sessions, adequate for servers that aren't
00322        under heavy load, basically allows 200 new sessions per minute
00323 
00324        HUGE_SESSION_CACHE yields 65,791 sessions, for servers under heavy load,
00325        allows over 13,000 new sessions per minute or over 200 new sessions per
00326        second
00327     */
00328     #ifdef HUGE_SESSION_CACHE
00329         #define SESSIONS_PER_ROW 11
00330         #define SESSION_ROWS 5981
00331     #elif defined(BIG_SESSION_CACHE)
00332         #define SESSIONS_PER_ROW 5
00333         #define SESSION_ROWS 211
00334     #else
00335         #define SESSIONS_PER_ROW 3
00336         #define SESSION_ROWS 11
00337     #endif
00338 
00339     typedef struct SessionRow {
00340         int nextIdx;                           /* where to place next one   */
00341         int totalCount;                        /* sessions ever on this row */
00342         SSL_SESSION Sessions[SESSIONS_PER_ROW];
00343     } SessionRow;
00344 
00345     static SessionRow SessionCache[SESSION_ROWS];
00346 
00347     static CyaSSL_Mutex mutex;   /* SessionCache mutex */
00348 
00349 #endif /* NO_SESSION_CACHE */
00350 
00351 
00352     static int PemToDer(const unsigned char* buff, long sz, int type,
00353                         buffer* der, void* heap, EncryptedInfo* info)
00354     {
00355         char  header[PEM_LINE_LEN];
00356         char  footer[PEM_LINE_LEN];
00357         char* headerEnd;
00358         char* footerEnd;
00359         long  neededSz;
00360         int   pkcs8 = 0;
00361         int   dynamicType;
00362 
00363         if (type == CERT_TYPE || type == CA_TYPE)  {
00364             XSTRNCPY(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
00365             XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
00366             dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
00367                                               DYNAMIC_TYPE_CERT;
00368         } else {
00369             XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
00370             XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer));
00371             dynamicType = DYNAMIC_TYPE_KEY;
00372         }
00373 
00374         /* find header */
00375         headerEnd = XSTRSTR((char*)buff, header);
00376         if (!headerEnd && type == PRIVATEKEY_TYPE) {  /* may be pkcs8 */
00377             XSTRNCPY(header, "-----BEGIN PRIVATE KEY-----", sizeof(header));
00378             XSTRNCPY(footer, "-----END PRIVATE KEY-----", sizeof(footer));
00379         
00380             headerEnd = XSTRSTR((char*)buff, header);
00381             if (headerEnd)
00382                 pkcs8 = 1;
00383             /*
00384             else
00385                 maybe encrypted "-----BEGIN ENCRYPTED PRIVATE KEY-----"
00386             */
00387         }
00388         if (!headerEnd)
00389             return SSL_BAD_FILE;
00390         headerEnd += XSTRLEN(header);
00391 
00392         /* get next line */
00393         if (headerEnd[0] == '\n')
00394             headerEnd++;
00395         else if (headerEnd[1] == '\n')
00396             headerEnd += 2;
00397         else
00398             return SSL_BAD_FILE;
00399 
00400 #ifdef OPENSSL_EXTRA
00401     {
00402         /* remove encrypted header if there */
00403         char encHeader[] = "Proc-Type";
00404         char* line = XSTRSTR((char*)buff, encHeader);
00405         if (line) {
00406             char* newline;
00407             char* finish;
00408             char* start  = XSTRSTR(line, "DES");
00409     
00410             if (!start)
00411                 start = XSTRSTR(line, "AES");
00412             
00413             if (!start) return SSL_BAD_FILE;
00414             if (!info)  return SSL_BAD_FILE;
00415             
00416             finish = XSTRSTR(start, ",");
00417 
00418             if (start && finish && (start < finish)) {
00419                 newline = XSTRSTR(finish, "\r");
00420 
00421                 XMEMCPY(info->name, start, finish - start);
00422                 info->name[finish - start] = 0;
00423                 XMEMCPY(info->iv, finish + 1, sizeof(info->iv));
00424 
00425                 if (!newline) newline = XSTRSTR(finish, "\n");
00426                 if (newline && (newline > finish)) {
00427                     info->ivSz = (word32)(newline - (finish + 1));
00428                     info->set = 1;
00429                 }
00430                 else
00431                     return SSL_BAD_FILE;
00432             }
00433             else
00434                 return SSL_BAD_FILE;
00435 
00436             /* eat blank line */
00437             while (*newline == '\r' || *newline == '\n')
00438                 newline++;
00439             headerEnd = newline;
00440         }
00441     }
00442 #endif /* OPENSSL_EXTRA */
00443 
00444         /* find footer */
00445         footerEnd = XSTRSTR((char*)buff, footer);
00446         if (!footerEnd) return SSL_BAD_FILE;
00447 
00448         /* set up der buffer */
00449         neededSz = (long)(footerEnd - headerEnd);
00450         if (neededSz > sz || neededSz < 0) return SSL_BAD_FILE;
00451         der->buffer = (byte*) XMALLOC(neededSz, heap, dynamicType);
00452         if (!der->buffer) return MEMORY_ERROR;
00453         der->length = neededSz;
00454 
00455         if (Base64Decode((byte*)headerEnd, neededSz, der->buffer,
00456                          &der->length) < 0)
00457             return SSL_BAD_FILE;
00458 
00459         if (pkcs8)
00460             return ToTraditional(der->buffer, der->length);
00461 
00462         /* not full support yet 
00463          if (pkcs8Enc)
00464             return ToTraditionalEnc(der->buffer, der->length);
00465         */
00466 
00467         return 0;
00468     }
00469 
00470 
00471     static int ProcessBuffer(SSL_CTX* ctx, const unsigned char* buff,
00472                              long sz, int format, int type)
00473     {
00474         EncryptedInfo info;
00475         buffer        der;        /* holds DER or RAW (for NTRU */
00476         int           dynamicType;
00477 
00478         info.set   = 0;
00479         der.buffer = 0;
00480 
00481         if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM 
00482                                         && format != SSL_FILETYPE_RAW)
00483             return SSL_BAD_FILETYPE;
00484 
00485         if (type == CA_TYPE)
00486             dynamicType = DYNAMIC_TYPE_CA;
00487         else if (type == CERT_TYPE)
00488             dynamicType = DYNAMIC_TYPE_CERT;
00489         else
00490             dynamicType = DYNAMIC_TYPE_KEY;
00491 
00492         if (format == SSL_FILETYPE_PEM) {
00493             if (PemToDer(buff, sz, type, &der, ctx->heap, &info) < 0) {
00494                 XFREE(der.buffer, ctx->heap, dynamicType);
00495                 return SSL_BAD_FILE;
00496             }
00497         }
00498         else {  /* ASN1 (DER) or RAW (NTRU) */
00499             der.buffer = (byte*) XMALLOC(sz, ctx->heap, dynamicType);
00500             if (!der.buffer) return MEMORY_ERROR;
00501             XMEMCPY(der.buffer, buff, sz);
00502             der.length = sz;
00503         }
00504 
00505 #ifdef OPENSSL_EXTRA
00506         if (info.set) {
00507             /* decrypt */
00508             char password[80];
00509             int  passwordSz;
00510 
00511             byte key[AES_256_KEY_SIZE];
00512             byte  iv[AES_IV_SIZE];
00513 
00514             if (!ctx->passwd_cb) return -1;
00515 
00516             /* use file's salt for key derivation, hex decode first */
00517             if (Base16Decode(info.iv, info.ivSz, info.iv, &info.ivSz) != 0)
00518                 return -1;
00519 
00520             passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
00521                                     ctx->userdata);
00522             if (EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
00523                                passwordSz, 1, key, iv) <= 0)
00524                 return -1;
00525 
00526             if (XSTRNCMP(info.name, "DES-CBC", 7) == 0) {
00527                 Des des;
00528                 Des_SetKey(&des, key, info.iv, DES_DECRYPTION);
00529                 Des_CbcDecrypt(&des, der.buffer, der.buffer, der.length);
00530             }
00531             else if (XSTRNCMP(info.name, "DES-EDE3-CBC", 13) == 0) {
00532                 Des3 des;
00533                 Des3_SetKey(&des, key, info.iv, DES_DECRYPTION);
00534                 Des3_CbcDecrypt(&des, der.buffer, der.buffer, der.length);
00535             }
00536             else if (XSTRNCMP(info.name, "AES-128-CBC", 13) == 0) {
00537                 Aes aes;
00538                 AesSetKey(&aes, key, AES_128_KEY_SIZE, info.iv, AES_DECRYPTION);
00539                 AesCbcDecrypt(&aes, der.buffer, der.buffer, der.length);
00540             }
00541             else if (XSTRNCMP(info.name, "AES-192-CBC", 13) == 0) {
00542                 Aes aes;
00543                 AesSetKey(&aes, key, AES_192_KEY_SIZE, info.iv, AES_DECRYPTION);
00544                 AesCbcDecrypt(&aes, der.buffer, der.buffer, der.length);
00545             }
00546             else if (XSTRNCMP(info.name, "AES-256-CBC", 13) == 0) {
00547                 Aes aes;
00548                 AesSetKey(&aes, key, AES_256_KEY_SIZE, info.iv, AES_DECRYPTION);
00549                 AesCbcDecrypt(&aes, der.buffer, der.buffer, der.length);
00550             }
00551             else 
00552                 return SSL_BAD_FILE;
00553         }
00554 #endif /* OPENSSL_EXTRA */
00555 
00556         if (type == CA_TYPE)
00557             return AddCA(ctx, der);     /* takes der over */
00558         else if (type == CERT_TYPE) {
00559             if (ctx->certificate.buffer)
00560                 XFREE(ctx->certificate.buffer, ctx->heap, dynamicType);
00561             ctx->certificate = der;     /* takes der over */
00562         }
00563         else if (type == PRIVATEKEY_TYPE) {
00564             if (ctx->privateKey.buffer)
00565                 XFREE(ctx->privateKey.buffer, ctx->heap, dynamicType);
00566             ctx->privateKey = der;      /* takes der over */
00567         }
00568         else {
00569             XFREE(der.buffer, ctx->heap, dynamicType);
00570             return SSL_BAD_CERTTYPE;
00571         }
00572 
00573         if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) {
00574             /* make sure RSA key can be used */
00575             RsaKey key;
00576             word32 idx = 0;
00577         
00578             InitRsaKey(&key, 0);
00579             if (RsaPrivateKeyDecode(der.buffer, &idx, &key, der.length) != 0) {
00580                 FreeRsaKey(&key);
00581                 return SSL_BAD_FILE;
00582             }
00583         
00584             FreeRsaKey(&key);
00585         }
00586 
00587         return SSL_SUCCESS;
00588     }
00589 
00590 
00591 #ifndef NO_FILESYSTEM
00592 
00593 #ifndef MICRIUM
00594     #define XFILE      FILE
00595     #define XFOPEN     fopen 
00596     #define XFSEEK     fseek
00597     #define XFTELL     ftell
00598     #define XREWIND    rewind
00599     #define XFREAD     fread
00600     #define XFCLOSE    fclose
00601     #define XSEEK_END  SEEK_END
00602 #else
00603     #include <fs.h>
00604     #define XFILE      FS_FILE
00605     #define XFOPEN     fs_fopen 
00606     #define XFSEEK     fs_fseek
00607     #define XFTELL     fs_ftell
00608     #define XREWIND    fs_rewind
00609     #define XFREAD     fs_fread
00610     #define XFCLOSE    fs_fclose
00611     #define XSEEK_END  FS_SEEK_END
00612 #endif
00613 
00614 static int ProcessFile(SSL_CTX* ctx, const char* fname, int format, int type)
00615 {
00616     byte   staticBuffer[FILE_BUFFER_SIZE];
00617     byte*  buffer = staticBuffer;
00618     int    dynamic = 0;
00619     int    ret;
00620     long   sz = 0;
00621     XFILE* file = XFOPEN(fname, "rb"); 
00622 
00623     if (!file) return SSL_BAD_FILE;
00624     XFSEEK(file, 0, XSEEK_END);
00625     sz = XFTELL(file);
00626     XREWIND(file);
00627 
00628     if (sz > sizeof(staticBuffer)) {
00629         buffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
00630         if (buffer == NULL) {
00631             XFCLOSE(file);
00632             return SSL_BAD_FILE;
00633         }
00634         dynamic = 1;
00635     }
00636 
00637     if ( (ret = XFREAD(buffer, sz, 1, file)) < 0)
00638         ret = SSL_BAD_FILE;
00639     else
00640         ret = ProcessBuffer(ctx, buffer, sz, format, type);
00641 
00642     XFCLOSE(file);
00643     if (dynamic) XFREE(buffer, ctx->heap, DYNAMIC_TYPE_FILE);
00644 
00645     return ret;
00646 }
00647 
00648 
00649 /* just one for now TODO: add dir support from path */
00650 int SSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file,
00651                                   const char* path)
00652 {
00653     if (ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE) == SSL_SUCCESS)
00654         return SSL_SUCCESS;
00655 
00656     return SSL_FAILURE;
00657 }
00658 
00659 
00660 #ifdef CYASSL_DER_LOAD
00661 
00662 /* Add format parameter to allow DER load of CA files */
00663 int CyaSSL_CTX_load_verify_locations(SSL_CTX* ctx, const char* file, int format)
00664 {
00665     if (ProcessFile(ctx, file, format, CA_TYPE) == SSL_SUCCESS)
00666         return SSL_SUCCESS;
00667 
00668     return SSL_FAILURE;
00669 }
00670 
00671 #endif /* CYASSL_DER_LOAD */
00672 
00673 
00674 #ifdef CYASSL_CERT_GEN
00675 
00676 /* load pem cert from file into der buffer, return der size or error */
00677 int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) 
00678 {
00679     byte   staticBuffer[FILE_BUFFER_SIZE];
00680     byte*  fileBuf = staticBuffer;
00681     int    dynamic = 0;
00682     int    ret;
00683     long   sz = 0;
00684     XFILE* file = XFOPEN(fileName, "rb"); 
00685     EncryptedInfo info;
00686     buffer        converted;
00687 
00688     converted.buffer = 0;
00689 
00690     if (!file) return SSL_BAD_FILE;
00691     XFSEEK(file, 0, XSEEK_END);
00692     sz = XFTELL(file);
00693     XREWIND(file);
00694 
00695     if (sz > sizeof(staticBuffer)) {
00696         fileBuf = (byte*) XMALLOC(sz, 0, DYNAMIC_TYPE_FILE);
00697         if (fileBuf == NULL) {
00698             XFCLOSE(file);
00699             return SSL_BAD_FILE;
00700         }
00701         dynamic = 1;
00702     }
00703 
00704     if ( (ret = XFREAD(fileBuf, sz, 1, file)) < 0)
00705         ret = SSL_BAD_FILE;
00706     else
00707         ret = PemToDer(fileBuf, sz, CA_TYPE, &converted, 0, &info);
00708 
00709     if (ret == 0) {
00710         if (converted.length < derSz) {
00711             memcpy(derBuf, converted.buffer, converted.length);
00712             ret = converted.length;
00713         }
00714         else
00715             ret = BUFFER_E;
00716     }       
00717 
00718     XFREE(converted.buffer, 0, DYNAMIC_TYPE_CA); 
00719     if (dynamic)
00720         XFREE(fileBuf, 0, DYNAMIC_TYPE_FILE); 
00721     XFCLOSE(file);
00722 
00723     return ret;
00724 }
00725 
00726 #endif /* CYASSL_CERT_GEN */
00727 
00728 
00729 int SSL_CTX_use_certificate_file(SSL_CTX* ctx, const char* file, int format)
00730 {
00731     if (ProcessFile(ctx, file, format, CERT_TYPE) == SSL_SUCCESS)
00732         return SSL_SUCCESS;
00733 
00734     return SSL_FAILURE;
00735 }
00736 
00737 
00738 int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx, const char* file, int format)
00739 {
00740     if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE) == SSL_SUCCESS)
00741         return SSL_SUCCESS;
00742 
00743     return SSL_FAILURE;
00744 }
00745 
00746 
00747 int SSL_CTX_use_certificate_chain_file(SSL_CTX* ctx, const char* file)
00748 {
00749     /* add first to ctx, all tested implementations support this */
00750    if (ProcessFile(ctx, file, SSL_FILETYPE_PEM, CERT_TYPE) == SSL_SUCCESS)
00751        return SSL_SUCCESS;
00752 
00753    return SSL_FAILURE;
00754 }
00755 
00756 
00757 #ifdef HAVE_NTRU
00758 
00759 int CyaSSL_CTX_use_NTRUPrivateKey_file(SSL_CTX* ctx, const char* file)
00760 {
00761     if (ProcessFile(ctx, file, SSL_FILETYPE_RAW, PRIVATEKEY_TYPE)
00762                          == SSL_SUCCESS) {
00763         ctx->haveNTRU = 1;
00764         return SSL_SUCCESS;
00765     }
00766 
00767     return SSL_FAILURE;
00768 }
00769 
00770 #endif /* HAVE_NTRU */
00771 
00772 
00773 
00774 #ifdef OPENSSL_EXTRA
00775 
00776     int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX* ctx,const char* file,int format)
00777     {
00778         if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE) == SSL_SUCCESS)
00779             return SSL_SUCCESS;
00780 
00781         return SSL_FAILURE;
00782     }
00783 
00784 #endif /* OPENSSL_EXTRA */
00785 
00786 #endif /* NO_FILESYSTEM */
00787 
00788 
00789 void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc)
00790 {
00791     if (mode & SSL_VERIFY_PEER) {
00792         ctx->verifyPeer = 1;
00793         ctx->verifyNone = 0;  /* in case perviously set */
00794     }
00795 
00796     if (mode == SSL_VERIFY_NONE) {
00797         ctx->verifyNone = 1;
00798         ctx->verifyPeer = 0;  /* in case previously set */
00799     }
00800 
00801     if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
00802         ctx->failNoCert = 1;
00803 
00804     ctx->verifyCallback = vc;
00805 }
00806 
00807 
00808 #ifndef NO_SESSION_CACHE
00809 
00810 SSL_SESSION* SSL_get_session(SSL* ssl)
00811 {
00812     return GetSession(ssl, 0);
00813 }
00814 
00815 
00816 int SSL_set_session(SSL* ssl, SSL_SESSION* session)
00817 {
00818     if (session)
00819         return SetSession(ssl, session);
00820 
00821     return SSL_FAILURE;
00822 }
00823 
00824 #endif /* NO_SESSION_CACHE */
00825 
00826 
00827 void SSL_load_error_strings(void)   /* compatibility only */
00828 {}
00829 
00830 
00831 int SSL_library_init(void)
00832 {
00833     if (InitCyaSSL() == 0)
00834         return SSL_SUCCESS;
00835     else
00836         return -1;
00837 }
00838 
00839 
00840 #ifndef NO_SESSION_CACHE
00841 
00842 /* on by default if built in but allow user to turn off */
00843 long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode)
00844 {
00845     if (mode == SSL_SESS_CACHE_OFF)
00846         ctx->sessionCacheOff = 1;
00847 
00848     if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
00849         ctx->sessionCacheFlushOff = 1;
00850 
00851     return SSL_SUCCESS;
00852 }
00853 
00854 #endif /* NO_SESSION_CACHE */
00855 
00856 
00857 int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list)
00858 {
00859     if (SetCipherList(ctx, list))
00860         return SSL_SUCCESS;
00861     else
00862         return SSL_FAILURE;
00863 }
00864 
00865 
00866 /* client only parts */
00867 #ifndef NO_CYASSL_CLIENT
00868 
00869     SSL_METHOD* SSLv3_client_method(void)
00870     {
00871         SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0,
00872                                                    DYNAMIC_TYPE_METHOD);
00873         if (method)
00874             InitSSL_Method(method, MakeSSLv3());
00875         return method;
00876     }
00877 
00878     #ifdef CYASSL_DTLS
00879         SSL_METHOD* DTLSv1_client_method(void)
00880         {
00881             SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0,
00882                                                        DYNAMIC_TYPE_METHOD);
00883             if (method)
00884                 InitSSL_Method(method, MakeDTLSv1());
00885             return method;
00886         }
00887     #endif
00888 
00889 
00890     /* please see note at top of README if you get an error from connect */
00891     int SSL_connect(SSL* ssl)
00892     {
00893         int neededState;
00894 
00895         CYASSL_ENTER("SSL_connect()");
00896 
00897         #ifdef HAVE_ERRNO_H 
00898             errno = 0;
00899         #endif
00900 
00901         if (ssl->options.side != CLIENT_END) {
00902             CYASSL_ERROR(ssl->error = SIDE_ERROR);
00903             return SSL_FATAL_ERROR;
00904         }
00905 
00906         #ifdef CYASSL_DTLS
00907             if (ssl->version.major == DTLS_MAJOR && 
00908                                       ssl->version.minor == DTLS_MINOR) {
00909                 ssl->options.dtls   = 1;
00910                 ssl->options.tls    = 1;
00911                 ssl->options.tls1_1 = 1;
00912             }
00913         #endif
00914 
00915         if (ssl->buffers.outputBuffer.length > 0) {
00916             if ( (ssl->error = SendBuffered(ssl)) == 0) {
00917                 ssl->options.connectState++;
00918                 CYASSL_MSG("connect state: Advanced from buffered send");
00919             }
00920             else {
00921                 CYASSL_ERROR(ssl->error);
00922                 return SSL_FATAL_ERROR;
00923             }
00924         }
00925 
00926         switch (ssl->options.connectState) {
00927 
00928         case CONNECT_BEGIN :
00929             /* always send client hello first */
00930             if ( (ssl->error = SendClientHello(ssl)) != 0) {
00931                 CYASSL_ERROR(ssl->error);
00932                 return SSL_FATAL_ERROR;
00933             }
00934             ssl->options.connectState = CLIENT_HELLO_SENT;
00935             CYASSL_MSG("connect state: CLIENT_HELLO_SENT");
00936 
00937         case CLIENT_HELLO_SENT :
00938             neededState = ssl->options.resuming ? SERVER_FINISHED_COMPLETE :
00939                                           SERVER_HELLODONE_COMPLETE;
00940             #ifdef CYASSL_DTLS
00941                 if (ssl->options.dtls && !ssl->options.resuming)
00942                     neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
00943             #endif
00944             /* get response */
00945             while (ssl->options.serverState < neededState) {
00946                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
00947                     CYASSL_ERROR(ssl->error);
00948                     return SSL_FATAL_ERROR;
00949                 }
00950                 /* if resumption failed, reset needed state */
00951                 else if (neededState == SERVER_FINISHED_COMPLETE)
00952                     if (!ssl->options.resuming) {
00953                         if (!ssl->options.dtls)
00954                             neededState = SERVER_HELLODONE_COMPLETE;
00955                         else
00956                             neededState = SERVER_HELLOVERIFYREQUEST_COMPLETE;
00957                     }
00958             }
00959 
00960             ssl->options.connectState = HELLO_AGAIN;
00961             CYASSL_MSG("connect state: HELLO_AGAIN");
00962 
00963         case HELLO_AGAIN :
00964             #ifdef CYASSL_DTLS
00965                 if (ssl->options.dtls && !ssl->options.resuming) {
00966                     /* re-init hashes, exclude first hello and verify request */
00967                     InitMd5(&ssl->hashMd5);
00968                     InitSha(&ssl->hashSha);
00969                     if ( (ssl->error = SendClientHello(ssl)) != 0) {
00970                         CYASSL_ERROR(ssl->error);
00971                         return SSL_FATAL_ERROR;
00972                     }
00973                 }
00974             #endif
00975 
00976             ssl->options.connectState = HELLO_AGAIN_REPLY;
00977             CYASSL_MSG("connect state: HELLO_AGAIN_REPLY");
00978 
00979         case HELLO_AGAIN_REPLY :
00980             #ifdef CYASSL_DTLS
00981                 if (ssl->options.dtls) {
00982                     neededState = ssl->options.resuming ?
00983                            SERVER_FINISHED_COMPLETE : SERVER_HELLODONE_COMPLETE;
00984             
00985                     /* get response */
00986                     while (ssl->options.serverState < neededState) {
00987                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
00988                                 CYASSL_ERROR(ssl->error);
00989                                 return SSL_FATAL_ERROR;
00990                         }
00991                         /* if resumption failed, reset needed state */
00992                         else if (neededState == SERVER_FINISHED_COMPLETE)
00993                             if (!ssl->options.resuming)
00994                                 neededState = SERVER_HELLODONE_COMPLETE;
00995                     }
00996                 }
00997             #endif
00998 
00999             ssl->options.connectState = FIRST_REPLY_DONE;
01000             CYASSL_MSG("connect state: FIRST_REPLY_DONE");
01001 
01002         case FIRST_REPLY_DONE :
01003             if (ssl->options.sendVerify)
01004                 if ( (ssl->error = SendCertificate(ssl)) != 0) {
01005                     CYASSL_ERROR(ssl->error);
01006                     return SSL_FATAL_ERROR;
01007                 }
01008 
01009             ssl->options.connectState = FIRST_REPLY_FIRST;
01010             CYASSL_MSG("connect state: FIRST_REPLY_FIRST");
01011 
01012         case FIRST_REPLY_FIRST :
01013             if (!ssl->options.resuming)
01014                 if ( (ssl->error = SendClientKeyExchange(ssl)) != 0) {
01015                     CYASSL_ERROR(ssl->error);
01016                     return SSL_FATAL_ERROR;
01017                 }
01018 
01019             ssl->options.connectState = FIRST_REPLY_SECOND;
01020             CYASSL_MSG("connect state: FIRST_REPLY_SECOND");
01021 
01022         case FIRST_REPLY_SECOND :
01023             if (ssl->options.sendVerify)
01024                 if ( (ssl->error = SendCertificateVerify(ssl)) != 0) {
01025                     CYASSL_ERROR(ssl->error);
01026                     return SSL_FATAL_ERROR;
01027             }
01028             ssl->options.connectState = FIRST_REPLY_THIRD;
01029             CYASSL_MSG("connect state: FIRST_REPLY_THIRD");
01030 
01031         case FIRST_REPLY_THIRD :
01032             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
01033                 CYASSL_ERROR(ssl->error);
01034                 return SSL_FATAL_ERROR;
01035             }
01036             ssl->options.connectState = FIRST_REPLY_FOURTH;
01037             CYASSL_MSG("connect state: FIRST_REPLY_FOURTH");
01038 
01039         case FIRST_REPLY_FOURTH :
01040             if ( (ssl->error = SendFinished(ssl)) != 0) {
01041                 CYASSL_ERROR(ssl->error);
01042                 return SSL_FATAL_ERROR;
01043             }
01044 
01045             ssl->options.connectState = FINISHED_DONE;
01046             CYASSL_MSG("connect state: FINISHED_DONE");
01047 
01048         case FINISHED_DONE :
01049             /* get response */
01050             while (ssl->options.serverState < SERVER_FINISHED_COMPLETE)
01051                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
01052                     CYASSL_ERROR(ssl->error);
01053                     return SSL_FATAL_ERROR;
01054                 }
01055           
01056             ssl->options.connectState = SECOND_REPLY_DONE;
01057             CYASSL_MSG("connect state: SECOND_REPLY_DONE");
01058 
01059         case SECOND_REPLY_DONE:
01060             if (ssl->buffers.inputBuffer.dynamicFlag)
01061                 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
01062             CYASSL_LEAVE("SSL_connect()", SSL_SUCCESS);
01063             return SSL_SUCCESS;
01064 
01065         default:
01066             CYASSL_MSG("Unknown connect state ERROR");
01067             return SSL_FATAL_ERROR; /* unknown connect state */
01068         }
01069     }
01070 
01071 #endif /* NO_CYASSL_CLIENT */
01072 
01073 
01074 /* server only parts */
01075 #ifndef NO_CYASSL_SERVER
01076 
01077     SSL_METHOD* SSLv3_server_method(void)
01078     {
01079         SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0,
01080                                                    DYNAMIC_TYPE_METHOD);
01081         if (method) {
01082             InitSSL_Method(method, MakeSSLv3());
01083             method->side = SERVER_END;
01084         }
01085         return method;
01086     }
01087 
01088 
01089     #ifdef CYASSL_DTLS
01090         SSL_METHOD* DTLSv1_server_method(void)
01091         {
01092             SSL_METHOD* method = (SSL_METHOD*) XMALLOC(sizeof(SSL_METHOD), 0,
01093                                                        DYNAMIC_TYPE_METHOD);
01094             if (method) {
01095                 InitSSL_Method(method, MakeDTLSv1());
01096                 method->side = SERVER_END;
01097             }
01098             return method;
01099         }
01100     #endif
01101 
01102 
01103     int SSL_accept(SSL* ssl)
01104     {
01105         CYASSL_ENTER("SSL_accept()");
01106 
01107         #ifdef HAVE_ERRNO_H 
01108             errno = 0;
01109         #endif
01110 
01111         if (ssl->options.side != SERVER_END) {
01112             CYASSL_ERROR(ssl->error = SIDE_ERROR);
01113             return SSL_FATAL_ERROR;
01114         }
01115 
01116         #ifdef CYASSL_DTLS
01117             if (ssl->version.major == DTLS_MAJOR &&
01118                                       ssl->version.minor == DTLS_MINOR) {
01119                 ssl->options.dtls   = 1;
01120                 ssl->options.tls    = 1;
01121                 ssl->options.tls1_1 = 1;
01122             }
01123         #endif
01124 
01125         if (ssl->buffers.outputBuffer.length > 0) {
01126             if ( (ssl->error = SendBuffered(ssl)) == 0) {
01127                 ssl->options.acceptState++;
01128                 CYASSL_MSG("accept state: Advanced from buffered send");
01129             }
01130             else {
01131                 CYASSL_ERROR(ssl->error);
01132                 return SSL_FATAL_ERROR;
01133             }
01134         }
01135 
01136         switch (ssl->options.acceptState) {
01137     
01138         case ACCEPT_BEGIN :
01139             /* get response */
01140             while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
01141                 if ( (ssl->error = ProcessReply(ssl)) < 0) {
01142                     CYASSL_ERROR(ssl->error);
01143                     return SSL_FATAL_ERROR;
01144                 }
01145             ssl->options.acceptState = ACCEPT_CLIENT_HELLO_DONE;
01146             CYASSL_MSG("accept state ACCEPT_CLIENT_HELLO_DONE");
01147 
01148         case ACCEPT_CLIENT_HELLO_DONE :
01149             #ifdef CYASSL_DTLS
01150                 if (ssl->options.dtls && !ssl->options.resuming)
01151                     if ( (ssl->error = SendHelloVerifyRequest(ssl)) != 0) {
01152                         CYASSL_ERROR(ssl->error);
01153                         return SSL_FATAL_ERROR;
01154                     }
01155             #endif
01156             ssl->options.acceptState = HELLO_VERIFY_SENT;
01157             CYASSL_MSG("accept state HELLO_VERIFY_SENT");
01158 
01159         case HELLO_VERIFY_SENT:
01160             #ifdef CYASSL_DTLS
01161                 if (ssl->options.dtls && !ssl->options.resuming) {
01162                     ssl->options.clientState = NULL_STATE;  /* get again */
01163                     /* re-init hashes, exclude first hello and verify request */
01164                     InitMd5(&ssl->hashMd5);
01165                     InitSha(&ssl->hashSha);
01166 
01167                     while (ssl->options.clientState < CLIENT_HELLO_COMPLETE)
01168                         if ( (ssl->error = ProcessReply(ssl)) < 0) {
01169                             CYASSL_ERROR(ssl->error);
01170                             return SSL_FATAL_ERROR;
01171                         }
01172                 }
01173             #endif
01174             ssl->options.acceptState = ACCEPT_FIRST_REPLY_DONE;
01175             CYASSL_MSG("accept state ACCEPT_FIRST_REPLY_DONE");
01176 
01177         case ACCEPT_FIRST_REPLY_DONE :
01178             if ( (ssl->error = SendServerHello(ssl)) != 0) {
01179                 CYASSL_ERROR(ssl->error);
01180                 return SSL_FATAL_ERROR;
01181             }
01182             ssl->options.acceptState = SERVER_HELLO_SENT;
01183             CYASSL_MSG("accept state SERVER_HELLO_SENT");
01184 
01185         case SERVER_HELLO_SENT :
01186             if (!ssl->options.resuming) 
01187                 if ( (ssl->error = SendCertificate(ssl)) != 0) {
01188                     CYASSL_ERROR(ssl->error);
01189                     return SSL_FATAL_ERROR;
01190                 }
01191             ssl->options.acceptState = CERT_SENT;
01192             CYASSL_MSG("accept state CERT_SENT");
01193 
01194         case CERT_SENT :
01195             if (!ssl->options.resuming) 
01196                 if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
01197                     CYASSL_ERROR(ssl->error);
01198                     return SSL_FATAL_ERROR;
01199                 }
01200             ssl->options.acceptState = KEY_EXCHANGE_SENT;
01201             CYASSL_MSG("accept state KEY_EXCHANGE_SENT");
01202 
01203         case KEY_EXCHANGE_SENT :
01204             if (!ssl->options.resuming) 
01205                 if (ssl->options.verifyPeer)
01206                     if ( (ssl->error = SendCertificateRequest(ssl)) != 0) {
01207                         CYASSL_ERROR(ssl->error);
01208                         return SSL_FATAL_ERROR;
01209                     }
01210             ssl->options.acceptState = CERT_REQ_SENT;
01211             CYASSL_MSG("accept state CERT_REQ_SENT");
01212 
01213         case CERT_REQ_SENT :
01214             if (!ssl->options.resuming) 
01215                 if ( (ssl->error = SendServerHelloDone(ssl)) != 0) {
01216                     CYASSL_ERROR(ssl->error);
01217                     return SSL_FATAL_ERROR;
01218                 }
01219             ssl->options.acceptState = SERVER_HELLO_DONE;
01220             CYASSL_MSG("accept state SERVER_HELLO_DONE");
01221 
01222         case SERVER_HELLO_DONE :
01223             if (!ssl->options.resuming) {
01224                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
01225                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
01226                         CYASSL_ERROR(ssl->error);
01227                         return SSL_FATAL_ERROR;
01228                     }
01229             }
01230             ssl->options.acceptState = ACCEPT_SECOND_REPLY_DONE;
01231             CYASSL_MSG("accept state  ACCEPT_SECOND_REPLY_DONE");
01232           
01233         case ACCEPT_SECOND_REPLY_DONE : 
01234             if ( (ssl->error = SendChangeCipher(ssl)) != 0) {
01235                 CYASSL_ERROR(ssl->error);
01236                 return SSL_FATAL_ERROR;
01237             }
01238             ssl->options.acceptState = CHANGE_CIPHER_SENT;
01239             CYASSL_MSG("accept state  CHANGE_CIPHER_SENT");
01240 
01241         case CHANGE_CIPHER_SENT : 
01242             if ( (ssl->error = SendFinished(ssl)) != 0) {
01243                 CYASSL_ERROR(ssl->error);
01244                 return SSL_FATAL_ERROR;
01245             }
01246 
01247             ssl->options.acceptState = ACCEPT_FINISHED_DONE;
01248             CYASSL_MSG("accept state ACCEPT_FINISHED_DONE");
01249 
01250         case ACCEPT_FINISHED_DONE :
01251             if (ssl->options.resuming)
01252                 while (ssl->options.clientState < CLIENT_FINISHED_COMPLETE)
01253                     if ( (ssl->error = ProcessReply(ssl)) < 0) {
01254                         CYASSL_ERROR(ssl->error);
01255                         return SSL_FATAL_ERROR;
01256                     }
01257 
01258             ssl->options.acceptState = ACCEPT_THIRD_REPLY_DONE;
01259             CYASSL_MSG("accept state ACCEPT_THIRD_REPLY_DONE");
01260 
01261         case ACCEPT_THIRD_REPLY_DONE :
01262             if (ssl->buffers.inputBuffer.dynamicFlag)
01263                 ShrinkInputBuffer(ssl, NO_FORCED_FREE);
01264             CYASSL_LEAVE("SSL_accept()", SSL_SUCCESS);
01265             return SSL_SUCCESS;
01266 
01267         default :
01268             CYASSL_MSG("Unknown accept state ERROR");
01269             return SSL_FATAL_ERROR;
01270         }
01271     }
01272 
01273 #endif /* NO_CYASSL_SERVER */
01274 
01275 
01276 int InitCyaSSL(void)
01277 {
01278     if (InitMutex(&mutex) == 0)
01279         return 0;
01280     else
01281         return -1;
01282 }
01283 
01284 
01285 int FreeCyaSSL(void)
01286 {
01287     if (FreeMutex(&mutex) == 0)
01288         return 0;
01289     else
01290         return -1;
01291 }
01292 
01293 
01294 #ifndef NO_SESSION_CACHE
01295 
01296 
01297 static INLINE word32 HashSession(const byte* sessionID)
01298 {
01299     /* id is random, just make 32 bit number from first 4 bytes for now */
01300     return (sessionID[0] << 24) | (sessionID[1] << 16) | (sessionID[2] <<  8) |
01301             sessionID[3];
01302 }
01303 
01304 
01305 void SSL_flush_sessions(SSL_CTX* ctx, long tm)
01306 {
01307     /* static table now, no flusing needed */
01308 }
01309 
01310 
01311 SSL_SESSION* GetSession(SSL* ssl, byte* masterSecret)
01312 {
01313     SSL_SESSION* ret = 0;
01314     const byte*  id = ssl->arrays.sessionID;
01315     word32       row;
01316     int          idx;
01317     
01318     if (ssl->options.sessionCacheOff)
01319         return 0;
01320 
01321     row = HashSession(id) % SESSION_ROWS;
01322 
01323     if (LockMutex(&mutex) != 0)
01324         return 0;
01325    
01326     if (SessionCache[row].totalCount >= SESSIONS_PER_ROW)
01327         idx = SESSIONS_PER_ROW - 1;
01328     else
01329         idx = SessionCache[row].nextIdx - 1;
01330 
01331     for (; idx >= 0; idx--) {
01332         SSL_SESSION* current;
01333         
01334         if (idx >= SESSIONS_PER_ROW)    /* server could have restarted, idx  */
01335             break;                      /* would be word32(-1) and seg fault */
01336         
01337         current = &SessionCache[row].Sessions[idx];
01338         if (XMEMCMP(current->sessionID, id, ID_LEN) == 0) {
01339             if (LowResTimer() < (current->bornOn + current->timeout)) {
01340                 ret = current;
01341                 if (masterSecret)
01342                     XMEMCPY(masterSecret, current->masterSecret, SECRET_LEN);
01343             }
01344             break;
01345         }   
01346     }
01347 
01348     UnLockMutex(&mutex);
01349     
01350     return ret;
01351 }
01352 
01353 
01354 int SetSession(SSL* ssl, SSL_SESSION* session)
01355 {
01356     if (ssl->options.sessionCacheOff)
01357         return SSL_FAILURE;
01358 
01359     if (LowResTimer() < (session->bornOn + session->timeout)) {
01360         ssl->session  = *session;
01361         ssl->options.resuming = 1;
01362 
01363 #ifdef SESSION_CERTS
01364         ssl->version             = session->version;
01365         ssl->options.cipherSuite = session->cipherSuite;
01366 #endif
01367 
01368         return SSL_SUCCESS;
01369     }
01370     return SSL_FAILURE;  /* session timed out */
01371 }
01372 
01373 
01374 int AddSession(SSL* ssl)
01375 {
01376     word32 row, idx;
01377 
01378     if (ssl->options.sessionCacheOff)
01379         return 0;
01380 
01381     row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS;
01382 
01383     if (LockMutex(&mutex) != 0)
01384         return -1;
01385 
01386     idx = SessionCache[row].nextIdx++;
01387 
01388     XMEMCPY(SessionCache[row].Sessions[idx].masterSecret,
01389            ssl->arrays.masterSecret, SECRET_LEN);
01390     XMEMCPY(SessionCache[row].Sessions[idx].sessionID, ssl->arrays.sessionID,
01391            ID_LEN);
01392 
01393     SessionCache[row].Sessions[idx].timeout = DEFAULT_TIMEOUT;
01394     SessionCache[row].Sessions[idx].bornOn  = LowResTimer();
01395 
01396 #ifdef SESSION_CERTS
01397     SessionCache[row].Sessions[idx].chain.count = ssl->session.chain.count;
01398     XMEMCPY(SessionCache[row].Sessions[idx].chain.certs,
01399            ssl->session.chain.certs, sizeof(x509_buffer) * MAX_CHAIN_DEPTH);
01400 
01401     SessionCache[row].Sessions[idx].version     = ssl->version;
01402     SessionCache[row].Sessions[idx].cipherSuite = ssl->options.cipherSuite;
01403 #endif
01404 
01405     SessionCache[row].totalCount++;
01406     if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
01407         SessionCache[row].nextIdx = 0;
01408 
01409     if (UnLockMutex(&mutex) != 0)
01410         return -1;
01411 
01412     return 0;
01413 }
01414 
01415 
01416     #ifdef SESSION_STATS
01417 
01418     void PrintSessionStats(void)
01419     {
01420         word32 totalSessionsSeen = 0;
01421         word32 totalSessionsNow = 0;
01422         word32 rowNow;
01423         int    i;
01424         double E;               /* expected freq */
01425         double chiSquare = 0;
01426         
01427         for (i = 0; i < SESSION_ROWS; i++) {
01428             totalSessionsSeen += SessionCache[i].totalCount;
01429 
01430             if (SessionCache[i].totalCount >= SESSIONS_PER_ROW)
01431                 rowNow = SESSIONS_PER_ROW;
01432             else if (SessionCache[i].nextIdx == 0)
01433                 rowNow = 0;
01434             else
01435                 rowNow = SessionCache[i].nextIdx;
01436         
01437             totalSessionsNow += rowNow;
01438         }
01439 
01440         printf("Total Sessions Seen = %d\n", totalSessionsSeen);
01441         printf("Total Sessions Now  = %d\n", totalSessionsNow);
01442 
01443         E = (double)totalSessionsSeen / SESSION_ROWS;
01444 
01445         for (i = 0; i < SESSION_ROWS; i++) {
01446             double diff = SessionCache[i].totalCount - E;
01447             diff *= diff;                /* sqaure    */
01448             diff /= E;                   /* normalize */
01449 
01450             chiSquare += diff;
01451         }
01452         printf("  chi-square = %5.1f, d.f. = %d\n", chiSquare,
01453                                                      SESSION_ROWS - 1);
01454         if (SESSION_ROWS == 11)
01455             printf(" .05 p value =  18.3, chi-square should be less\n");
01456         else if (SESSION_ROWS == 211)
01457             printf(".05 p value  = 244.8, chi-square should be less\n");
01458         else if (SESSION_ROWS == 5981)
01459             printf(".05 p value  = 6161.0, chi-square should be less\n");
01460         printf("\n");
01461     }
01462 
01463     #endif /* SESSION_STATS */
01464 
01465 #endif /* NO_SESSION_CACHE */
01466 
01467 
01468 /* call before SSL_connect, if verifying will add name check to
01469    date check and signature check */
01470 int CyaSSL_check_domain_name(SSL* ssl, const char* dn)
01471 {
01472     if (ssl->buffers.domainName.buffer)
01473         XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN);
01474 
01475     ssl->buffers.domainName.length = (word32)XSTRLEN(dn) + 1;
01476     ssl->buffers.domainName.buffer = (byte*) XMALLOC(
01477                 ssl->buffers.domainName.length, ssl->heap, DYNAMIC_TYPE_DOMAIN);
01478 
01479     if (ssl->buffers.domainName.buffer) {
01480         XSTRNCPY((char*)ssl->buffers.domainName.buffer, dn,
01481                 ssl->buffers.domainName.length);
01482         return SSL_SUCCESS;
01483     }
01484     else {
01485         ssl->error = MEMORY_ERROR;
01486         return SSL_FAILURE;
01487     }
01488 }
01489 
01490 
01491 /* turn on CyaSSL zlib compression
01492    returns 0 for success, else error (not built in)
01493 */
01494 int CyaSSL_set_compression(SSL* ssl)
01495 {
01496 #ifdef HAVE_LIBZ
01497     ssl->options.usingCompression = 1;
01498     return 0;
01499 #else
01500     return -1;
01501 #endif
01502 }
01503 
01504 
01505 #ifndef USE_WINDOWS_API 
01506     #ifndef NO_WRITEV
01507 
01508         /* simulate writev semantics, doesn't actually do block at a time though
01509            because of SSL_write behavior and because front adds may be small */
01510         int CyaSSL_writev(SSL* ssl, const struct iovec* iov, int iovcnt)
01511         {
01512             byte  tmp[OUTPUT_RECORD_SIZE];
01513             byte* buffer    = tmp;
01514             int   send      = 0;
01515             int   newBuffer = 0;
01516             int   idx       = 0;
01517             int   i;
01518             int   ret;
01519 
01520             for (i = 0; i < iovcnt; i++)
01521                 send += iov[i].iov_len;
01522 
01523             if (send > sizeof(tmp)) {
01524                 byte* tmp2 = (byte*) XMALLOC(send, ssl->heap,
01525                                              DYNAMIC_TYPE_WRITEV);
01526                 if (!tmp2)
01527                     return MEMORY_ERROR;
01528                 buffer = tmp2;
01529                 newBuffer = 1;
01530             }
01531 
01532             for (i = 0; i < iovcnt; i++) {
01533                 XMEMCPY(&buffer[idx], iov[i].iov_base, iov[i].iov_len);
01534                 idx += iov[i].iov_len;
01535             }
01536 
01537             ret = SSL_write(ssl, buffer, send);
01538 
01539             if (newBuffer) XFREE(buffer, ssl->heap, DYNAMIC_TYPE_WRITEV);
01540 
01541             return ret;
01542         }
01543     #endif
01544 #endif
01545 
01546 
01547 #ifdef CYASSL_CALLBACKS
01548 
01549     typedef struct itimerval Itimerval;
01550 
01551     /* don't keep calling simple functions while setting up timer and singals
01552        if no inlining these are the next best */
01553 
01554     #define AddTimes(a, b, c)                       \
01555         do {                                        \
01556             c.tv_sec  = a.tv_sec  + b.tv_sec;       \
01557             c.tv_usec = a.tv_usec + b.tv_usec;      \
01558             if (c.tv_sec >=  1000000) {             \
01559                 c.tv_sec++;                         \
01560                 c.tv_usec -= 1000000;               \
01561             }                                       \
01562         } while (0)
01563 
01564 
01565     #define SubtractTimes(a, b, c)                  \
01566         do {                                        \
01567             c.tv_sec  = a.tv_sec  - b.tv_sec;       \
01568             c.tv_usec = a.tv_usec - b.tv_usec;      \
01569             if (c.tv_sec < 0) {                     \
01570                 c.tv_sec--;                         \
01571                 c.tv_usec += 1000000;               \
01572             }                                       \
01573         } while (0)
01574 
01575     #define CmpTimes(a, b, cmp)                     \
01576         ((a.tv_sec  ==  b.tv_sec) ?                 \
01577             (a.tv_usec cmp b.tv_usec) :             \
01578             (a.tv_sec  cmp b.tv_sec))               \
01579 
01580 
01581     /* do nothing handler */
01582     static void myHandler(int signo)
01583     {
01584         return;
01585     }
01586 
01587 
01588     static int CyaSSL_ex_wrapper(SSL* ssl, HandShakeCallBack hsCb,
01589                                  TimeoutCallBack toCb, Timeval timeout)
01590     {
01591         int       ret        = -1;
01592         int       oldTimerOn = 0;   /* was timer already on */
01593         Timeval   startTime;
01594         Timeval   endTime;
01595         Timeval   totalTime;
01596         Itimerval myTimeout;
01597         Itimerval oldTimeout; /* if old timer adjust from total time to reset */
01598         struct sigaction act, oact;
01599        
01600         #define ERR_OUT(x) { ssl->hsInfoOn = 0; ssl->toInfoOn = 0; return x; }
01601 
01602         if (hsCb) {
01603             ssl->hsInfoOn = 1;
01604             InitHandShakeInfo(&ssl->handShakeInfo);
01605         }
01606         if (toCb) {
01607             ssl->toInfoOn = 1;
01608             InitTimeoutInfo(&ssl->timeoutInfo);
01609             
01610             if (gettimeofday(&startTime, 0) < 0)
01611                 ERR_OUT(GETTIME_ERROR);
01612 
01613             /* use setitimer to simulate getitimer, init 0 myTimeout */
01614             myTimeout.it_interval.tv_sec  = 0;
01615             myTimeout.it_interval.tv_usec = 0;
01616             myTimeout.it_value.tv_sec     = 0;
01617             myTimeout.it_value.tv_usec    = 0;
01618             if (setitimer(ITIMER_REAL, &myTimeout, &oldTimeout) < 0)
01619                 ERR_OUT(SETITIMER_ERROR);
01620 
01621             if (oldTimeout.it_value.tv_sec || oldTimeout.it_value.tv_usec) {
01622                 oldTimerOn = 1;
01623                 
01624                 /* is old timer going to expire before ours */
01625                 if (CmpTimes(oldTimeout.it_value, timeout, <)) { 
01626                     timeout.tv_sec  = oldTimeout.it_value.tv_sec;
01627                     timeout.tv_usec = oldTimeout.it_value.tv_usec;
01628                 }       
01629             }
01630             myTimeout.it_value.tv_sec  = timeout.tv_sec;
01631             myTimeout.it_value.tv_usec = timeout.tv_usec;
01632             
01633             /* set up signal handler, don't restart socket send/recv */
01634             act.sa_handler = myHandler;
01635             sigemptyset(&act.sa_mask);
01636             act.sa_flags = 0;
01637 #ifdef SA_INTERRUPT
01638             act.sa_flags |= SA_INTERRUPT;
01639 #endif
01640             if (sigaction(SIGALRM, &act, &oact) < 0)
01641                 ERR_OUT(SIGACT_ERROR);
01642 
01643             if (setitimer(ITIMER_REAL, &myTimeout, 0) < 0)
01644                 ERR_OUT(SETITIMER_ERROR);
01645         }
01646 
01647         /* do main work */
01648 #ifndef NO_CYASSL_CLIENT
01649         if (ssl->options.side == CLIENT_END)
01650             ret = SSL_connect(ssl);
01651 #endif
01652 #ifndef NO_CYASSL_SERVER
01653         if (ssl->options.side == SERVER_END)
01654             ret = SSL_accept(ssl);
01655 #endif
01656        
01657         /* do callbacks */ 
01658         if (toCb) {
01659             if (oldTimerOn) {
01660                 gettimeofday(&endTime, 0);
01661                 SubtractTimes(endTime, startTime, totalTime);
01662                 /* adjust old timer for elapsed time */
01663                 if (CmpTimes(totalTime, oldTimeout.it_value, <))
01664                     SubtractTimes(oldTimeout.it_value, totalTime,
01665                                   oldTimeout.it_value);
01666                 else {
01667                     /* reset value to interval, may be off */
01668                     oldTimeout.it_value.tv_sec = oldTimeout.it_interval.tv_sec;
01669                     oldTimeout.it_value.tv_usec =oldTimeout.it_interval.tv_usec;
01670                 }
01671                 /* keep iter the same whether there or not */
01672             }
01673             /* restore old handler */
01674             if (sigaction(SIGALRM, &oact, 0) < 0)
01675                 ret = SIGACT_ERROR;    /* more pressing error, stomp */
01676             else
01677                 /* use old settings which may turn off (expired or not there) */
01678                 if (setitimer(ITIMER_REAL, &oldTimeout, 0) < 0)
01679                     ret = SETITIMER_ERROR;
01680             
01681             /* if we had a timeout call callback */
01682             if (ssl->timeoutInfo.timeoutName[0]) {
01683                 ssl->timeoutInfo.timeoutValue.tv_sec  = timeout.tv_sec;
01684                 ssl->timeoutInfo.timeoutValue.tv_usec = timeout.tv_usec;
01685                 (toCb)(&ssl->timeoutInfo);
01686             }
01687             /* clean up */
01688             FreeTimeoutInfo(&ssl->timeoutInfo, ssl->heap);
01689             ssl->toInfoOn = 0;
01690         }
01691         if (hsCb) {
01692             FinishHandShakeInfo(&ssl->handShakeInfo, ssl);
01693             (hsCb)(&ssl->handShakeInfo);
01694             ssl->hsInfoOn = 0;
01695         }
01696         return ret;
01697     }
01698 
01699 
01700 #ifndef NO_CYASSL_CLIENT
01701 
01702     int CyaSSL_connect_ex(SSL* ssl, HandShakeCallBack hsCb,
01703                           TimeoutCallBack toCb, Timeval timeout)
01704     {
01705         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
01706     }
01707 
01708 #endif
01709 
01710 
01711 #ifndef NO_CYASSL_SERVER
01712 
01713     int CyaSSL_accept_ex(SSL* ssl, HandShakeCallBack hsCb,
01714                          TimeoutCallBack toCb,Timeval timeout)
01715     {
01716         return CyaSSL_ex_wrapper(ssl, hsCb, toCb, timeout);
01717     }
01718 
01719 #endif
01720 
01721 #endif /* CYASSL_CALLBACKS */
01722 
01723 
01724 #ifndef NO_PSK
01725 
01726     void SSL_CTX_set_psk_client_callback(SSL_CTX* ctx, psk_client_callback cb)
01727     {
01728         ctx->havePSK = 1;
01729         ctx->client_psk_cb = cb;
01730     }
01731 
01732 
01733     void SSL_set_psk_client_callback(SSL* ssl, psk_client_callback cb)
01734     {
01735         ssl->options.havePSK = 1;
01736         ssl->options.client_psk_cb = cb;
01737 
01738         InitSuites(&ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU);
01739     }
01740 
01741 
01742     void SSL_CTX_set_psk_server_callback(SSL_CTX* ctx, psk_server_callback cb)
01743     {
01744         ctx->havePSK = 1;
01745         ctx->server_psk_cb = cb;
01746     }
01747 
01748 
01749     void SSL_set_psk_server_callback(SSL* ssl, psk_server_callback cb)
01750     {
01751         ssl->options.havePSK = 1;
01752         ssl->options.server_psk_cb = cb;
01753 
01754         InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, TRUE,
01755                    ssl->options.haveNTRU);
01756     }
01757 
01758 
01759     const char* SSL_get_psk_identity_hint(const SSL* ssl)
01760     {
01761         return ssl->arrays.server_hint;
01762     }
01763 
01764 
01765     const char* SSL_get_psk_identity(const SSL* ssl)
01766     {
01767         return ssl->arrays.client_identity;
01768     }
01769 
01770 
01771     int SSL_CTX_use_psk_identity_hint(SSL_CTX* ctx, const char* hint)
01772     {
01773         if (hint == 0)
01774             ctx->server_hint[0] = 0;
01775         else
01776             XSTRNCPY(ctx->server_hint, hint, MAX_PSK_ID_LEN);
01777         return SSL_SUCCESS;
01778     }
01779 
01780 
01781     int SSL_use_psk_identity_hint(SSL* ssl, const char* hint)
01782     {
01783         if (hint == 0)
01784             ssl->arrays.server_hint[0] = 0;
01785         else
01786             XSTRNCPY(ssl->arrays.server_hint, hint, MAX_PSK_ID_LEN);
01787         return SSL_SUCCESS;
01788     }
01789 
01790 #endif /* NO_PSK */
01791 
01792 
01793 #if defined(NO_FILESYSTEM) || defined(MICRIUM)
01794 
01795     /* CyaSSL extension allows DER files to be loaded from buffers as well */
01796     int CyaSSL_CTX_load_verify_buffer(SSL_CTX* ctx, const unsigned char* buffer,
01797                                       long sz, int format)
01798     {
01799         return ProcessBuffer(ctx, buffer, sz, format, CA_TYPE);
01800     }
01801 
01802 
01803     int CyaSSL_CTX_use_certificate_buffer(SSL_CTX* ctx,
01804                                  const unsigned char* buffer,long sz,int format)
01805     {
01806         return ProcessBuffer(ctx, buffer, sz, format, CERT_TYPE);
01807     }
01808 
01809 
01810     int CyaSSL_CTX_use_PrivateKey_buffer(SSL_CTX* ctx,
01811                                  const unsigned char* buffer,long sz,int format)
01812     {
01813         return ProcessBuffer(ctx, buffer, sz, format, PRIVATEKEY_TYPE);
01814     }
01815 
01816 
01817     int CyaSSL_CTX_use_certificate_chain_buffer(SSL_CTX* ctx,
01818                                  const unsigned char* buffer, long sz)
01819     {
01820         /* add first to ctx, all tested implementations support this */
01821         return ProcessBuffer(ctx, buffer, sz, SSL_FILETYPE_PEM, CA_TYPE);
01822     }
01823 
01824 #endif /* NO_FILESYSTEM || MICRIUM */
01825 
01826 
01827 #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
01828 
01829 
01830     int SSLeay_add_ssl_algorithms(void)
01831     {
01832         OpenSSL_add_all_algorithms(); 
01833         return SSL_SUCCESS;
01834     }
01835 
01836 
01837     long SSL_CTX_sess_set_cache_size(SSL_CTX* ctx, long sz)
01838     {
01839         /* cache size fixed at compile time in CyaSSL */
01840         return 0;
01841     }
01842 
01843 
01844     void SSL_CTX_set_quiet_shutdown(SSL_CTX* ctx, int mode)
01845     {
01846         if (mode)
01847             ctx->quietShutdown = 1;
01848     }
01849 
01850 
01851     int SSL_CTX_check_private_key(SSL_CTX* ctx)
01852     {
01853         /* TODO: check private against public for RSA match */
01854         return SSL_SUCCESS;
01855     }
01856 
01857 
01858     void SSL_set_bio(SSL* ssl, BIO* rd, BIO* wr)
01859     {
01860         SSL_set_rfd(ssl, rd->fd);
01861         SSL_set_wfd(ssl, wr->fd);
01862 
01863         ssl->biord = rd;
01864         ssl->biowr = wr;
01865     }
01866 
01867 
01868     void SSL_CTX_set_client_CA_list(SSL_CTX* ctx, STACK_OF(X509_NAME)* names)
01869     {
01870    
01871     }
01872 
01873 
01874     STACK_OF(X509_NAME)* SSL_load_client_CA_file(const char* fname)
01875     {
01876         return 0;
01877     }
01878 
01879 
01880     int SSL_CTX_set_default_verify_paths(SSL_CTX* ctx)
01881     {
01882         /* TODO:, not needed in goahead */
01883         return SSL_NOT_IMPLEMENTED;
01884     }
01885 
01886 
01887     void SSL_set_accept_state(SSL* ssl)
01888     {
01889         byte havePSK = 0;
01890 
01891         ssl->options.side = SERVER_END;
01892         /* reset suites in case user switched */
01893 #ifndef NO_PSK
01894         havePSK = ssl->options.havePSK;
01895 #endif
01896         InitSuites(&ssl->suites, ssl->version, ssl->options.haveDH, havePSK,
01897                    ssl->options.haveNTRU);
01898     }
01899 
01900 
01901     void OpenSSL_add_all_algorithms(void)
01902     {
01903         InitCyaSSL(); 
01904     }
01905 
01906 
01907     int SSLeay_add_all_algorithms(void)
01908     {
01909         OpenSSL_add_all_algorithms(); 
01910         return SSL_SUCCESS;
01911     }
01912 
01913     
01914     void SSL_CTX_set_tmp_rsa_callback(SSL_CTX* ctx, RSA*(*f)(SSL*, int, int))
01915     {
01916         /* CyaSSL verifies all these internally */   
01917     }
01918 
01919 
01920     void SSL_set_shutdown(SSL* ssl, int opt)
01921     {
01922        
01923     }
01924 
01925 
01926     long SSL_CTX_set_options(SSL_CTX* ctx, long opt)
01927     {
01928         /* goahead calls with 0, do nothing */ 
01929         return opt;
01930     }
01931 
01932 
01933     int SSL_set_rfd(SSL* ssl, int rfd)
01934     {
01935         ssl->rfd = rfd;      /* not used directly to allow IO callbacks */
01936 
01937         ssl->IOCB_ReadCtx  = &ssl->rfd;
01938 
01939         return SSL_SUCCESS;
01940     }
01941 
01942 
01943     int SSL_set_wfd(SSL* ssl, int wfd)
01944     {
01945         ssl->wfd = wfd;      /* not used directly to allow IO callbacks */
01946 
01947         ssl->IOCB_WriteCtx  = &ssl->wfd;
01948 
01949         return SSL_SUCCESS;
01950     }
01951 
01952 
01953     RSA* RSA_generate_key(int len, unsigned long bits, void(*f)(int,
01954                                                         int, void*), void* data)
01955     {
01956         /* no tmp key needed, actual generation not supported */
01957         return 0;
01958     }
01959 
01960 
01961     X509_NAME* X509_get_issuer_name(X509* cert)
01962     {
01963         return &cert->issuer;
01964     }
01965 
01966 
01967     X509_NAME* X509_get_subject_name(X509* cert)
01968     {
01969         return &cert->subject;
01970     }
01971 
01972 
01973     /* copy name into buffer, at most sz bytes, if buffer is null will
01974        malloc buffer, call responsible for freeing                     */
01975     char* X509_NAME_oneline(X509_NAME* name, char* buffer, int sz)
01976     {
01977         int copySz = min(sz, name->sz);
01978         if (!name->sz) return buffer;
01979 
01980         if (!buffer) {
01981             buffer = (char*)XMALLOC(name->sz, 0, DYNAMIC_TYPE_OPENSSL);
01982             if (!buffer) return buffer;
01983             copySz = name->sz;
01984         }
01985 
01986         if (copySz == 0)
01987             return buffer;
01988 
01989         XMEMCPY(buffer, name->name, copySz - 1);
01990         buffer[copySz - 1] = 0;
01991 
01992         return buffer;
01993     }
01994 
01995 
01996     X509* X509_STORE_CTX_get_current_cert(X509_STORE_CTX* ctx)
01997     {
01998         return 0;
01999     }
02000 
02001 
02002     int X509_STORE_CTX_get_error(X509_STORE_CTX* ctx)
02003     {
02004         return 0;
02005     }
02006 
02007 
02008     int X509_STORE_CTX_get_error_depth(X509_STORE_CTX* ctx)
02009     {
02010         return 0;
02011     }
02012 
02013 
02014     BIO_METHOD* BIO_f_buffer(void)
02015     {
02016         static BIO_METHOD meth;
02017         meth.type = BIO_BUFFER;
02018 
02019         return &meth;
02020     }
02021 
02022 
02023     long BIO_set_write_buffer_size(BIO* bio, long size)
02024     {
02025         /* CyaSSL has internal buffer, compatibility only */
02026         return size; 
02027     }
02028 
02029 
02030     BIO_METHOD* BIO_f_ssl(void)
02031     {
02032         static BIO_METHOD meth;
02033         meth.type = BIO_SSL;
02034 
02035         return &meth;
02036     }
02037 
02038 
02039     BIO* BIO_new_socket(int sfd, int close)
02040     {
02041         BIO* bio = (BIO*) XMALLOC(sizeof(BIO), 0, DYNAMIC_TYPE_OPENSSL);
02042         if (bio) { 
02043             bio->type  = BIO_SOCKET;
02044             bio->close = close;
02045             bio->eof   = 0;
02046             bio->ssl   = 0;
02047             bio->fd    = sfd;
02048             bio->prev  = 0;
02049             bio->next  = 0;
02050         }
02051         return bio; 
02052     }
02053 
02054 
02055     int BIO_eof(BIO* b)
02056     {
02057         if (b->eof)
02058             return 1;
02059 
02060         return 0;        
02061     }
02062 
02063 
02064     long BIO_set_ssl(BIO* b, SSL* ssl, int close)
02065     {
02066         b->ssl   = ssl;
02067         b->close = close;
02068     /* add to ssl for bio free if SSL_free called before/instead of free_all? */
02069 
02070         return 0;
02071     }
02072 
02073 
02074     BIO* BIO_new(BIO_METHOD* method)
02075     {
02076         BIO* bio = (BIO*) XMALLOC(sizeof(BIO), 0, DYNAMIC_TYPE_OPENSSL);
02077         if (bio) {
02078             bio->type  = method->type;
02079             bio->close = 0;
02080             bio->eof   = 0;
02081             bio->ssl   = 0;
02082             bio->fd    = 0;
02083             bio->prev  = 0;
02084             bio->next  = 0;
02085         }
02086         return bio;
02087     }
02088 
02089 
02090 #ifdef USE_WINDOWS_API 
02091     #define CloseSocket(s) closesocket(s)
02092 #else
02093     #define CloseSocket(s) close(s)
02094 #endif
02095 
02096     int BIO_free(BIO* bio)
02097     {
02098         /* unchain?, doesn't matter in goahead since from free all */
02099         if (bio) {
02100             if (bio->close) {
02101                 if (bio->ssl)
02102                     SSL_free(bio->ssl);
02103                 if (bio->fd)
02104                     CloseSocket(bio->fd);
02105             }
02106             XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL);
02107         }
02108         return 0;
02109     }
02110 
02111 
02112     int BIO_free_all(BIO* bio)
02113     {
02114         BIO* next = bio;
02115 
02116         while ( (bio = next) ) {
02117             next = bio->next;
02118             BIO_free(bio);
02119         }
02120         return 0;
02121     }
02122 
02123 
02124     int BIO_read(BIO* bio, void* buf, int len)
02125     {
02126         int  ret;
02127         SSL* ssl = 0;
02128         BIO* front = bio;
02129 
02130         /* already got eof, again is error */
02131         if (front->eof)
02132             return -1;
02133 
02134         while(bio && ((ssl = bio->ssl) == 0) )
02135             bio = bio->next;
02136 
02137         if (ssl == 0) return -1;
02138 
02139         ret = SSL_read(ssl, buf, len);
02140         if (ret == 0)
02141             front->eof = 1;
02142         else if (ret < 0) {
02143             int err = SSL_get_error(ssl, 0);
02144             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
02145                 front->eof = 1;
02146         }
02147         return ret;
02148     }
02149 
02150 
02151     int BIO_write(BIO* bio, const void* data, int len)
02152     {
02153         int  ret;
02154         SSL* ssl = 0;
02155         BIO* front = bio;
02156 
02157         /* already got eof, again is error */
02158         if (front->eof)
02159             return -1;
02160 
02161         while(bio && ((ssl = bio->ssl) == 0) )
02162             bio = bio->next;
02163 
02164         if (ssl == 0) return -1;
02165 
02166         ret = SSL_write(ssl, data, len);
02167         if (ret == 0)
02168             front->eof = 1;
02169         else if (ret < 0) {
02170             int err = SSL_get_error(ssl, 0);
02171             if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) )
02172                 front->eof = 1;
02173         }
02174 
02175         return ret;
02176     }
02177 
02178 
02179     BIO* BIO_push(BIO* top, BIO* append)
02180     {
02181         top->next    = append;
02182         append->prev = top;
02183 
02184         return top;
02185     }
02186 
02187 
02188     int BIO_flush(BIO* bio)
02189     {
02190         /* for CyaSSL no flushing needed */
02191         return 1;
02192     }
02193 
02194 
02195 #endif /* OPENSSL_EXTRA || GOAHEAD_WS */
02196 
02197 
02198 #ifdef OPENSSL_EXTRA
02199 
02200     unsigned long SSLeay(void)
02201     {
02202         return SSLEAY_VERSION_NUMBER;
02203     }
02204 
02205 
02206     const char* SSLeay_version(int type)
02207     {
02208         static const char* version = "SSLeay CyaSSL compatibility";
02209         return version;
02210     }
02211 
02212 
02213     void MD5_Init(MD5_CTX* md5)
02214     {
02215         typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1];
02216         (void)sizeof(md5_test);
02217 
02218         InitMd5((Md5*)md5);
02219     }
02220 
02221 
02222     void MD5_Update(MD5_CTX* md5, const void* input, unsigned long sz)
02223     {
02224         Md5Update((Md5*)md5, (const byte*)input, sz);
02225     }
02226 
02227 
02228     void MD5_Final(byte* input, MD5_CTX* md5)
02229     {
02230         Md5Final((Md5*)md5, input);
02231     }
02232 
02233 
02234     void SHA_Init(SHA_CTX* sha)
02235     {
02236         typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1];
02237         (void)sizeof(sha_test);
02238 
02239         InitSha((Sha*)sha);
02240     }
02241 
02242 
02243     void SHA_Update(SHA_CTX* sha, const void* input, unsigned long sz)
02244     {
02245         ShaUpdate((Sha*)sha, (const byte*)input, sz);
02246     }
02247 
02248 
02249     void SHA_Final(byte* input, SHA_CTX* sha)
02250     {
02251         ShaFinal((Sha*)sha, input);
02252     }
02253 
02254 
02255     const EVP_MD* EVP_md5(void)
02256     {
02257         static const char* type = "MD5";
02258         return type;
02259     }
02260 
02261 
02262     const EVP_MD* EVP_sha1(void)
02263     {
02264         static const char* type = "SHA";
02265         return type;
02266     }
02267 
02268 
02269     void EVP_MD_CTX_init(EVP_MD_CTX* ctx)
02270     {
02271         /* do nothing */ 
02272     }
02273 
02274 
02275     int EVP_MD_CTX_cleanup(EVP_MD_CTX* ctx)
02276     {
02277         return 0;
02278     }    
02279 
02280 
02281     int EVP_DigestInit(EVP_MD_CTX* ctx, const EVP_MD* type)
02282     {
02283         if (XSTRNCMP(type, "MD5", 3) == 0) {
02284              ctx->macType = MD5;
02285              MD5_Init((MD5_CTX*)&ctx->hash);
02286         }
02287         else if (XSTRNCMP(type, "SHA", 3) == 0) {
02288              ctx->macType = SHA;
02289              SHA_Init((SHA_CTX*)&ctx->hash);
02290         }
02291         else
02292              return -1;
02293 
02294         return 0;
02295     }
02296 
02297 
02298     int EVP_DigestUpdate(EVP_MD_CTX* ctx, const void* data, size_t sz)
02299     {
02300         if (ctx->macType == MD5) 
02301             MD5_Update((MD5_CTX*)&ctx->hash, data, (unsigned long)sz);
02302         else if (ctx->macType == SHA) 
02303             SHA_Update((SHA_CTX*)&ctx->hash, data, (unsigned long)sz);
02304         else
02305             return -1;
02306 
02307         return 0;
02308     }
02309 
02310 
02311     int EVP_DigestFinal(EVP_MD_CTX* ctx, unsigned char* md, unsigned int* s)
02312     {
02313         if (ctx->macType == MD5) {
02314             MD5_Final(md, (MD5_CTX*)&ctx->hash);
02315             if (s) *s = MD5_DIGEST_SIZE;
02316         }
02317         else if (ctx->macType == SHA) {
02318             SHA_Final(md, (SHA_CTX*)&ctx->hash);
02319             if (s) *s = SHA_DIGEST_SIZE;
02320         }
02321         else
02322             return -1;
02323 
02324         return 0;
02325     }
02326 
02327 
02328     int EVP_DigestFinal_ex(EVP_MD_CTX* ctx, unsigned char* md, unsigned int* s)
02329     {
02330         return EVP_DigestFinal(ctx, md, s);
02331     }
02332 
02333 
02334     unsigned char* HMAC(const EVP_MD* evp_md, const void* key, int key_len,
02335         const unsigned char* d, int n, unsigned char* md, unsigned int* md_len)
02336     {
02337         Hmac hmac;
02338 
02339         if (!md) return 0;  /* no static buffer support */
02340 
02341         if (XSTRNCMP(evp_md, "MD5", 3) == 0) {
02342             HmacSetKey(&hmac, MD5, key, key_len);
02343             if (md_len) *md_len = MD5_DIGEST_SIZE;
02344         }
02345         else if (XSTRNCMP(evp_md, "SHA", 3) == 0) {
02346             HmacSetKey(&hmac, SHA, key, key_len);    
02347             if (md_len) *md_len = SHA_DIGEST_SIZE;
02348         }
02349         else
02350             return 0;
02351 
02352         HmacUpdate(&hmac, d, n);
02353         HmacFinal(&hmac, md);
02354     
02355         return md;
02356     }
02357 
02358     unsigned long ERR_get_error(void)
02359     {
02360         /* TODO: */
02361         return 0;
02362     }
02363 
02364     void ERR_clear_error(void)
02365     {
02366         /* TODO: */
02367     }
02368 
02369 
02370     int RAND_status(void)
02371     {
02372         return 1;  /* CTaoCrypt provides enough seed internally */
02373     }
02374 
02375 
02376     int RAND_bytes(unsigned char* buf, int num)
02377     {
02378         RNG rng;
02379 
02380         if (InitRng(&rng))
02381            return 0;
02382 
02383         RNG_GenerateBlock(&rng, buf, num);
02384 
02385         return 1;
02386     }
02387 
02388 
02389     int DES_key_sched(const_DES_cblock* key, DES_key_schedule* schedule)
02390     {
02391         XMEMCPY(schedule, key, sizeof(const_DES_cblock));
02392         return 0;
02393     }
02394 
02395 
02396     void DES_cbc_encrypt(const unsigned char* input, unsigned char* output,
02397                      long length, DES_key_schedule* schedule, DES_cblock* ivec,
02398                      int enc)
02399     {
02400         Des des;
02401         Des_SetKey(&des, (const byte*)schedule, (const byte*)ivec, !enc);
02402 
02403         if (enc)
02404             Des_CbcEncrypt(&des, output, input, length);
02405         else
02406             Des_CbcDecrypt(&des, output, input, length);
02407     }
02408 
02409 
02410     /* correctly sets ivec for next call */
02411     void DES_ncbc_encrypt(const unsigned char* input, unsigned char* output,
02412                      long length, DES_key_schedule* schedule, DES_cblock* ivec,
02413                      int enc)
02414     {
02415         Des des;
02416         Des_SetKey(&des, (const byte*)schedule, (const byte*)ivec, !enc);
02417 
02418         if (enc)
02419             Des_CbcEncrypt(&des, output, input, length);
02420         else
02421             Des_CbcDecrypt(&des, output, input, length);
02422 
02423         XMEMCPY(ivec, output + length - sizeof(DES_cblock), sizeof(DES_cblock));
02424     }
02425 
02426 
02427     void ERR_free_strings(void)
02428     {
02429         /* handled internally */
02430     }
02431 
02432 
02433     void ERR_remove_state(unsigned long state)
02434     {
02435         /* TODO: GetErrors().Remove(); */
02436     }
02437 
02438 
02439     void EVP_cleanup(void)
02440     {
02441         /* nothing to do here */
02442     }
02443 
02444 
02445     void CRYPTO_cleanup_all_ex_data(void)
02446     {
02447         /* nothing to do here */
02448     }
02449 
02450 
02451     long SSL_CTX_set_mode(SSL_CTX* ctx, long mode)
02452     {
02453         /* SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER is CyaSSL default mode */
02454 
02455         if (mode == SSL_MODE_ENABLE_PARTIAL_WRITE)
02456             ctx->partialWrite = 1;
02457 
02458         return mode;
02459     }
02460 
02461 
02462     long SSL_CTX_get_mode(SSL_CTX* ctx)
02463     {
02464         /* TODO: */
02465         return 0;
02466     }
02467 
02468 
02469     void SSL_CTX_set_default_read_ahead(SSL_CTX* ctx, int m)
02470     {
02471         /* TODO: maybe? */
02472     }
02473 
02474 
02475     int SSL_CTX_set_session_id_context(SSL_CTX* ctx,
02476                                        const unsigned char* sid_ctx,
02477                                        unsigned int sid_ctx_len)
02478     {
02479         /* No application specific context needed for cyaSSL */
02480         return SSL_SUCCESS;
02481     }
02482 
02483 
02484     long SSL_CTX_sess_get_cache_size(SSL_CTX* ctx)
02485     {
02486         /* TODO: maybe? */
02487         return (~0);
02488     }
02489 
02490     unsigned long ERR_get_error_line_data(const char** file, int* line,
02491                                           const char** data, int *flags)
02492     {
02493         /* Not implemented */
02494         return 0;
02495     }
02496 
02497 
02498     X509* SSL_get_peer_certificate(SSL* ssl)
02499     {
02500         if (ssl->peerCert.issuer.sz)
02501             return &ssl->peerCert;
02502         else
02503             return 0;
02504     }
02505 
02506 
02507 
02508     int SSL_set_ex_data(SSL* ssl, int idx, void* data)
02509     {
02510         return 0;
02511     }
02512 
02513 
02514     int SSL_get_shutdown(const SSL* ssl)
02515     {
02516         return 0;
02517     }
02518 
02519 
02520     int SSL_set_session_id_context(SSL* ssl, const unsigned char* id,
02521                                    unsigned int len)
02522     {
02523         return 0;
02524     }
02525 
02526 
02527     void SSL_set_connect_state(SSL* ssl)
02528     {
02529         /* client by default */ 
02530     }
02531 
02532 
02533     int SSL_session_reused(SSL* ssl)
02534     {
02535         return ssl->options.resuming;
02536     }
02537 
02538 
02539     void SSL_SESSION_free(SSL_SESSION* session)
02540     {
02541      
02542     }
02543 
02544 
02545     const char* SSL_get_version(SSL* ssl)
02546     {
02547         if (ssl->version.major == 3) {
02548             switch (ssl->version.minor) {
02549                 case 0 :
02550                     return "SSLv3";
02551                 case 1 :
02552                     return "TLSv1";
02553                 case 2 :
02554                     return "TLSv1.1";
02555                 case 3 :
02556                     return "TLSv1.2";
02557             }
02558         }
02559         return "unknown";
02560     }
02561 
02562 
02563     SSL_CIPHER*  SSL_get_current_cipher(SSL* ssl)
02564     {
02565         return &ssl->cipher;
02566     }
02567 
02568 
02569     const char* SSL_CIPHER_get_name(const SSL_CIPHER* cipher)
02570     {
02571         if (cipher) {
02572             switch (cipher->ssl->options.cipherSuite) {
02573                 case SSL_RSA_WITH_RC4_128_SHA :
02574                     return "SSL_RSA_WITH_RC4_128_SHA";
02575                 case SSL_RSA_WITH_RC4_128_MD5 :
02576                     return "SSL_RSA_WITH_RC4_128_MD5";
02577                 case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
02578                     return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
02579                 case TLS_RSA_WITH_AES_128_CBC_SHA :
02580                     return "TLS_RSA_WITH_AES_128_CBC_SHA";
02581                 case TLS_RSA_WITH_AES_256_CBC_SHA :
02582                     return "TLS_RSA_WITH_AES_256_CBC_SHA";
02583                 case TLS_PSK_WITH_AES_128_CBC_SHA :
02584                     return "TLS_PSK_WITH_AES_128_CBC_SHA";
02585                 case TLS_PSK_WITH_AES_256_CBC_SHA :
02586                     return "TLS_PSK_WITH_AES_256_CBC_SHA";
02587                 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
02588                     return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
02589                 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
02590                     return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
02591                 case TLS_RSA_WITH_HC_128_CBC_MD5 :
02592                     return "TLS_RSA_WITH_HC_128_CBC_MD5";
02593                 case TLS_RSA_WITH_HC_128_CBC_SHA :
02594                     return "TLS_RSA_WITH_HC_128_CBC_SHA";
02595                 case TLS_RSA_WITH_RABBIT_CBC_SHA :
02596                     return "TLS_RSA_WITH_RABBIT_CBC_SHA";
02597                 case TLS_NTRU_RSA_WITH_RC4_128_SHA :
02598                     return "TLS_NTRU_RSA_WITH_RC4_128_SHA";
02599                 case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
02600                     return "TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA";
02601                 case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
02602                     return "TLS_NTRU_RSA_WITH_AES_128_CBC_SHA";
02603                 case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
02604                     return "TLS_NTRU_RSA_WITH_AES_256_CBC_SHA";
02605             }
02606         }
02607 
02608         return "NONE";
02609     }
02610 
02611 
02612     char* SSL_CIPHER_description(SSL_CIPHER* cipher, char* buffer, int len)
02613     {
02614         return 0;
02615     }
02616 
02617 
02618     SSL_SESSION* SSL_get1_session(SSL* ssl)  /* what's ref count */
02619     {
02620         return 0;
02621     }
02622 
02623 
02624     void X509_free(X509* buf)
02625     {
02626        
02627     }
02628 
02629 
02630     void OPENSSL_free(void* buf)
02631     {
02632   
02633     }
02634 
02635 
02636     int OCSP_parse_url(char* url, char** host, char** port, char** path,
02637                        int* ssl)
02638     {
02639         return 0;
02640     }
02641 
02642 
02643     SSL_METHOD* SSLv2_client_method(void)
02644     {
02645         return 0;
02646     }
02647 
02648 
02649     SSL_METHOD* SSLv2_server_method(void)
02650     {
02651         return 0;
02652     }
02653 
02654 
02655 #ifndef NO_MD4
02656 
02657     void MD4_Init(MD4_CTX* md4)
02658     {
02659         /* make sure we have a big enough buffer */
02660         typedef char ok[sizeof(md4->buffer) >= sizeof(Md4) ? 1 : -1];
02661         (void) sizeof(ok);
02662  
02663         InitMd4((Md4*)md4);    
02664     }
02665 
02666 
02667     void MD4_Update(MD4_CTX* md4, const void* data, size_t len)
02668     {
02669         Md4Update((Md4*)md4, (const byte*)data, (word32)len); 
02670     }
02671 
02672 
02673     void MD4_Final(unsigned char* digest, MD4_CTX* md4)
02674     {
02675         Md4Final((Md4*)md4, digest); 
02676     }
02677 
02678 #endif /* NO_MD4 */
02679 
02680 
02681     BIO* BIO_pop(BIO* top)
02682     {
02683         return 0;
02684     }
02685 
02686 
02687     int BIO_pending(BIO* bio)
02688     {
02689         return 0;
02690     }
02691 
02692 
02693 
02694     BIO_METHOD* BIO_s_mem(void)
02695     {
02696         return 0;
02697     }
02698 
02699 
02700     BIO_METHOD* BIO_f_base64(void)
02701     {
02702         return 0;
02703     }
02704 
02705 
02706     void BIO_set_flags(BIO* bio, int flags)
02707     {
02708      
02709     }
02710 
02711 
02712 
02713     void RAND_screen(void)
02714     {
02715     
02716     }
02717 
02718 
02719     const char* RAND_file_name(char* fname, size_t len)
02720     {
02721         return 0;
02722     }
02723 
02724 
02725     int RAND_write_file(const char* fname)
02726     {
02727         return 0;
02728     }
02729 
02730 
02731     int RAND_load_file(const char* fname, long len)
02732     {
02733         /* CTaoCrypt provides enough entropy internally or will report error */
02734         if (len == -1)
02735             return 1024;
02736         else
02737             return (int)len;
02738     }
02739 
02740 
02741     int RAND_egd(const char* path)
02742     {
02743         return 0;
02744     }
02745 
02746 
02747 
02748     COMP_METHOD* COMP_zlib(void)
02749     {
02750         return 0;
02751     }
02752 
02753 
02754     COMP_METHOD* COMP_rle(void)
02755     {
02756         return 0;
02757     }
02758 
02759 
02760     int SSL_COMP_add_compression_method(int method, void* data)
02761     {
02762         return 0;
02763     }
02764 
02765 
02766 
02767     int SSL_get_ex_new_index(long idx, void* data, void* cb1, void* cb2,
02768                              void* cb3)
02769     {
02770         return 0;
02771     }
02772 
02773 
02774     int CRYPTO_num_locks(void)
02775     {
02776         return 0;
02777     }
02778 
02779 
02780     void CRYPTO_set_id_callback(unsigned long (*f)(void))
02781     {
02782     
02783     }
02784 
02785 
02786     void CRYPTO_set_locking_callback(void (*f)(int, int, const char*, int))
02787     {
02788       
02789     }
02790 
02791 
02792     void CRYPTO_set_dynlock_create_callback(CRYPTO_dynlock_value* (*f)(
02793                                                               const char*, int))
02794     {
02795      
02796     }
02797 
02798 
02799     void CRYPTO_set_dynlock_lock_callback(void (*f)(int, CRYPTO_dynlock_value*,
02800                                                 const char*, int))
02801     {
02802      
02803     }
02804 
02805 
02806     void CRYPTO_set_dynlock_destroy_callback(void (*f)(CRYPTO_dynlock_value*,
02807                                                    const char*, int))
02808     {
02809       
02810     }
02811 
02812 
02813 
02814     const char* X509_verify_cert_error_string(long err)
02815     {
02816         return 0;
02817     }
02818 
02819 
02820 
02821     int X509_LOOKUP_add_dir(X509_LOOKUP* lookup, const char* dir, long len)
02822     {
02823         return 0;
02824     }
02825 
02826 
02827     int X509_LOOKUP_load_file(X509_LOOKUP* lookup, const char* file, long len)
02828     {
02829         return 0;
02830     }
02831 
02832 
02833     X509_LOOKUP_METHOD* X509_LOOKUP_hash_dir(void)
02834     {
02835         return 0;
02836     }
02837 
02838 
02839     X509_LOOKUP_METHOD* X509_LOOKUP_file(void)
02840     {
02841         return 0;
02842     }
02843 
02844 
02845 
02846     X509_LOOKUP* X509_STORE_add_lookup(X509_STORE* store, X509_LOOKUP_METHOD* m)
02847     {
02848         return 0;
02849     }
02850 
02851 
02852     X509_STORE* X509_STORE_new(void)
02853     {
02854         return 0;
02855     }
02856 
02857 
02858     int X509_STORE_get_by_subject(X509_STORE_CTX* ctx, int idx, X509_NAME* name,
02859                                        X509_OBJECT* obj)
02860     {
02861         return 0;
02862     }
02863 
02864 
02865     int X509_STORE_CTX_init(X509_STORE_CTX* ctx, X509_STORE* store, X509* x509,
02866                             STACK_OF(X509)* sk)
02867     {
02868         return 0;
02869     }
02870 
02871 
02872     void X509_STORE_CTX_cleanup(X509_STORE_CTX* ctx)
02873     {
02874  
02875     }
02876 
02877 
02878 
02879     ASN1_TIME* X509_CRL_get_lastUpdate(X509_CRL* crl)
02880     {
02881         return 0;
02882     }
02883 
02884 
02885     ASN1_TIME* X509_CRL_get_nextUpdate(X509_CRL* crl)
02886     {
02887         return 0;
02888     }
02889 
02890 
02891 
02892     EVP_PKEY* X509_get_pubkey(X509* x509)
02893     {
02894         return 0;
02895     }
02896 
02897 
02898     int X509_CRL_verify(X509_CRL* crl, EVP_PKEY* key)
02899     {
02900         return 0;
02901     }
02902 
02903 
02904     void X509_STORE_CTX_set_error(X509_STORE_CTX* ctx, int err)
02905     {
02906  
02907     }
02908 
02909 
02910     void X509_OBJECT_free_contents(X509_OBJECT* obj)
02911     {
02912   
02913     }
02914 
02915 
02916     void EVP_PKEY_free(EVP_PKEY* key)
02917     {
02918      
02919     }
02920 
02921 
02922     int X509_cmp_current_time(const ASN1_TIME* time)
02923     {
02924         return 0;
02925     }
02926 
02927 
02928     int sk_X509_REVOKED_num(X509_REVOKED* revoked)
02929     {
02930         return 0;
02931     }
02932 
02933 
02934 
02935     X509_REVOKED* X509_CRL_get_REVOKED(X509_CRL* crl)
02936     {
02937         return 0;
02938     }
02939 
02940 
02941     X509_REVOKED* sk_X509_REVOKED_value(X509_REVOKED* revoked, int value)
02942     {
02943         return 0;
02944     }
02945 
02946 
02947 
02948     ASN1_INTEGER* X509_get_serialNumber(X509* x509)
02949     {
02950         return 0;
02951     }
02952 
02953 
02954 
02955     int ASN1_TIME_print(BIO* bio, const ASN1_TIME* time)
02956     {
02957         return 0;
02958     }
02959 
02960 
02961 
02962     int ASN1_INTEGER_cmp(const ASN1_INTEGER* a, const ASN1_INTEGER* b)
02963     {
02964         return 0;
02965     }
02966 
02967 
02968     long ASN1_INTEGER_get(const ASN1_INTEGER* i)
02969     {
02970         return 0;
02971     }
02972 
02973 
02974 
02975     void* X509_STORE_CTX_get_ex_data(X509_STORE_CTX* ctx, int idx)
02976     {
02977         return 0;
02978     }
02979 
02980 
02981     int SSL_get_ex_data_X509_STORE_CTX_idx(void)
02982     {
02983         return 0;
02984     }
02985 
02986 
02987     void* SSL_get_ex_data(const SSL* ssl, int idx)
02988     {
02989         return 0;
02990     }
02991 
02992 
02993     void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX* ctx, void* userdata)
02994     {
02995         ctx->userdata = userdata;
02996     }
02997 
02998 
02999     void SSL_CTX_set_default_passwd_cb(SSL_CTX* ctx, pem_password_cb cb)
03000     {
03001         ctx->passwd_cb = cb;
03002     }
03003 
03004 
03005     long SSL_CTX_set_timeout(SSL_CTX* ctx, long to)
03006     {
03007         return 0;
03008     }
03009 
03010 
03011     void SSL_CTX_set_info_callback(SSL_CTX* ctx, void (*f)())
03012     {
03013         
03014     }
03015 
03016 
03017     unsigned long ERR_peek_error(void)
03018     {
03019         return 0;
03020     }
03021 
03022 
03023     int ERR_GET_REASON(int err)
03024     {
03025         return 0;
03026     }
03027 
03028 
03029     char* SSL_alert_type_string_long(int alert)
03030     {
03031         return 0;
03032     }
03033 
03034 
03035     char* SSL_alert_desc_string_long(int alert)
03036     {
03037         return 0;
03038     }
03039 
03040 
03041     char* SSL_state_string_long(SSL* ssl)
03042     {
03043         return 0;
03044     }
03045 
03046 
03047 
03048     void RSA_free(RSA* rsa)
03049     {
03050         
03051     }
03052 
03053 
03054     int PEM_def_callback(char* name, int num, int w, void* key)
03055     {
03056         return 0;
03057     }
03058     
03059 
03060     long SSL_CTX_sess_accept(SSL_CTX* ctx)
03061     {
03062         return 0;
03063     }
03064 
03065 
03066     long SSL_CTX_sess_connect(SSL_CTX* ctx)
03067     {
03068         return 0;
03069     }
03070 
03071 
03072     long SSL_CTX_sess_accept_good(SSL_CTX* ctx)
03073     {
03074         return 0;
03075     }
03076 
03077 
03078     long SSL_CTX_sess_connect_good(SSL_CTX* ctx)
03079     {
03080         return 0;
03081     }
03082 
03083 
03084     long SSL_CTX_sess_accept_renegotiate(SSL_CTX* ctx)
03085     {
03086         return 0;
03087     }
03088 
03089 
03090     long SSL_CTX_sess_connect_renegotiate(SSL_CTX* ctx)
03091     {
03092         return 0;
03093     }
03094 
03095 
03096     long SSL_CTX_sess_hits(SSL_CTX* ctx)
03097     {
03098         return 0;
03099     }
03100 
03101 
03102     long SSL_CTX_sess_cb_hits(SSL_CTX* ctx)
03103     {
03104         return 0;
03105     }
03106 
03107 
03108     long SSL_CTX_sess_cache_full(SSL_CTX* ctx)
03109     {
03110         return 0;
03111     }
03112 
03113 
03114     long SSL_CTX_sess_misses(SSL_CTX* ctx)
03115     {
03116         return 0;
03117     }
03118 
03119 
03120     long SSL_CTX_sess_timeouts(SSL_CTX* ctx)
03121     {
03122         return 0;
03123     }
03124 
03125 
03126     long SSL_CTX_sess_number(SSL_CTX* ctx)
03127     {
03128         return 0;
03129     }
03130 
03131 
03132     void DES_set_key_unchecked(const_DES_cblock* des, DES_key_schedule* key)
03133     {
03134     }
03135 
03136 
03137     void DES_set_odd_parity(DES_cblock* des)
03138     {
03139     }
03140 
03141     
03142     void DES_ecb_encrypt(DES_cblock* desa, DES_cblock* desb,
03143                          DES_key_schedule* key, int len)
03144     {
03145     }
03146 
03147     int BIO_printf(BIO* bio, const char* format, ...)
03148     {
03149         return 0;
03150     }
03151 
03152 
03153     int ASN1_UTCTIME_print(BIO* bio, const ASN1_UTCTIME* a)
03154     {
03155         return 0;
03156     }
03157     
03158 
03159     int  sk_num(X509_REVOKED* rev)
03160     {
03161         return 0;
03162     }
03163 
03164 
03165     void* sk_value(X509_REVOKED* rev, int i)
03166     {
03167         return 0;
03168     }
03169 
03170 
03171     int EVP_BytesToKey(const EVP_CIPHER* type, const EVP_MD* md,
03172                        const byte* salt, const byte* data, int sz, int count,
03173                        byte* key, byte* iv)
03174     {
03175         int keyLen = 0;
03176         int ivLen  = 0;
03177 
03178         Md5    myMD;
03179         byte   digest[MD5_DIGEST_SIZE];
03180 
03181         int j;
03182         int keyLeft;
03183         int ivLeft;
03184         int keyOutput = 0;
03185 
03186         InitMd5(&myMD);
03187 
03188         /* only support MD5 for now */
03189         if (XSTRNCMP(md, "MD5", 3)) return 0;
03190 
03191         /* only support CBC DES and AES for now */
03192         if (XSTRNCMP(type, "DES-CBC", 7) == 0) {
03193             keyLen = DES_KEY_SIZE;
03194             ivLen  = DES_IV_SIZE;
03195         }
03196         else if (XSTRNCMP(type, "DES-EDE3-CBC", 12) == 0) {
03197             keyLen = DES3_KEY_SIZE;
03198             ivLen  = DES_IV_SIZE;
03199         }
03200         else if (XSTRNCMP(type, "AES-128-CBC", 11) == 0) {
03201             keyLen = AES_128_KEY_SIZE;
03202             ivLen  = AES_IV_SIZE;
03203         }
03204         else if (XSTRNCMP(type, "AES-192-CBC", 11) == 0) {
03205             keyLen = AES_192_KEY_SIZE;
03206             ivLen  = AES_IV_SIZE;
03207         }
03208         else if (XSTRNCMP(type, "AES-256-CBC", 11) == 0) {
03209             keyLen = AES_256_KEY_SIZE;
03210             ivLen  = AES_IV_SIZE;
03211         }
03212         else
03213             return 0;
03214 
03215         keyLeft   = keyLen;
03216         ivLeft    = ivLen;
03217 
03218         while (keyOutput < (keyLen + ivLen)) {
03219             int digestLeft = MD5_DIGEST_SIZE;
03220             /* D_(i - 1) */
03221             if (keyOutput)                      /* first time D_0 is empty */
03222                 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
03223             /* data */
03224             Md5Update(&myMD, data, sz);
03225             /* salt */
03226             if (salt)
03227                 Md5Update(&myMD, salt, EVP_SALT_SIZE);
03228             Md5Final(&myMD, digest);
03229             /* count */
03230             for (j = 1; j < count; j++) {
03231                 Md5Update(&myMD, digest, MD5_DIGEST_SIZE);
03232                 Md5Final(&myMD, digest);
03233             }
03234 
03235             if (keyLeft) {
03236                 int store = min(keyLeft, MD5_DIGEST_SIZE);
03237                 XMEMCPY(&key[keyLen - keyLeft], digest, store);
03238 
03239                 keyOutput  += store;
03240                 keyLeft    -= store;
03241                 digestLeft -= store;
03242             }
03243 
03244             if (ivLeft && digestLeft) {
03245                 int store = min(ivLeft, digestLeft);
03246                 XMEMCPY(&iv[ivLen - ivLeft], &digest[MD5_DIGEST_SIZE -
03247                                                     digestLeft], store);
03248                 keyOutput += store;
03249                 ivLeft    -= store;
03250             }
03251         }
03252         if (keyOutput != (keyLen + ivLen))
03253             return 0;
03254         return keyOutput;
03255     }
03256 
03257     /* stunnel 4.28 needs */
03258     void* SSL_CTX_get_ex_data(const SSL_CTX* ctx, int d)
03259     {
03260         return 0;
03261     }
03262 
03263 
03264     int SSL_CTX_set_ex_data(SSL_CTX* ctx, int d, void* p)
03265     {
03266         return SSL_SUCCESS;
03267     }
03268 
03269 
03270     void SSL_CTX_sess_set_get_cb(SSL_CTX* ctx, SSL_SESSION*(*f)(SSL*,
03271                                                     unsigned char*, int, int*))
03272     {
03273        
03274     }
03275 
03276 
03277     void SSL_CTX_sess_set_new_cb(SSL_CTX* ctx, int (*f)(SSL*, SSL_SESSION*))
03278     {
03279 
03280     }
03281 
03282 
03283     void SSL_CTX_sess_set_remove_cb(SSL_CTX* ctx, void (*f)(SSL_CTX*,
03284                                                             SSL_SESSION*))
03285     {
03286 
03287     }
03288 
03289 
03290     int i2d_SSL_SESSION(SSL_SESSION* sess, unsigned char** p)
03291     {
03292         return sizeof(SSL_SESSION);
03293     }
03294 
03295 
03296     SSL_SESSION* d2i_SSL_SESSION(SSL_SESSION** sess, const unsigned char** p,
03297                                  long i)
03298     {
03299         return *sess;
03300     }
03301 
03302 
03303     long SSL_SESSION_get_timeout(const SSL_SESSION* sess)
03304     {
03305         return sess->timeout;
03306     }
03307 
03308 
03309     long SSL_SESSION_get_time(const SSL_SESSION* sess)
03310     {
03311         return sess->bornOn;
03312     }
03313 
03314 
03315     int SSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, void* c)
03316     {
03317         return 0; 
03318     }
03319 
03320 
03321 #endif /* OPENSSL_EXTRA */
03322 
03323 
03324 #ifdef SESSION_CERTS
03325 
03326 
03327 /* Get peer's certificate chain */
03328 X509_CHAIN* CyaSSL_get_peer_chain(SSL* ssl)
03329 {
03330     if (ssl)
03331         return &ssl->session.chain;
03332 
03333     return 0;
03334 }
03335 
03336 
03337 /* Get peer's certificate chain total count */
03338 int CyaSSL_get_chain_count(X509_CHAIN* chain)
03339 {
03340     if (chain)
03341         return chain->count;
03342 
03343     return 0;
03344 }
03345 
03346 
03347 /* Get peer's ASN.1 DER ceritifcate at index (idx) length in bytes */
03348 int CyaSSL_get_chain_length(X509_CHAIN* chain, int idx)
03349 {
03350     if (chain)
03351         return chain->certs[idx].length;
03352 
03353     return 0;
03354 }
03355 
03356 
03357 /* Get peer's ASN.1 DER ceritifcate at index (idx) */
03358 byte* CyaSSL_get_chain_cert(X509_CHAIN* chain, int idx)
03359 {
03360     if (chain)
03361         return chain->certs[idx].buffer;
03362 
03363     return 0;
03364 }
03365 
03366 
03367 /* Get peer's PEM ceritifcate at index (idx), output to buffer if inLen big
03368    enough else return error (-1), output length is in *outLen */
03369 int  CyaSSL_get_chain_cert_pem(X509_CHAIN* chain, int idx,
03370                                unsigned char* buffer, int inLen, int* outLen)
03371 {
03372     const char header[] = "-----BEGIN CERTIFICATE-----\n";
03373     const char footer[] = "-----END CERTIFICATE-----\n";
03374 
03375     int headerLen = sizeof(header) - 1;
03376     int footerLen = sizeof(footer) - 1;
03377     int i;
03378 
03379     if (!chain || !outLen || !buffer)
03380         return -1;
03381 
03382     /* don't even try if inLen too short */
03383     if (inLen < headerLen + footerLen + chain->certs[idx].length)
03384         return -1;
03385 
03386     /* header */
03387     XMEMCPY(buffer, header, headerLen);
03388     i = headerLen;
03389 
03390     /* body */
03391     *outLen = inLen;  /* input to Base64Encode */
03392     if (Base64Encode(chain->certs[idx].buffer, chain->certs[idx].length,
03393                      buffer + i, (word32*)outLen) < 0)
03394         return -1;
03395     i += *outLen;
03396 
03397     /* footer */
03398     if ( (i + footerLen) > inLen)
03399         return -1;
03400     XMEMCPY(buffer + i, footer, footerLen);
03401     *outLen += headerLen + footerLen; 
03402 
03403     return 0;
03404 }
03405 
03406 
03407 /* get session ID */
03408 const byte* CyaSSL_get_sessionID(const SSL_SESSION* session)
03409 {
03410     return session->sessionID;
03411 }
03412 
03413 
03414 #endif /* SESSION_CERTS */
03415