[0001]
[0002]
[0003]
[0004]
[0005]
[0006]
[0007]
[0008]
[0009]
[0010]
[0011]
[0012]
[0013]
[0014]
[0015]
[0016]
[0017]
[0018]
[0019]
[0020]
[0021]
[0022]
[0023]
[0024]
[0025]
[0026]
[0027]
[0028]
[0029]
[0030]
[0031]
[0032]
[0033]
[0034]
[0035]
[0036]
[0037]
[0038]
[0039]
[0040]
[0041]
[0042]
[0043]
[0044]
[0045]
[0046]
[0047]
[0048]
[0049]
[0050]
[0051]
[0052]
[0053]
[0054]
[0055]
[0056]
[0057]
[0058]
[0059]
[0060]
[0061]
[0062]
[0063]
[0064]
[0065]
[0066]
[0067]
[0068]
[0069]
[0070]
[0071]
[0072]
[0073]
[0074]
[0075]
[0076]
[0077]
[0078]
[0079]
[0080]
[0081]
[0082]
[0083]
[0084]
[0085]
[0086]
[0087]
[0088]
[0089]
[0090]
[0091]
[0092]
[0093]
[0094]
[0095]
[0096]
[0097]
[0098]
[0099]
[0100]
[0101]
[0102]
[0103]
[0104]
[0105]
[0106]
[0107]
[0108]
[0109]
[0110]
[0111]
[0112]
[0113]
[0114]
[0115]
[0116]
[0117]
[0118]
[0119]
[0120]
[0121]
[0122]
[0123]
[0124]
[0125]
[0126]
[0127]
[0128]
[0129]
[0130]
[0131]
[0132]
[0133]
[0134]
[0135]
[0136]
[0137]
[0138]
[0139]
[0140]
[0141]
[0142]
[0143]
[0144]
[0145]
[0146]
[0147]
[0148]
[0149]
[0150]
[0151]
[0152]
[0153]
[0154]
[0155]
[0156]
[0157]
[0158]
[0159]
[0160]
[0161]
[0162]
[0163]
[0164]
[0165]
[0166]
[0167]
[0168]
[0169]
[0170]
[0171]
[0172]
[0173]
[0174]
[0175]
[0176]
[0177]
[0178]
[0179]
[0180]
[0181]
[0182]
[0183]
[0184]
[0185]
[0186]
[0187]
[0188]
[0189]
[0190]
[0191]
[0192]
[0193]
[0194]
[0195]
[0196]
[0197]
[0198]
[0199]
[0200]
[0201]
[0202]
[0203]
[0204]
[0205]
[0206]
[0207]
[0208]
[0209]
[0210]
[0211]
[0212]
[0213]
[0214]
[0215]
[0216]
[0217]
[0218]
[0219]
[0220]
[0221]
[0222]
[0223]
[0224]
[0225]
[0226]
[0227]
[0228]
[0229]
[0230]
[0231]
[0232]
[0233]
[0234]
[0235]
[0236]
[0237]
[0238]
[0239]
[0240]
[0241]
[0242]
[0243]
[0244]
[0245]
[0246]
[0247]
[0248]
[0249]
[0250]
[0251]
[0252]
[0253]
[0254]
[0255]
[0256]
[0257]
[0258]
[0259]
[0260]
[0261]
[0262]
[0263]
[0264]
[0265]
[0266]
[0267]
[0268]
[0269]
[0270]
[0271]
[0272]
[0273]
[0274]
[0275]
[0276]
[0277]
[0278]
[0279]
[0280]
[0281]
[0282]
[0283]
[0284]
[0285]
[0286]
[0287]
[0288]
[0289]
[0290]
[0291]
[0292]
[0293]
[0294]
[0295]
[0296]
[0297]
[0298]
[0299]
[0300]
[0301]
[0302]
[0303]
[0304]
[0305]
[0306]
[0307]
[0308]
[0309]
[0310]
[0311]
[0312]
[0313]
[0314]
[0315]
[0316]
[0317]
[0318]
[0319]
[0320]
[0321]
[0322]
[0323]
[0324]
[0325]
[0326]
[0327]
[0328]
[0329]
[0330]
[0331]
[0332]
[0333]
[0334]
[0335]
[0336]
[0337]
[0338]
[0339]
[0340]
[0341]
[0342]
[0343]
[0344]
[0345]
[0346]
[0347]
[0348]
[0349]
[0350]
[0351]
[0352]
[0353]
[0354]
[0355]
[0356]
[0357]
[0358]
[0359]
[0360]
[0361]
[0362]
[0363]
[0364]
[0365]
[0366]
[0367]
[0368]
[0369]
[0370]
[0371]
[0372]
[0373]
[0374]
[0375]
[0376]
[0377]
[0378]
[0379]
[0380]
[0381]
[0382]
[0383]
[0384]
[0385]
[0386]
[0387]
[0388]
[0389]
[0390]
[0391]
[0392]
[0393]
[0394]
[0395]
[0396]
[0397]
[0398]
[0399]
[0400]
[0401]
[0402]
[0403]
[0404]
[0405]
[0406]
[0407]
[0408]
[0409]
[0410]
[0411]
[0412]
[0413]
[0414]
[0415]
[0416]
[0417]
[0418]
[0419]
[0420]
[0421]
[0422]
[0423]
[0424]
[0425]
[0426]
[0427]
[0428]
[0429]
[0430]
[0431]
[0432]
[0433]
[0434]
[0435]
[0436]
[0437]
[0438]
[0439]
[0440]
[0441]
[0442]
[0443]
[0444]
[0445]
[0446]
[0447]
[0448]
[0449]
[0450]
[0451]
[0452]
[0453]
[0454]
[0455]
[0456]
[0457]
[0458]
[0459]
[0460]
[0461]
[0462]
[0463]
[0464]
[0465]
[0466]
[0467]
[0468]
[0469]
[0470]
[0471]
[0472]
[0473]
[0474]
[0475]
[0476]
[0477]
[0478]
[0479]
[0480]
[0481]
[0482]
[0483]
[0484]
[0485]
[0486]
[0487]
[0488]
[0489]
[0490]
[0491]
[0492]
[0493]
[0494]
[0495]
[0496]
[0497]
[0498]
[0499]
[0500]
[0501]
[0502]
[0503]
[0504]
[0505]
[0506]
[0507]
[0508]
[0509]
[0510]
[0511]
[0512]
[0513]
[0514]
[0515]
[0516]
[0517]
[0518]
[0519]
[0520]
[0521]
[0522]
[0523]
[0524]
[0525]
[0526]
[0527]
[0528]
[0529]
[0530]
[0531]
[0532]
[0533]
[0534]
[0535]
[0536]
[0537]
[0538]
[0539]
[0540]
[0541]
[0542]
[0543]
[0544]
[0545]
[0546]
[0547]
[0548]
[0549]
[0550]
[0551]
[0552]
[0553]
[0554]
[0555]
[0556]
[0557]
[0558]
[0559]
[0560]
[0561]
[0562]
[0563]
[0564]
[0565]
[0566]
[0567]
[0568]
[0569]
[0570]
[0571]
[0572]
[0573]
[0574]
[0575]
[0576]
[0577]
[0578]
[0579]
[0580]
[0581]
[0582]
[0583]
[0584]
[0585]
[0586]
[0587]
[0588]
[0589]
[0590]
[0591]
[0592]
[0593]
[0594]
[0595]
[0596]
[0597]
[0598]
[0599]
[0600]
[0601]
[0602]
[0603]
[0604]
[0605]
[0606]
[0607]
[0608]
[0609]
[0610]
[0611]
[0612]
[0613]
[0614]
[0615]
[0616]
[0617]
[0618]
[0619]
[0620]
[0621]
[0622]
[0623]
[0624]
[0625]
[0626]
[0627]
[0628]
/*****************************************************************************/
/*
                                 Sesola.h
*/
/*****************************************************************************/

#ifndef SESOLA_H_LOADED
#define SESOLA_H_LOADED 1

#include "wasd.h"

/*****************/
/* config macros */
/*****************/

#define SESOLA_MEMORY 1

#ifndef SESOLA_MEMORY
#define SESOLA_MEMORY 1
#endif

/* being used to assess OpenSSL 3.0 processing durations */
#if WATCH_MOD
#define WATCH_OPENSSL_30 1
#else
#define WATCH_OPENSSL_30 0
#endif

/******************/
/* general macros */
/******************/

#define SESOLA_AFTER_102  OPENSSL_VERSION_NUMBER > 0x1000200fL
#define SESOLA_AFTER_110  OPENSSL_VERSION_NUMBER > 0x10100000L
#define SESOLA_AFTER_111  OPENSSL_VERSION_NUMBER > 0x10101000L
#define SESOLA_AFTER_300  OPENSSL_VERSION_NUMBER > 0x30000000L
#define SESOLA_BEFORE_102 OPENSSL_VERSION_NUMBER < 0x1000200fL
#define SESOLA_BEFORE_110 OPENSSL_VERSION_NUMBER < 0x10100000L
#define SESOLA_BEFORE_111 OPENSSL_VERSION_NUMBER < 0x10101000L
#define SESOLA_BEFORE_300 OPENSSL_VERSION_NUMBER < 0x30000000L
#define SESOLA_SINCE_102 OPENSSL_VERSION_NUMBER >= 0x1000200fL
#define SESOLA_SINCE_110 OPENSSL_VERSION_NUMBER >= 0x10100000L
#define SESOLA_SINCE_111 OPENSSL_VERSION_NUMBER >= 0x10101000L
#define SESOLA_SINCE_300 OPENSSL_VERSION_NUMBER >= 0x30000000L

/* include which variety of SSL CGI variables */
#define SESOLA_CGI_VAR_NONE                   1
#define SESOLA_CGI_VAR_APACHE_MOD_SSL         2
#define SESOLA_CGI_VAR_APACHE_MOD_SSL_EXTENS  3
#define SESOLA_CGI_VAR_APACHE_MOD_SSL_CLIENT  4
#define SESOLA_CGI_VAR_APACHE_MOD_SSL_OID     5
#define SESOLA_CGI_VAR_PURVEYOR               6

/* wait a maximum of five minutes for a private key password to be supplied */
#define SESOLA_PKPASSWD_REQUEST_SECONDS 300

/* number of attempts to get correct password */
#define SESOLA_PKPASSWD_ATTEMPTS 3

#define SESOLA_VERIFY_PEER_DATA_MAX_DEFAULT 1024  /* kBytes - i.e. 1MB */

/* local client certificate verification macros (see [.SSL]SSL.H) */
#define SESOLA_VERIFY_PEER_NONE        0x00
/* SSL_VERIFY_PEER */
#define SESOLA_VERIFY_PEER_OPTIONAL    0x01
/* SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */
#define SESOLA_VERIFY_PEER_REQUIRED    0x03

/* mask off the lower 8 OpenSSL verify bits removing the WASD bits */
#define SESOLA_VERIFY_PEER_MASK        0x0ff
/* do not alter certificate processing, just a callback (AST delivery) */
#define SESOLA_VERIFY_AST              0x100
/* use the peer certificate for authentication */
/* SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | 0x200 */
#define SESOLA_VERIFY_PEER_AUTH        0x203 

#define SESOLA_SSL_ACCEPT_MAX   48
#define SESOLA_SSL_CONNECT_MAX  48
#define SESOLA_SSL_SHUTDOWN_MAX 16

/* the fixed keywords used by SesolaCertKeyword() */
#define SESOLA_X509_EXTENSION_KEYWORDS \
        "CA:CPS:keyid:Policy:rfc822Name:URI:userPrincipalName:"

/*
http://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

The OpenSSL command

  $ openssl ciphers [-v] [-ssl2] [-ssl3] [-tls1] [cipherlist]

can be used to list available ciphers.

18-JAN-2015  MGD  !RC4
*/

/* the OpenSSL definitions are only required for the SSL modules */
#ifndef SESOLA_REQUIRED
#  undef SESOLA
#endif

/*******************************/
/* always used data structures */
/*******************************/

typedef struct SesolaServiceStruct SESOLA_CONTEXT;

struct SesolaServiceStruct
{
   BOOL  VerifyCA;

   int  SessionLifetime,
        VerifyDataMax,
        VerifyDepth,
        VersionBitmap,
        VersionOptions,
        VerifyPeer;

   char  *CaFilePtr,
         *CertFilePtr,
         *CipherListPtr,
         *KeyFilePtr,
         *OptionsStringPtr,
         *StrictTransSecPtr,
         *VersionStringPtr;

   char  CaFile [128],
         CertFile [128],
         CipherList [1024],
         KeyFile [128],
         OptionsString [256],
         StrictTransSec [48],
         VersionString [128];

   /* this will be cast using (SSL_CTX*) in Sesola.C */
   void  *SslCtx;
};

/***************************************/
#ifdef SESOLA  /* secure sockets layer */
/***************************************/

/* OpenSSL 0.9.6 has a typedef boolean - work around this */
#ifdef boolean
#  undef boolean
#  define BOOL int
#endif /* boolean */

/* OpenSSL header files (0.9.3ff) */
#include "openssl/err.h"
#include "openssl/X509.h"
#include "openssl/x509v3.h"
#include "openssl/ssl.h"
#include "openssl/bio.h"
#include "openssl/buffer.h"
#include "openssl/crypto.h"
#include "openssl/ssl.h"
#include "openssl/rand.h"
/***
  For SNI under HP SSL we want the TLS1 extensions and the HP SSL V1.4-471
  OpenSSL 0.9.8y (at least) OPENSSLCONF.H disables that portion of the header!
  Kludge it in here.
***/
#ifndef SSL_TLSEXT_ERR_OK

/* from ssl.h */
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB  53
#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54
#define SSL_CTRL_SET_TLSEXT_HOSTNAME       55

/* from tls1.h */
const char *SSL_get_servername(const SSL *s, const int type);
int SSL_get_servername_type(const SSL *s);

/* from ssl.h */
const SSL_METHOD *TLSv1_1_method(void);
const SSL_METHOD *TLSv1_2_method(void);

#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)

#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)

#define SSL_set_tlsext_host_name(s,name) \
SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)

#define SSL_TLSEXT_ERR_OK 0
#define SSL_TLSEXT_ERR_ALERT_WARNING 1
#define SSL_TLSEXT_ERR_ALERT_FATAL 2
#define SSL_TLSEXT_ERR_NOACK 3

#endif /* SSL_TLSEXT_ERR_OK */

/* not defined anywhere in OpenSSL but the "1024*10" seems common %^) */
#define SSL_SESSION_MAX_DER (1024*10)

#define SESOLA_DEFAULT_PROTOCOL "TLSvAll"

#define SESOLA_DEFAULT_OPTIONS  "+OP_CIPHER_SERVER_PREFERENCE"

#if OPENSSL_VERSION_NUMBER < 0x10101000L

/*
Modern compatibility
--------------------
For services that don't need backward compatibility, the parameters below
provide a higher level of security.  This configuration is compatible with
Firefox 27, Chrome 30, IE 11 on Windows 7, Edge, Opera 17, Safari 9, Android
5.0, and Java 8.

https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations

These ciphers required the [LOCAL]DH_PARAM_nnnn.PEM PFS prime files!
*/

#define SESOLA_DEFAULT_CIPHER_LIST \
"ECDHE-ECDSA-AES256-GCM-SHA384:" \
"ECDHE-RSA-AES256-GCM-SHA384:" \
"ECDHE-ECDSA-CHACHA20-POLY1305:" \
"ECDHE-RSA-CHACHA20-POLY1305:" \
"ECDHE-ECDSA-AES128-GCM-SHA256:" \
"ECDHE-RSA-AES128-GCM-SHA256:" \
"ECDHE-ECDSA-AES256-SHA384:" \
"ECDHE-RSA-AES256-SHA384:" \
"ECDHE-ECDSA-AES128-SHA256:" \
"ECDHE-RSA-AES128-SHA256"

#else

/* plus the TLSv1.3 ciphers */

#define SESOLA_DEFAULT_CIPHER_LIST \
"TLS13-CHACHA20-POLY1305-SHA256:" \
"TLS13-AES-256-GCM-SHA384:" \
"TLS13-AES-128-GCM-SHA256:" \
"TLS13-AES-128-CCM-SHA256:" \
"TLS13-AES-128-CCM-8-SHA256:" \
"ECDHE-ECDSA-AES256-GCM-SHA384:" \
"ECDHE-RSA-AES256-GCM-SHA384:" \
"ECDHE-ECDSA-CHACHA20-POLY1305:" \
"ECDHE-RSA-CHACHA20-POLY1305:" \
"ECDHE-ECDSA-AES128-GCM-SHA256:" \
"ECDHE-RSA-AES128-GCM-SHA256:" \
"ECDHE-ECDSA-AES256-SHA384:" \
"ECDHE-RSA-AES256-SHA384:" \
"ECDHE-ECDSA-AES128-SHA256:" \
"ECDHE-RSA-AES128-SHA256"

#endif

/**********/
/* macros */
/**********/

#define SESOLA_DEFAULT_VERIFY_DEPTH        10
#define SESOLA_DEFAULT_CACHE_SIZE         128  /* OpenSSL cache entries */
#define SESOLA_DEFAULT_CACHE_RECORD_MAX    32  /* WASD shared cache entries */
#define SESOLA_DEFAULT_CACHE_RECORD_SIZE 1024  /* bytes */
#define SESOLA_DEFAULT_CACHE_RECORD_X509 2048  /* bytes if X509 auth in use */
#define SESOLA_DEFAULT_CACHE_TIMEOUT        5  /* minutes */

/* bitmap used to specify protocols */
#define SESOLA_SSLV2    0x01
#define SESOLA_SSLV3    0x02
#define SESOLA_TLSV1    0x04
#define SESOLA_TLSV1_1  0x08
#define SESOLA_TLSV1_2  0x10
#define SESOLA_TLSV1_3  0x20

#define APACHE_MOD_SSL_VERSION_INTERFACE SoftwareID
#define APACHE_MOD_SSL_SERVER_CERT 0

#define SESOLA_NETIO_IN_PROGRESS(sesptr) \
   ((sesptr)->NetIoPtr->ReadAstFunction || \
    (sesptr)->NetIoPtr->WriteAstFunction || \
    (sesptr)->SslStateFunction)

#define SESOLA_NETIO_READ_IN_PROGRESS(sesptr) \
   ((sesptr)->NetIoPtr->ReadAstFunction || \
    (sesptr)->SslStateFunction)

#define SESOLA_NETIO_WRITE_IN_PROGRESS(sesptr) \
   ((sesptr)->NetIoPtr->WriteAstFunction || \
    (sesptr)->SslStateFunction)

/*******************/
/* data structures */
/*******************/

#pragma member_alignment __save
#pragma member_alignment

typedef struct SesolaStruct SESOLA_STRUCT;

struct SesolaStruct
{
   /* OpenSSL structures */
   SSL  *SslPtr;
   BIO  *BioPtr;
   SSL_CTX  *SslCtx;
   X509  *ClientCertPtr,
         *ConnectCertPtr;

   REQUEST_STRUCT  *RequestPtr;
   PROXY_TASK  *ProxyTaskPtr;

   /* pointer to the NETIO structure */
   NETIO_STRUCT  *NetIoPtr;

   BOOL  CertVerifyFailed,
         HTTPduringHandshake,
         ReadClientCert,
         ReadInProgress,
         ReadIsComplete,
         SNIctxSet,
         SNIserviceSet,
         SSHduringHandshake,
         WriteInProgress,
         WriteIsComplete,
         X509CertRequested,
         X509optionalNoCa;

   int  /* simple count of how many times verify callback has been called */
        CertVerifyCallbackCount,
        /* depth client certificates are to be verified to */
        CertVerifyDepth,
        /* value of verify type initially passed to the function */
        CertVerifyMode,
        /* count of data read so far */
        ReadCount,
        /* size of read data buffer (for AST routine) */
        ReadSize,
        /* sort of a 'state' flag */
        ReportClientCertState,
        /* keep a check on unusual Sesola_read behaviours */
        Sesola_read_ErrorCount,
        /* keep a check on unusual Sesola_write behaviours */
        Sesola_write_ErrorCount,
        /* [LT:integer] value stored until needed */
        SessionLifetimeMinutes,
        /* [TO:integer] value stored until needed */
        SessionTimeoutMinutes,
        /* keep a check on how many times we try */
        SslAcceptCount,
        /* ditto */
        SslConnectCount,
        /* ditto */
        SslShutdownCount,
        /* request data (likely PROPFIND/PUT/POSTed) before renegotiate */
        VerifyPeerDataCount,
        /* count is when emptying and size is the amount of data */
        VerifyPeerDataSize,
        /* when non-zero this status value is returned (e.g. SS$_CANCEL) */
        VmsStatus,
        /* if the parent being WATCHed */
        WatchItem,
        /* number of characters written so far */
        WriteCount,
        /* number of octets to be written to network */
        WriteLength;

   int64  /* number of I/Os (reset with each stats update) */
          BlocksTallyRx64,
          /* number of bytes I/Oed (reset with each stats update) */
          BytesTallyRx64,
          /* number of I/Os (reset with each stats update) */
          BlocksTallyTx64,
          /* number of bytes I/Oed (reset with each stats update) */
          BytesTallyTx64;

   char  /* selected ALPN protocol */
         *ALPNok,
         /* read buffer */
         *ReadPtr,
         /* QIO buffer */
         *ReadRawPtr,
         /* request data buffer during renegotiation */
         *VerifyPeerDataPtr,
         /* next request data when being reinserted into application stream */
         *VerifyPeerReadPtr,
         /* write buffer */
         *WritePtr,
         /* QIO buffer */
         *WriteRawPtr,
         /* pointer to hold position when parsing the X509 param="" */
         *X509ConditionalPtr;

   char  /* buffer this information when getting a client certificate */
         ReportVirtualHostPort [128],
         /* SNI supplied server name */
         SNIServerName [128],
         /* source of X.509 remote-user, record from subject DN of cert */
         X509RemoteUserDnRecord [AUTH_MAX_USERNAME_LENGTH];

   IO_SB  ReadIOsb,
          WriteIOsb;

   /* SSL post-processing, stores the pointer to the AST routine */
   GENERAL_AST  ClientCertAstFunction,
                ReportNextTaskFunction,
                SslStateFunction;
};

typedef struct SesolaTicketKeyStruct SESOLA_TICKET_KEY;

struct SesolaTicketKeyStruct
{
    uchar  AesKey [16],
           HmacKey [16],
           NameKey [16];
    int64  AtTime64;
};

typedef struct SesolaSessionCacheRecordStruct SESOLA_SESSION_CREC;

struct SesolaSessionCacheRecordStruct
{
    int  SessDataLength,
         SessIdLength,
         TimeoutTickSecond;
    int64  CachedTime64;
    uchar  SessId [SSL_MAX_SSL_SESSION_ID_LENGTH];

    /* session DER is stored from here onwards */
    char  SessData [];
};

typedef struct SesolaGblSecStruct SESOLA_GBLSEC;

struct SesolaGblSecStruct
{
   ulong  GblSecVersion,
          GblSecLength;

   int  CacheHitCount,
        CacheMissCount,
        CacheRecordCount,
        CacheFullCount,
        CacheTimeoutCount;
   int64  SinceTime64;

    /* session cache records are stored from this point onwards */
   char  CacheRecordPool [];
};

#pragma member_alignment __restore

/***********************/
/* function prototypes */
/***********************/

/* SESOLA.C */

#if OPENSSL_VERSION_NUMBER < 0x10101000L
#if OPENSSL_VERSION_NUMBER < 0x10100000L
# define OPENSSL_VERSION        SSLEAY_VERSION
# define OPENSSL_CFLAGS         SSLEAY_CFLAGS
# define OPENSSL_BUILT_ON       SSLEAY_BUILT_ON
# define OPENSSL_PLATFORM       SSLEAY_PLATFORM
# define OPENSSL_DIR            SSLEAY_DIR
const char *OpenSSL_version(int);
#endif
unsigned long OpenSSL_version_num(void);
#endif

int SesolaALPNCallback (SSL*, uchar **out, uchar*, uchar*, uint, void*);
char* SesolaCertFingerprint (void*, EVP_MD*(*)(void), char*, int);
int SesolaGetWatch (SESOLA_STRUCT*);
void SesolaInitCertFile (SERVICE_STRUCT*);
void SesolaInitContext (char*, SESOLA_CONTEXT*);
uint SesolaInitOptions (char*, uint*);
void SesolaControlReloadCA ();
void SesolaControlReloadCerts ();
SesolaError (REQUEST_STRUCT*, char*);
int SesolaInitGetServerName();
int SesolaInitGetServerNameHandler();
int SesolaPrivateKeyPasswd (char*, int, int, void*);
SesolaInit ();
SesolaInitService (SERVICE_STRUCT*);
SesolaReport (REQUEST_STRUCT*, char*);
SesolaReportCA (REQUEST_STRUCT*, char*);
SesolaReportFormatCertName (char*, char*, int);
void SesolaMemTrackReset (void);
char* SesolaOptionsAsString (ulong*);
char* SesolaRequestCipher (SESOLA_STRUCT*);
BOOL SesolaRequestSessionReused (SESOLA_STRUCT*);
char* SesolaRequestVersion (SESOLA_STRUCT*);
int SesolaServiceCount ();
int SesolaSessionTicketCallback (SSL*, uchar*, uchar*,
                                 EVP_CIPHER_CTX*, HMAC_CTX*, int);
uchar* SesolaSessionTicketNewKey ();
uchar* SesolaSessionTicketUseKey (uchar*);
void* SesolaRequestSesolaPtr (REQUEST_STRUCT*);
DH* SesolaTmpDHCallback (SSL*, int, int);
RSA* SesolaTmpRSACallback (SSL*, int, int);
void SesolaSetWatch (SESOLA_STRUCT*, int);
int SesolaSNICallback (SSL*, int*, void*);
BOOL SesolaSNIserviceSet (SESOLA_STRUCT*);
char* SesolaVersion (BOOL);
void SesolaWatchPeek (REQUEST_STRUCT*, void*);
int SesolaWatchBioCallback (BIO*, int, char*, int, long, long);
SesolaWatchErrors (SESOLA_STRUCT*);
SesolaWatchInfoCallback (SSL*, int, int);
SesolaWatchSession (SESOLA_STRUCT*);

#if SESOLA_MEMORY
void SesolaMemoryFree (void*);
void SesolaMemoryInit ();
void* SesolaMemoryMalloc (size_t);
void* SesolaMemoryRealloc (void*, size_t);
#endif /* SESOLA_MEMORY */
void SesolaMemoryControl (int, char*, int);
void SesolaMemoryEvery ();
char* SesolaMemoryReport ();
char* SesolaMemTrackReport (void);
void SesolaFree (void*);
void* SesolaMalloc (int);
void* SesolaRealloc (void*, int);

/* SESOLACACHE.C */

int SesolaCacheInit ();
int SesolaCacheAddRecord (SSL*, SSL_SESSION*);
SSL_SESSION* SesolaCacheFindRecord (SSL*, uchar*, int, int*);
SesolaCacheGblSecInit ();
int SesolaCacheRemoveRecord (SSL_CTX*, SSL_SESSION*);
int SesolaCacheStats (REQUEST_STRUCT*);

/* SESOLACERT.C */

char* SesolaCertExtension (void*, char*);
char* SesolaCertExtension2 (void*, char*);
uchar* SesolaCertFind (uchar*, uchar*, uchar**);
uchar* SesolaCertKeyword (uchar*);
char* SesolaCertName (void*, char*);
char* SesolaCertParseDn (char*, char*);
int SesolaCertReportDn (char*, char*, int);
int SesolaCertReportName (void*, char*, char*, int);
int SesolaCertReportExtension (void*, char*, int);
int SesolaCertVerifyCallback (int, void*);

/* SESOLACGI.C */

SesolaCgiGenerateVariables (REQUEST_STRUCT*, int);
SesolaCgiVariablesApacheModSsl (REQUEST_STRUCT*, int);
SesolaCgiVariablesExtension (REQUEST_STRUCT*, int);
SesolaCgiVariablesPurveyor (REQUEST_STRUCT*, int);

/* SESOLACLIENT.C */

int SesolaClientCert (REQUEST_STRUCT*, int, REQUEST_AST);
void SesolaClientCertEnd (REQUEST_STRUCT*);
int SesolaClientCertConditional (REQUEST_STRUCT*, char*);
BOOL SesolaClientCertMetaCon (REQUEST_STRUCT*, METACON_LINE*, int);
int SesolaClientCertRequestData (SESOLA_STRUCT*);
char* SesolaClientCertRemoteUser (REQUEST_STRUCT*);
void SesolaClientCertGet (SESOLA_STRUCT*);

/* SESOLAMKCERT.C */

char* SesolaMkCert (char*);

/* SESOLANET.C */

SesolaNetAccept (SESOLA_STRUCT*);
void SesolaNetBegin (REQUEST_STRUCT*);
void SesolaNetBeginFail (SESOLA_STRUCT*);
SesolaNetClientBegin (PROXY_TASK*);
SesolaNetClientConnect (SESOLA_STRUCT*);
SesolaNetClientShutdown (SESOLA_STRUCT*);
void SesolaNetEnd (SESOLA_STRUCT*);
SesolaNetClientFree (PROXY_TASK*);
void SesolaNetFree (SESOLA_STRUCT*);
void SesolaNetSetProxyTask (PROXY_TASK*);
char* SesolaNetStats (void);
void SesolaNetThisIsSSL (SESOLA_STRUCT*);
int Sesola_read (BIO*, char*, int);
int Sesola_read_ast (SESOLA_STRUCT*);
int Sesola_write (BIO*, char*, int);
int Sesola_write_ast (SESOLA_STRUCT*);
int Sesola_puts (BIO*, char*);
int Sesola_gets (BIO*, char*, int);
long Sesola_ctrl (BIO*, int, long, char*);
BIO_METHOD *BIO_s_Sesola();

/* SESOLANETIO.C */

void SesolaNetIoCancel (NETIO_STRUCT*);
BOOL SesolaNetIoInProgress (NETIO_STRUCT*);
int SesolaNetIoRead (NETIO_STRUCT*, void*, int);
void SesolaNetIoReadAst (NETIO_STRUCT*);
void SesolaNetIoReset (NETIO_STRUCT*);
int SesolaNetIoWrite (NETIO_STRUCT*, void*, int);
void SesolaNetIoWriteAst (NETIO_STRUCT*);
int Sesola_netio_read (BIO*, char*, int);
int Sesola_netio_read_ex (BIO*, char*, int, int*);
int Sesola_netio_write (BIO*, char*, int);
int Sesola_netio_write_ex (BIO*, char*, int, int*);
void Sesola_netio_read_ast (SESOLA_STRUCT*);
void Sesola_netio_write_ast (SESOLA_STRUCT*);

/*********************/
#else  /* not SESOLA */
/*********************/

#ifdef SESOLA_MEMORY
#undef SESOLA_MEMORY
#endif

BOOL SesolaInitClientService (SERVICE_STRUCT *);
SesolaCgiGenerateVariables (REQUEST_STRUCT*, int);

/* these need to be here only for WATCH.C to resolve the references */
void SesolaNetIoReadAst (void*);
void SesolaNetIoWriteAst (void*);
void Sesola_netio_read_ast (void*);
void Sesola_netio_write_ast (void*);
int SesolaMkCertBegin ();

/************************/
#endif  /* ifdef SESOLA */
/************************/

#endif /* SESOLA_H_LOADED */

/*****************************************************************************/