Renegotiate is exactly the same, except it will redo the negotiation if a connection is established. Renegotiate is currently NOT supported.
- pISSL:The Interface pointer
- pinfo:Place to put the response structure
- pCerts:Place for ISSL to return cert chain.
- pcb:Place to call back when SSL, succeeds, fails or needs help pOpts or ... : The set of WebOpt options against which negotiation is performed.
void ISSL_Negotiate ( ISSL *pISSL, SSLInfo *pinfo, IX509Chain **pCerts, AEECallback *pcb, ... ); void ISSL_NegotiateV ( ISSL *pISSL, SSLInfo *pinfo, IX509Chain **pCerts, AEECallback *pcb, WebOpts *pOpts ); void ISSL_Renegotiate ( ISSL *pISSL, SSLInfo *pinfo, IX509Chain *pCerts, AEECallback *pcb, ... ); void ISSL_RenegotiateV ( ISSL *pISSL, SSLInfo *pinfo, IX509Chain **pCerts, AEECallback *pcb, WebOpts *pOpts );
When evaluating parameters for the negotiation, the options passed as arguments to ISSL_Negotiate() are considered first. Note that these may include a default IWebOpts that contains a whole tree of options. The ones stored in ISSL are considered next. These options are used for the SSL negotiation to determine cipher suite, protocol, version and other. They are also passed to the IX509Chain instance internally as options for the cert chain verification. That is you can and should add/pass IX509Chain options here. In particular you should pass the root certs set and the hostname.
If you want the IX509Chain instance returned so you can examine the certs in the chain or store them, then you can either pass a non-NULL parameter for pCerts or set the WebOpt that causes the interface to be put in a WebOpt.
The negotiation has different behaviors depending on the state of the connection, WEBOPT_SSL_TRUST_MODE, and whether negotiation or renegotiate is called. The three connections states are unsecured, suspended negotiation and secured.
In the unsecured state the description of WEBOPT_SSL_TRUST_MODE above applies to a call to negotiate or renegotiate. Normally on a trust error ISSL closes the connection to the server and cannot be overridden. This is the case if WEBOPT_SSL_TRUST_MODE is not set or if it is set to SSL_TRUST_MODE_FAIL. If WEBOPT_SSL_TRUST_MODE is set to SSL_TRUST_MODE_CHECK, the connection is not closed. ISSL_Negotiate can then be called again, most likely with some TrustOverrides to continue with the SSL session despite the trust error. If it is set to SSL_TRUST_MODE_IGNORE, then all trust errors are ignored at substantial risk to the connection security. If the mode is SSL_TRUST_MODE_ALWAYS, the call back will always fire after the trust check is complete. This allows you to examine the trust chain and reject it even if the chaining engine is able to successfully validate it.
A possible mode of operation is to use SSL_TRUST_MODE_CHECK on the first call to negotiate, and after checking the trust errors to use SSL_TRUST_MODE_IGNORE on the second call to negotiate. If you set SSL_TRUST_IGNORE on the first call to negotiate you are defeating most of SSL's security! The following are the possible trust modes:
SSL_TRUST_MODE_FAIL: Default, fail on trust errors SSL_TRUST_MODE_CHECK: Suspend on trust error so they can be checked and ignored SSL_TRUST_MODE_IGNORE: Ignore all trust errors SSL_TRUST_MODE_ALWAYS: Always suspend so trust can always be checked.
Once in the suspended state, any call to negotiate or renegotiate will continue the negotiation to success or failure.
Calls in the secured state are where it gets unusual and interesting. If renegotiate is supported and is called in the secured state, then a new negotiation takes place.
If you call negotiate in the secured state, the security level of the connection is evaluated against the security level implied by the various options, in particular the cipher suites and root certs. If it matches, then success is returned, otherwise failure. On either success or failure the connection it self is not disturbed. The purpose of this is to evaluate a kept-alive session for reuse. Though this is not commonly done it is used by the internal https implementation.
If the WEBOPT_SSL_SESSIONDB option is set to an instantiated IRecordStore interface, the interface is used to store and fetch session resumption data. When a negotiation is successful, a record is stored in the database/cache provided by this interface via an add call. Before a negotiation is attempted, Lookup calls to this database/cache are performed to find any previously stored sessions. The sessions may be stored for the life of the app or for longer. If they are stored longer, care should be taken as the records contain the master secret from the session.
When the negotiation completes, examine the pinfo structure to get details. If using the ISocket interface, the secured ISocket is contained in this structure. This ISocket can be used like any other ISocket. Any IOCTLs that are not handled by ISSL are passed on to the ISocket passed in to ISSL_SetSocket(). Calling ISOCKET_Release() on this pointer is equivalent to calling ISSL_Release().
If using the IPort interface, calling ISSL_QueryInterface() with AEECLSID_PORT at this point retrieves the secured IPort interface. Calling IPORT_Release() on this pointer is equivalent to calling ISSL_Release().
The following summarizes WebOpts that affect negotiation. Note that all the WebOpts that affect IX509CHAIN_Verify() also affect negotiation.
WEBOPT_SSL_SEC_INFO An alternate way to get the SSLInfo result of a negotiation. This is useful with IWeb and HTTPS. WEBOPT_SSL_TRUST_MODE Specify general behavior on trust errors. WEBOPT_SSL_ALLOWED_CIPHER_SUITES Multiple options to give an ordered list of cipher suites to be allowed for the negotiation. Must be one of SSL_CSUITE_*. If not provided, the SSL negotiation chooses the strongest common cipher suite. WEBOPT_SSL_CIPHER_MAP Multiple options to remap the cipher implementation. This allows overriding the ICipher implementation, which defaults to the best implementation as determined by the ICipherFactory. This webopt takes the SSLCipherMap structure to define the mapping. uCryptAlgo must be one of SSL_CRYPT_* and uImplCls must be a cipher AEECLSID which implements the SSL_CRYPT_* algorithm. This option does not affect the cipher suite negotiation (See WEBOPT_SSL_ALLOWED_CIPHER_SUITES). WEBOPT_SSL_ALLOWED_VERSIONS Multiple options to give an ordered list of protocol versions to be allowed for the negotiation. Must be one of SSL_VERSION_*. If this is not specified, ISSL defaults to allowing all supported versions. WEBOPT_SSL_WANT_X509_CHAIN Set this option to get the X509Chain created internally back in the web opt below. This allows you to examine the cert chain, display it or save it. If you set the chain which uses memory to store all the certs will persist until this interface is destroyed, or the option deleted. WEBOPT_SSL_RSA_IMPLEMENTATION This option allows the client to specify the RSA implementation to be used. For example, some platforms may allow support for hardware based modular exponentiation, and the client may use this option to take advantage of this capability in order to improve performance. WEBOPT_SSL_X509_CHAIN The option in which a reference to the IX509Chain object used internally will be returned. This is a single value and should not be set. WEBOPT_SSL_SESSIONDB The instantiated interface for session resumption. This must be an interface to an IRecordStore, such a IRamCache. If this is not set or set to NULL then there will be no session resumption.
During the Negotiation operation, ISSL may need extra information from the client (ex: client certificates during client authentication). If a negotiation handler function is supplied using WEBOPT_SSL_NEGOTIATE_HANDLER WebOpt, then it will be called with the error code, so that the user can supply more information.