diff -r 000000000000 -r af10295192d8 networksecurity/tls/secsock/SecureSocket.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/networksecurity/tls/secsock/SecureSocket.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,796 @@ +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Describes the implementation of a secure socket class. +// +// + +/** + @file +*/ + +#include "SecureSocket.h" +#include "GenericSecureSocket.h" +#include + +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#include +#endif + +#include +#include + +using namespace CommsDat; + +TInt SetTLSData(void); + +#define LOADDLL_ORIG_ORDINAL 1 +#define UNLOADDLL_ORDINAL 2 +#define LOADDLL_NEW_ORDINAL 3 + +TSecSocketProtocol::~TSecSocketProtocol() +/** + * Closes the DLL library. + */ +{ + iLibrary.Close(); +} + +TInt CSecureSocketLibraryLoader::OpenL(const TDesC& aProtocolName,TSecSockDllLibraryFunction& aEntryPoint) +/** + * Opens the protocol library. + * Attempts to load the secure socket implementation DLL for the requested + * protocol type. + * + * @param aProtocolName A reference to a descriptor containing the protocol name, + * i.e. tls1.0, ssl3.0. Case is ignored. + * @param aEntryPoint Entry point into the secureSocket plug-in. + * @return KErrNone, if successful; otherwise, another of the system-wide error codes. + */ + { + TLibraryFunction entry; + + CSecureSocketLibraryLoader::OpenWithIdL(LOADDLL_ORIG_ORDINAL, aProtocolName, entry); + aEntryPoint = reinterpret_cast(entry); + if(!aEntryPoint) + { + return KErrNotFound; + } + + return KErrNone; + } + + +TInt CSecureSocketLibraryLoader::OpenL(const TDesC& aProtocolName,TSecSockDllLibraryGenericFunction& aEntryPoint) +/** + * Opens the protocol library. + * Attempts to load the secure socket implementation DLL for the requested + * protocol type. + * + * @param aProtocolName A reference to a descriptor containing the protocol name, + * i.e. tls1.0, ssl3.0. Case is ignored. + * @param aEntryPoint Entry point into the secureSocket plug-in. + * @return KErrNone, if successful; otherwise, another of the system-wide error codes. + */ + { + TLibraryFunction entry; + + CSecureSocketLibraryLoader::OpenWithIdL(LOADDLL_NEW_ORDINAL, aProtocolName, entry); + aEntryPoint = reinterpret_cast(entry); + if(!aEntryPoint) + { + return KErrNotFound; + } + + return KErrNone; + } + + +void CSecureSocketLibraryLoader::OpenWithIdL(TInt aId, const TDesC& aProtocolName, TLibraryFunction& aEntryPoint) +/** + * Opens the protocol library. + * Attempts to load the secure socket implementation DLL for the requested + * protocol type. + * + * @param aProtocolName A reference to a descriptor containing the protocol name, + * i.e. tls1.0, ssl3.0. Case is ignored. + * @param aEntryPoint Entry point into the secureSocket plug-in. + * @return KErrNone, if successful; otherwise, another of the system-wide error codes. + */ +{ + //Fetch the TLS data + TSecureSocketGlobals* global = (TSecureSocketGlobals*)Dll::Tls(); + if ( !global ) + { + if (SetTLSData() == KErrNone) + global = (TSecureSocketGlobals*)Dll::Tls(); + } + __ASSERT_ALWAYS(global,User::Leave(KErrNoMemory)); + + // Increase the globals use count + global->iUseCount++; + + // Convert to lower case before doing a comparison + TBuf<32> protocol; + protocol.Copy(aProtocolName); + protocol.LowerCase(); + + //Walk the list and find the protocol + global->iSecureSocketProtocolsIter.SetToFirst(); + TSecSocketProtocol* secProtocol; + while ((secProtocol = global->iSecureSocketProtocolsIter++) != NULL) + { + if(secProtocol->iName.Compare(protocol)) + //Found a matching protocol name + break; + } + + if(secProtocol == NULL) + //Library not loaded yet - Find a dll name in Commdb that matches proto name + //and load the dll + { + secProtocol = new(ELeave)TSecSocketProtocol; + CleanupStack::PushL(secProtocol); + //Find the protocolname record in COMMDB + TBuf fileName; + FindItemInDbL(protocol, fileName); + + // Load the library whose name we just fetched + // Commented out the line below as it loads the SSLADAPTOR.DLL + // Hardcoded the SSL.DLL. SSL.DLL ultimately should be an ECOM Plugin. + // (These changes were made as part of GT167 Zephyr work on TLS. + //(void)User::LeaveIfError(secProtocol->iLibrary.Load(fileName)); + (void)User::LeaveIfError(secProtocol->iLibrary.Load(_L("SSL.DLL"))); + + + //Add the entry in the list + secProtocol->iName.Copy(protocol); + global->iSecureSocketProtocols.AddLast(*secProtocol); + CleanupStack::Pop(); + } + + // Get the pointer to the NewL function in the DLL + aEntryPoint = secProtocol->iLibrary.Lookup(aId); + +} + +void CSecureSocketLibraryLoader::FindItemInDbL(const TDesC& aProtocolName, TDes& aLibraryName) +/** + * Opens the Commdb and locates the DLL name for a protocol. + * + * @param aProtocolName A reference to a descriptor containing the protocol name, + * i.e. tls1.0, ssl3.0. Case is ignored. + * @param aLibraryName On return, name of the library. + * @exception This function will leave if the protocol was not found or in OOM conditions. + */ +{ + +#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY + CMDBSession* session = CMDBSession::NewL(KCDVersion1_2); +#else + CMDBSession* session = CMDBSession::NewL(KCDVersion1_1); +#endif + CleanupStack::PushL(session); + CCDSecureSocketRecord* ptrRecord = static_cast(CCDRecordBase::RecordFactoryL(KCDTIdSSProtoRecord)); + CleanupStack::PushL(ptrRecord); + ptrRecord->iSSProtoName = aProtocolName; + // check if any record is returned back + if (!ptrRecord->FindL(*session)) + { + // ignore return from FindL otherwise tests fail + //User::Leave(KErrNotFound); + } + + aLibraryName = ptrRecord->iSSProtoLibrary; + CleanupStack::PopAndDestroy(ptrRecord); + CleanupStack::PopAndDestroy(session); +} + +EXPORT_C void CSecureSocketLibraryLoader::Unload() +/** + * Closes and unloads the implementation library. + */ +{ + //Fetch the TLS data + TSecureSocketGlobals* global = (TSecureSocketGlobals*)Dll::Tls(); + + //Cannot assume that tls exists at this point (False with WINS) + if(!global) + return; + + // if the use count isn't 0, don't do the unload + if ( --global->iUseCount ) + return; + + //Walk the list and find the protocol + global->iSecureSocketProtocolsIter.SetToFirst(); + TSecSocketProtocol* secProtocol; + + while ((secProtocol = global->iSecureSocketProtocolsIter++) != NULL) + { + //Find the entry point for the resource cleanup function + TSecSockDllUnloadFunction cleanupEntryPoint = reinterpret_cast (secProtocol->iLibrary.Lookup(UNLOADDLL_ORDINAL)); + //Call the function + if(cleanupEntryPoint) + (*cleanupEntryPoint)(NULL); + global->iSecureSocketProtocols.Remove(*secProtocol); + delete secProtocol; + } + // remove the globals reference + delete global; + Dll::SetTls(NULL); // @bug check ret val +} + +EXPORT_C CSecureSocket* CSecureSocket::NewL(RSocket& aSocket,const TDesC& aProtocol) +/** + * Creates and returns a pointer to a new secure socket. + * + * A reference to an already open and connected socket should be passed in, + * along with a descriptor that contains the protocol name. + * + * @param aSocket A reference to an open and connected RSocket object. + * @param aProtocol A constant descriptor containing the protocol name. + * @return A pointer to the newly created secure socket, or NULL if the creation failed. + */ +{ + CSecureSocket* self = new(ELeave) CSecureSocket; + CleanupStack::PushL( self ); + self->ConstructL(aSocket,aProtocol); + CleanupStack::Pop(); + return self; +} + +EXPORT_C CSecureSocket* CSecureSocket::NewL(MGenericSecureSocket& aSocket,const TDesC& aProtocol) +/** + * Creates and returns a pointer to a new secure socket. + * + * A reference to a socket derived from MGenericSecureSocket should be passed in, + * along with a descriptor that contains the protocol name. + * + * @param aSocket A reference to an MGenericSecureSocket derived object. + * @param aProtocol A constant descriptor containing the protocol name. + * @return A pointer to the newly created secure socket, or NULL if the creation failed. + */ +{ + CSecureSocket* self = new(ELeave) CSecureSocket; + CleanupStack::PushL( self ); + self->ConstructL(aSocket,aProtocol); + CleanupStack::Pop(); + return self; +} + +void CSecureSocket::ConstructL(RSocket& aSocket, const TDesC& aProtocol) +/** + * Standard 2-phase construction. + */ +{ + TSecSockDllLibraryFunction libEntryPointL; + User::LeaveIfError(CSecureSocketLibraryLoader::OpenL(aProtocol,libEntryPointL)); + //Beware! the following call can leave... + iSecureImplementation = (MSecureSocket*)libEntryPointL( aSocket, aProtocol ); + if (iSecureImplementation) + { + iSecureSocketState = ESecureSocketStateOpen; + } + +} + +void CSecureSocket::ConstructL(MGenericSecureSocket& aSocket, const TDesC& aProtocol) +/** + * Standard 2-phase construction. + */ +{ + TSecSockDllLibraryGenericFunction libEntryPointL; + User::LeaveIfError(CSecureSocketLibraryLoader::OpenL(aProtocol,libEntryPointL)); + //Beware! the following call can leave... + iSecureImplementation = (MSecureSocket*)libEntryPointL( aSocket, aProtocol ); + if (iSecureImplementation) + { + iSecureSocketState = ESecureSocketStateOpen; + } +} + +CSecureSocket::~CSecureSocket() +/** + *Standard destructor. + */ +{ + if ((iSecureImplementation) && (iSecureSocketState == ESecureSocketStateOpen)) + { + iSecureImplementation->Close(); + } + + delete iSecureImplementation; + // Close and unload the implementation library, Unload checks access count first + CSecureSocketLibraryLoader::Unload(); +} + + +// +EXPORT_C TInt CSecureSocket::AvailableCipherSuites( TDes8& aCiphers ) +/** + * Gets the available cipher suites. + * + * Note that ciphersuites using NULL encryption or PSK key exchange will not be included + * unless they have been enabled via SetOpt. + * + * @param aCiphers Descriptor holding the ciphers. + * @return KErrNone if successful, a system-wide error code if not. + */ +{ + return iSecureImplementation->AvailableCipherSuites( aCiphers ); +} + +EXPORT_C void CSecureSocket::CancelAll() +/** + *Cancels all the send and receive actions in the SSL state machine. + */ +{ + iSecureImplementation->CancelAll(); +} + +EXPORT_C void CSecureSocket::CancelHandshake() +/** + *Cancels the handshake. + */ +{ + iSecureImplementation->CancelHandshake(); +} + +EXPORT_C void CSecureSocket::CancelRecv() +/** + * Cancels a receive action in the SSL state machine. + */ +{ + iSecureImplementation->CancelRecv(); +} + +EXPORT_C void CSecureSocket::CancelSend() +/** + *Cancels a send action in the SSL state machine. + */ +{ + iSecureImplementation->CancelSend(); +} + +EXPORT_C const CX509Certificate* CSecureSocket::ClientCert() +/** + * Gets the current client certificate. + * + * When a secure socket is acting in server mode, the returned certificate will + * be the certificate that the remote client provided. When acting in client mode, + * the certificate returned will be local certificate. + * + * @return A pointer to the client certificate, or NULL if none exists. + */ +{ + return iSecureImplementation->ClientCert(); +} + +EXPORT_C TClientCertMode CSecureSocket::ClientCertMode() +/** + * Gets the current client certificate mode. + * + * The client certificate mode is used when the socket is acting as a server, + * and determines whether a client certificate is requested. + * + * @return The current mode that is set. + */ +{ + return iSecureImplementation->ClientCertMode(); +} + +EXPORT_C TDialogMode CSecureSocket::DialogMode() +/** + * Gets the current dialog mode. + * + * @return The current dialog mode. + */ +{ + return iSecureImplementation->DialogMode(); +} + +EXPORT_C void CSecureSocket::Close() +/** + * Closes the secure connection and the socket. + * + * Implementations should terminate the secure connection gracefully as + * appropriate to their protocol. The RSocket object is not destoyed: + * this is left to the client application. + */ +{ + iSecureSocketState = ESecureSocketStateClosed; + iSecureImplementation->Close(); +} + +EXPORT_C TInt CSecureSocket::CurrentCipherSuite( TDes8& aCipherSuite ) +/** + * Gets the current cipher suite in use. + * + * The current cipher suite is returned in the referenced buffer + * in two byte format as, i.e. [0x??][0x??]. + * + * @param aCipherSuite A reference to a descriptor at least 2 bytes long. + * Implementations that differ from the [0x??][0x??] + * format may require larger descriptors. See individual + * implementation notes for details. + * @return KErrNone if successful; + * otherwise, another of the system-wide error codes. + */ +{ + return iSecureImplementation->CurrentCipherSuite( aCipherSuite ); +} + +EXPORT_C void CSecureSocket::FlushSessionCache() +/** + *Flushes the session cache. + */ +{ + iSecureImplementation->FlushSessionCache(); +} + +EXPORT_C TInt CSecureSocket::GetOpt(TUint aOptionName, TUint aOptionLevel, TDes8& aOption) +/** + * Gets an option. + * + * Secure socket implementations may provide options that can + * be used with this function. + * + * (nb. Getting the KSoServerNameIndication option is not supported). + * + * @param aOptionName An integer constant which identifies an option. + * @param aOptionLevel An integer constant which identifies the level of an option, + * i.e. an option level group of related options. + * @param aOption An option value packaged in a descriptor. + * @return KErrNone if successful; + * otherwise, another of the system-wide error codes. + */ +{ + return iSecureImplementation->GetOpt(aOptionName, aOptionLevel, aOption); +} + +EXPORT_C TInt CSecureSocket::GetOpt(TUint aOptionName, TUint aOptionLevel, TInt& aOption) +/** + * Gets an option. + * + * Secure socket implementations may provide options that can + * be used with this method. + * + * (nb. Getting the KSoServerNameIndication option is not supported). + * + * @param aOptionName An integer constant which identifies an option. + * @param aOptionLevel An integer constant which identifies the level of an option, + * i.e. an option level group of related options. + * @param aOption An integer option value. + * @return KErrNone if successful; + * otherwise, another of the system-wide error codes. + */ +{ + return iSecureImplementation->GetOpt(aOptionName, aOptionLevel, aOption); +} + +EXPORT_C TInt CSecureSocket::Protocol(TDes& aProtocol) +/** + * Gets the protocol in use. + * + * This method can be used to return the particular protocol/version that is + * being used by implementations that support different protocols/versions. + * + * @param aProtocol A descriptor containing the protocol name/version that is + * being used. Protocol names can be up to 32 characters long, + * and so a descriptor of at least that size is required. + * @return KErrNone + */ +{ + return iSecureImplementation->Protocol( aProtocol ); +} + +EXPORT_C void CSecureSocket::Recv (TDes8& aDesc, TRequestStatus& aStatus ) +/** + * Receives data from the socket. + * + * This is an asynchronous function, and completes + * when the descriptor has been filled. Only one Recv() or RecvOneOrMore() + * operation can be outstanding at any time. + * + * @param aDesc A descriptor where data read will be placed. + * @param aStatus On completion, KErrNone if successful; + * KErrEof if a remote connection is closed and there is no more data; + * KErrNotReady if called when an operation is still outstanding; + * or another system-wide error code. + */ +{ + iSecureImplementation->Recv( aDesc, aStatus ); +} + +EXPORT_C void CSecureSocket::RecvOneOrMore( TDes8& aDesc, TRequestStatus& aStatus, TSockXfrLength& aLen ) +/** + * Receives data from the socket. + * + * This is an asynchronous function, and will complete when at least one byte has been read. + * Only one Recv() or RecvOneOrMore() operation can be outstanding at any time. + * + * @param aDesc A descriptor where data read will be placed. + * @param aStatus On completion, KErrNone if successful; + * KErrEof if a remote connection is closed and there is no more data; + * KErrNotReady if called when an operation is still outstanding; + * or another system-wide error code. + * @param aLen On completion, the length of the descriptor, aDesc. + */ +{ + iSecureImplementation->RecvOneOrMore( aDesc, aStatus, aLen ); +} + +EXPORT_C void CSecureSocket::RenegotiateHandshake(TRequestStatus& aStatus ) +/** + * Initiates a renegotiation of the secure connection. + * + * This is an asynchronous function that completes when renegotiation is complete. + * It is valid for both client and server operation. There can only be one outstanding + * RenegotiateHandshake() operation at a time. + * + * @param aStatus On completion, KErrNone if successful; + * KErrNotReady if called when an operation is still outstanding; + * or another system-wide error code. + */ +{ + iSecureImplementation->RenegotiateHandshake( aStatus ); +} + +EXPORT_C void CSecureSocket::Send( const TDesC8& aDesc, TRequestStatus& aStatus, TSockXfrLength& aLen ) +/** + * Sends data over the socket. + * + * This is an asynchronous function. Only one Send() operation can be outstanding at any time. + * + * @param aDesc A constant descriptor with the data to be send. + * @param aStatus On completion, KErrNone if successful; + * KErrNotReady if called when an operation is still outstanding; + * or another system-wise error code. + * @param aLen On completion, the amount of data sent. + */ +{ + iSecureImplementation->Send( aDesc, aStatus, aLen ); +} + +EXPORT_C void CSecureSocket::Send( const TDesC8& aDesc, TRequestStatus& aStatus ) +/** + * Sends data over the socket. + * + * This is an asynchronous function. Only one Send() operation can be outstanding + * at any time, and the function will complete with the error KErrNotReady if called + * when a send is still outstanding. + * + * @param aDesc A constant descriptor. The application must not modify this + * descriptor until the Send() completes. + * @param aStatus On completion, KErrNone; + * KErrNotReady if called when a send is still outstanding, if successful; + * or another system-wide error code. + */ +{ + iSecureImplementation->Send( aDesc, aStatus ); +} + +EXPORT_C const CX509Certificate* CSecureSocket::ServerCert() +/** + * Gets the current server certificate. + * + * When a secure socket is acting in client mode, the returned certificate will be + * the certificate for the remote server. When acting in server mode, the certificate + * returned will be the local certificate. + * + * Note that the operation in server mode is currently reserved for future use, + * and returns NULL. + * + * @return Pointer to the certificate, or NULL if no certificate is available. + */ +{ + return iSecureImplementation->ServerCert(); +} + +EXPORT_C TInt CSecureSocket::SetAvailableCipherSuites(const TDesC8& aCiphers) +/** + * Sets the list of cipher suites that are available for use. + * + * The list of cipher suites should be supplied in a descriptor in the format + * as per the TLS RFC, i.e. [0x??][0x??] for each suite. The order of suites is + * important, and so they should be listed with the preferred suites first. + * + * Note that ciphersuites using NULL encryption or PSK key exchange will be considered + * unsupported unless these features have been enabled via SetOpt. + * + * Unsupported ciphersuites are silently ignored except that if the list + * becomes empty KErrNotSupported will be returned. + * + * @param aCiphers Descriptor holding the cipher suites list. + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetAvailableCipherSuites( aCiphers ); +} + +EXPORT_C TInt CSecureSocket::SetClientCert(const CX509Certificate& aCert) +/** + * Sets the client certificate to use. + * + * When a secure socket is acting in client mode, this method will set the certificate + * that will be used if a server requests one. When acting in server mode, if called + * this method will perform no action, but will return KErrNotSupported. + * + * Note that this method is currently reserved for future use, and always returns + * KErrNotSupported. + * + * @param aCert The client certificate. + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetClientCert( aCert ); +} + +EXPORT_C TInt CSecureSocket::SetClientCertMode(const TClientCertMode aClientCertMode) +/** + * Sets the client certificate mode. + * + * @param aClientCertMode The client certificate mode to set. + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetClientCertMode( aClientCertMode ); +} + +EXPORT_C TInt CSecureSocket::SetDialogMode(const TDialogMode aDialogMode) +/** + * Sets the Dialog mode. + * + * @param aDialogMode Dialog mode to set. + * @return KErrNone if successful, otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetDialogMode( aDialogMode ); +} + +EXPORT_C TInt CSecureSocket::SetProtocol(const TDesC& aProtocol) +/** + * Sets the protocol + * + * @param aProtocol Descriptor holding the protocol name to be set, + * e.g. "SSL3.0" or "TLS1.0". + * @return KErrNone if successful, or KErrNotSupported if the protocol in + * the descriptor isn't recognized. + */ +{ + return iSecureImplementation->SetProtocol( aProtocol ); +} + +EXPORT_C TInt CSecureSocket::SetOpt(TUint aOptionName, TUint aOptionLevel, const TDesC8& aOption) +/** + * Sets an option. + * + * SecureSocket implementations may provide options that can be used with this method. + * See individual implementation notes for details. + * + * In order for full verification of the Server certificate during handshake negotiation + * the domain name must be set. + * This is done using the option KSoSSLDomainName, with the option level KSolInetSSL. + * + * In order to use a TLS PSK ciphersuite the user must use the the option KSoPskConfig, + * with the option level KSolInetSSL. + * The aOption argument should be a TPckgBuf. This passes in a pointer + * to an object which implements the MSoPskKeyHandler interface to decide which PSK identity and + * value the client wishes to use to secure the connection. See MSoPskKeyHandler for further details. + * If the MSoPskKeyHandler is NULL then PSK ciphersuites will be disabled again. If you specified an exact list + * of ciphersuites (by calling SetAvailableCipherSuites) you must update that list to exclude PSK ciphersuites. + * + * The option KSoServerNameIndication, with the option level KSolInetSSL can be used to include the + * RFC3546 server name indication in the ClientHello sent to the server. This can be used to facilitate + * secure connections to servers that host multiple 'virtual' servers at a single underlying + * network address. The aOption argument should be a TPckgBuf, ownership is passed in. + * One or more UTF-8 FQDNs can be supplied. Neither trailing dots nor numeric IP addresses should be used. + * + * @param aOptionName An integer constant which identifies an option. + * @param aOptionLevel An integer constant which identifies the level of an option: + * i.e. an option level group of related options. + * @param aOption An option value packaged in a descriptor. + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetOpt( aOptionName, aOptionLevel, aOption ); +} + +EXPORT_C TInt CSecureSocket::SetOpt(TUint aOptionName, TUint aOptionLevel, TInt aOption) +/** + * Sets an option. + * + * SecureSocket implementations may provide options that can be used with this method. + * See individual implementation notes for details. + * + * By default the TLS_RSA_WITH_NULL_MD5 and TLS_RSA_WITH_NULL_SHA ciphersuites are disabled. + * These ciphersuites use NULL encryption and therefore offer no protection against evesdropping. + * Server authentication (and client, if a client certificate is used) is performed and data integrity + * is still checked (nb. TLS_NULL_WITH_NULL_NULL is never supported). + * In order to these ciphersuites the user must use the the option KSoEnableNullCiphers, with the + * option level KSolInetSSL and a non-zero argument. Using an argument of zero will disable them. + * + * @param aOptionName An integer constant which identifies an option. + * @param aOptionLevel An integer constant which identifies the level of an option: + * i.e. an option level group of related options. + * @param aOption An option value as an integer . + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetOpt( aOptionName, aOptionLevel, aOption ); +} + +EXPORT_C TInt CSecureSocket::SetServerCert(const CX509Certificate& aCert) +/** + * Sets the server X.509 certificate. + * + * @param aCert The certificate to use. + * @return KErrNone if successful; otherwise, a system-wide error code. + */ +{ + return iSecureImplementation->SetServerCert( aCert ); +} + +EXPORT_C void CSecureSocket::StartClientHandshake(TRequestStatus& aStatus) +/** + * Starts the client handshake. + * + * @param aStatus On completion, KErrNone if successful; + * otherwise, a system-wide error code. + */ +{ + iSecureImplementation->StartClientHandshake( aStatus ); +} + +EXPORT_C void CSecureSocket::StartServerHandshake(TRequestStatus& aStatus) +/** + * Starts the server handshake. + * + * @param aStatus On completion, KErrNone if successful; + * otherwise, a system-wide error code. + */ +{ + iSecureImplementation->StartServerHandshake( aStatus ); +} + +TInt SetTLSData() +/** + * Sets the Thread local storage data. + */ +{ + TInt ret=KErrNone; + + // Create a new DllGlobals class + TSecureSocketGlobals* global = new TSecureSocketGlobals; + if(!global) + { + return KErrNoMemory; + } + + ret = Dll::SetTls( global ); + + if(ret) + { + delete global; + } + else + { + global->iUseCount=0; + } + + return ret; +} + +