networksecurity/tls/secsock/SecureSocket.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Describes the implementation of a secure socket class.
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include "SecureSocket.h"
       
    23 #include "GenericSecureSocket.h"
       
    24 #include <commsdattypesv1_1.h>
       
    25 
       
    26 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    27 #include <ssl_internal.h>
       
    28 #include <securesocket_internal.h>
       
    29 #endif
       
    30 
       
    31 #include <commsdattypeinfov1_1_internal.h>
       
    32 #include <commsdattypesv1_1_partner.h>
       
    33 
       
    34 using namespace CommsDat;
       
    35 
       
    36 TInt SetTLSData(void);
       
    37 
       
    38 #define LOADDLL_ORIG_ORDINAL 1
       
    39 #define UNLOADDLL_ORDINAL 2
       
    40 #define LOADDLL_NEW_ORDINAL 3
       
    41 
       
    42 TSecSocketProtocol::~TSecSocketProtocol()
       
    43 /** 
       
    44  * Closes the DLL library. 
       
    45  */
       
    46 {
       
    47 	iLibrary.Close();
       
    48 }
       
    49 
       
    50 TInt CSecureSocketLibraryLoader::OpenL(const TDesC& aProtocolName,TSecSockDllLibraryFunction& aEntryPoint)
       
    51 /** 
       
    52  * Opens the protocol library.
       
    53  * Attempts to load the secure socket implementation DLL for the requested 
       
    54  * protocol type. 
       
    55  * 
       
    56  * @param aProtocolName	A reference to a descriptor containing the protocol name, 
       
    57  * 						i.e. tls1.0, ssl3.0. Case is ignored.
       
    58  * @param aEntryPoint	Entry point into the secureSocket plug-in.
       
    59  * @return				KErrNone, if successful; otherwise, another of the system-wide error codes. 
       
    60  */
       
    61 	{
       
    62 	TLibraryFunction entry;
       
    63 
       
    64 	CSecureSocketLibraryLoader::OpenWithIdL(LOADDLL_ORIG_ORDINAL, aProtocolName, entry);
       
    65 	aEntryPoint = reinterpret_cast<TSecSockDllLibraryFunction>(entry);
       
    66 	if(!aEntryPoint)
       
    67 		{
       
    68 		return KErrNotFound;
       
    69 		}
       
    70 
       
    71 	return KErrNone;
       
    72 	}
       
    73 
       
    74 
       
    75 TInt CSecureSocketLibraryLoader::OpenL(const TDesC& aProtocolName,TSecSockDllLibraryGenericFunction& aEntryPoint)
       
    76 /** 
       
    77  * Opens the protocol library.
       
    78  * Attempts to load the secure socket implementation DLL for the requested 
       
    79  * protocol type. 
       
    80  * 
       
    81  * @param aProtocolName	A reference to a descriptor containing the protocol name, 
       
    82  * 						i.e. tls1.0, ssl3.0. Case is ignored.
       
    83  * @param aEntryPoint	Entry point into the secureSocket plug-in.
       
    84  * @return				KErrNone, if successful; otherwise, another of the system-wide error codes. 
       
    85  */
       
    86 	{
       
    87 	TLibraryFunction entry;
       
    88 
       
    89 	CSecureSocketLibraryLoader::OpenWithIdL(LOADDLL_NEW_ORDINAL, aProtocolName, entry);
       
    90 	aEntryPoint = reinterpret_cast<TSecSockDllLibraryGenericFunction>(entry);
       
    91 	if(!aEntryPoint)
       
    92 		{
       
    93 		return KErrNotFound;
       
    94 		}
       
    95 
       
    96 	return KErrNone;
       
    97 	}
       
    98 
       
    99 
       
   100 void CSecureSocketLibraryLoader::OpenWithIdL(TInt aId, const TDesC& aProtocolName, TLibraryFunction& aEntryPoint)
       
   101 /** 
       
   102  * Opens the protocol library.
       
   103  * Attempts to load the secure socket implementation DLL for the requested 
       
   104  * protocol type. 
       
   105  * 
       
   106  * @param aProtocolName	A reference to a descriptor containing the protocol name, 
       
   107  * 						i.e. tls1.0, ssl3.0. Case is ignored.
       
   108  * @param aEntryPoint	Entry point into the secureSocket plug-in.
       
   109  * @return				KErrNone, if successful; otherwise, another of the system-wide error codes. 
       
   110  */
       
   111 {
       
   112 	//Fetch the TLS data
       
   113 	TSecureSocketGlobals* global = (TSecureSocketGlobals*)Dll::Tls();
       
   114 	if ( !global )
       
   115 	{
       
   116 		if (SetTLSData() == KErrNone) 
       
   117 			global = (TSecureSocketGlobals*)Dll::Tls();
       
   118 	}
       
   119 	__ASSERT_ALWAYS(global,User::Leave(KErrNoMemory));
       
   120 
       
   121 	// Increase the globals use count
       
   122 	global->iUseCount++;
       
   123 
       
   124 	// Convert to lower case before doing a comparison
       
   125 	TBuf<32> protocol;
       
   126 	protocol.Copy(aProtocolName);
       
   127 	protocol.LowerCase();
       
   128 
       
   129 	//Walk the list and find the protocol
       
   130 	global->iSecureSocketProtocolsIter.SetToFirst(); 
       
   131 	TSecSocketProtocol* secProtocol;
       
   132 	while ((secProtocol = global->iSecureSocketProtocolsIter++) != NULL)
       
   133 		{
       
   134 		if(secProtocol->iName.Compare(protocol))
       
   135 			//Found a matching protocol name
       
   136 			break;
       
   137 		}
       
   138 
       
   139 	if(secProtocol == NULL)
       
   140 	//Library not loaded yet - Find a dll name in Commdb that matches proto name
       
   141 	//and load the dll
       
   142 		{
       
   143 		secProtocol = new(ELeave)TSecSocketProtocol;
       
   144 		CleanupStack::PushL(secProtocol);
       
   145 		//Find the protocolname record in COMMDB
       
   146 		TBuf<KMaxFileName> fileName;
       
   147 		FindItemInDbL(protocol, fileName);
       
   148 
       
   149 		// Load the library whose name we just fetched
       
   150 		// Commented out the line below as it loads the SSLADAPTOR.DLL
       
   151 		// Hardcoded the SSL.DLL. SSL.DLL ultimately should be an ECOM Plugin.
       
   152 		// (These changes were made as part of GT167 Zephyr work on TLS.
       
   153 		//(void)User::LeaveIfError(secProtocol->iLibrary.Load(fileName));
       
   154 		(void)User::LeaveIfError(secProtocol->iLibrary.Load(_L("SSL.DLL")));
       
   155 
       
   156 
       
   157 		//Add the entry in the list
       
   158 		secProtocol->iName.Copy(protocol);
       
   159 		global->iSecureSocketProtocols.AddLast(*secProtocol);
       
   160 		CleanupStack::Pop();
       
   161 		}
       
   162 
       
   163 	// Get the pointer to the NewL function in the DLL
       
   164 	aEntryPoint = secProtocol->iLibrary.Lookup(aId);	
       
   165 	
       
   166 }
       
   167 
       
   168 void CSecureSocketLibraryLoader::FindItemInDbL(const TDesC& aProtocolName, TDes& aLibraryName)
       
   169 /**
       
   170  * Opens the Commdb and locates the DLL name for a protocol.
       
   171  * 
       
   172  * @param aProtocolName	A reference to a descriptor containing the protocol name, 
       
   173  * 						i.e. tls1.0, ssl3.0. Case is ignored.
       
   174  * @param aLibraryName 	On return, name of the library.
       
   175  * @exception			This function will leave if the protocol was not found or in OOM conditions. 
       
   176  */
       
   177 {
       
   178 
       
   179 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
   180 		CMDBSession* session = CMDBSession::NewL(KCDVersion1_2);
       
   181 #else
       
   182 		CMDBSession* session = CMDBSession::NewL(KCDVersion1_1);
       
   183 #endif
       
   184 		CleanupStack::PushL(session);
       
   185 		CCDSecureSocketRecord* ptrRecord = static_cast<CCDSecureSocketRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdSSProtoRecord));
       
   186 		CleanupStack::PushL(ptrRecord);
       
   187 		ptrRecord->iSSProtoName = aProtocolName;
       
   188 		// check if any record is returned back
       
   189 		if (!ptrRecord->FindL(*session))
       
   190 			{
       
   191 			// ignore return from FindL otherwise tests fail
       
   192 			//User::Leave(KErrNotFound);
       
   193 			}
       
   194 
       
   195 		aLibraryName = ptrRecord->iSSProtoLibrary;
       
   196 		CleanupStack::PopAndDestroy(ptrRecord);
       
   197 		CleanupStack::PopAndDestroy(session);
       
   198 }
       
   199 
       
   200 EXPORT_C void CSecureSocketLibraryLoader::Unload()
       
   201 /** 
       
   202  * Closes and unloads the implementation library.
       
   203  */
       
   204 {
       
   205 	//Fetch the TLS data
       
   206 	TSecureSocketGlobals* global = (TSecureSocketGlobals*)Dll::Tls();
       
   207 
       
   208 	//Cannot assume that tls exists at this point (False with WINS)
       
   209 	if(!global)
       
   210 		return;
       
   211 
       
   212 	// if the use count isn't 0, don't do the unload
       
   213 	if ( --global->iUseCount )
       
   214 		return;
       
   215 
       
   216 	//Walk the list and find the protocol
       
   217 	global->iSecureSocketProtocolsIter.SetToFirst(); 
       
   218 	TSecSocketProtocol* secProtocol;
       
   219 	
       
   220 	while ((secProtocol = global->iSecureSocketProtocolsIter++) != NULL)
       
   221 		{
       
   222 		//Find the entry point for  the resource cleanup function 
       
   223 		TSecSockDllUnloadFunction cleanupEntryPoint  = reinterpret_cast<TSecSockDllUnloadFunction> (secProtocol->iLibrary.Lookup(UNLOADDLL_ORDINAL));
       
   224 		//Call the function
       
   225 		if(cleanupEntryPoint)
       
   226 			(*cleanupEntryPoint)(NULL);
       
   227 		global->iSecureSocketProtocols.Remove(*secProtocol);
       
   228 		delete secProtocol;
       
   229 		}
       
   230 	// remove the globals reference
       
   231 	delete global;
       
   232 	Dll::SetTls(NULL); // @bug check ret val
       
   233 }
       
   234 
       
   235 EXPORT_C CSecureSocket* CSecureSocket::NewL(RSocket& aSocket,const TDesC& aProtocol)
       
   236 /** 
       
   237  * Creates and returns a pointer to a new secure socket.
       
   238  *
       
   239  * A reference to an already open and connected socket should be passed in, 
       
   240  * along with a descriptor that contains the protocol name.
       
   241  *
       
   242  * @param aSocket	A reference to an open and connected RSocket object.
       
   243  * @param aProtocol	A constant descriptor containing the protocol name.
       
   244  * @return 			A pointer to the newly created secure socket, or NULL if the creation failed.
       
   245  */
       
   246 {
       
   247 	CSecureSocket* self = new(ELeave) CSecureSocket;
       
   248 	CleanupStack::PushL( self );
       
   249 	self->ConstructL(aSocket,aProtocol);
       
   250 	CleanupStack::Pop();
       
   251 	return self;
       
   252 }
       
   253 
       
   254 EXPORT_C CSecureSocket* CSecureSocket::NewL(MGenericSecureSocket& aSocket,const TDesC& aProtocol)
       
   255 /** 
       
   256  * Creates and returns a pointer to a new secure socket.
       
   257  *
       
   258  * A reference to a socket derived from MGenericSecureSocket should be passed in, 
       
   259  * along with a descriptor that contains the protocol name.
       
   260  *
       
   261  * @param aSocket	A reference to an MGenericSecureSocket derived object.
       
   262  * @param aProtocol	A constant descriptor containing the protocol name.
       
   263  * @return 			A pointer to the newly created secure socket, or NULL if the creation failed.
       
   264  */
       
   265 {
       
   266 	CSecureSocket* self = new(ELeave) CSecureSocket;
       
   267 	CleanupStack::PushL( self );
       
   268 	self->ConstructL(aSocket,aProtocol);
       
   269 	CleanupStack::Pop();
       
   270 	return self;
       
   271 }
       
   272 
       
   273 void CSecureSocket::ConstructL(RSocket& aSocket, const TDesC& aProtocol)
       
   274 /** 
       
   275  * Standard 2-phase construction.
       
   276  */
       
   277 {
       
   278 	TSecSockDllLibraryFunction libEntryPointL;
       
   279 	User::LeaveIfError(CSecureSocketLibraryLoader::OpenL(aProtocol,libEntryPointL));
       
   280 	//Beware! the following call can leave...
       
   281 	iSecureImplementation = (MSecureSocket*)libEntryPointL( aSocket, aProtocol );
       
   282 	if (iSecureImplementation)
       
   283 		{
       
   284 		iSecureSocketState = ESecureSocketStateOpen;
       
   285 		}
       
   286 
       
   287 }
       
   288 
       
   289 void CSecureSocket::ConstructL(MGenericSecureSocket& aSocket, const TDesC& aProtocol)
       
   290 /** 
       
   291  * Standard 2-phase construction.
       
   292  */
       
   293 {
       
   294 	TSecSockDllLibraryGenericFunction libEntryPointL;
       
   295 	User::LeaveIfError(CSecureSocketLibraryLoader::OpenL(aProtocol,libEntryPointL));
       
   296 	//Beware! the following call can leave...
       
   297 	iSecureImplementation = (MSecureSocket*)libEntryPointL( aSocket, aProtocol );
       
   298 	if (iSecureImplementation)
       
   299 		{
       
   300 		iSecureSocketState = ESecureSocketStateOpen;
       
   301 		}
       
   302 }
       
   303 
       
   304 CSecureSocket::~CSecureSocket()
       
   305 /** 
       
   306  *Standard destructor. 
       
   307  */
       
   308 {
       
   309 	if ((iSecureImplementation) && (iSecureSocketState == ESecureSocketStateOpen))
       
   310 	{
       
   311 		iSecureImplementation->Close();
       
   312 	}
       
   313 
       
   314 	delete iSecureImplementation;
       
   315 	// Close and unload the implementation library, Unload checks access count first
       
   316 	CSecureSocketLibraryLoader::Unload();
       
   317 }
       
   318 
       
   319 
       
   320 //
       
   321 EXPORT_C TInt CSecureSocket::AvailableCipherSuites( TDes8& aCiphers )
       
   322 /** 
       
   323  * Gets the available cipher suites.
       
   324  *
       
   325  * Note that ciphersuites using NULL encryption or PSK key exchange will not be included
       
   326  * unless they have been enabled via SetOpt.
       
   327  *
       
   328  * @param aCiphers	Descriptor holding the ciphers.
       
   329  * @return			KErrNone if successful, a system-wide error code if not.
       
   330  */
       
   331 {
       
   332 	return iSecureImplementation->AvailableCipherSuites( aCiphers );
       
   333 }
       
   334 
       
   335 EXPORT_C void CSecureSocket::CancelAll()
       
   336 /** 
       
   337  *Cancels all the send and receive actions in the SSL state machine. 
       
   338  */
       
   339 {
       
   340 	iSecureImplementation->CancelAll();
       
   341 }
       
   342 
       
   343 EXPORT_C void CSecureSocket::CancelHandshake()
       
   344 /** 
       
   345  *Cancels the handshake. 
       
   346  */
       
   347 {
       
   348 	iSecureImplementation->CancelHandshake();
       
   349 }
       
   350 
       
   351 EXPORT_C void CSecureSocket::CancelRecv()
       
   352 /** 
       
   353  * Cancels a receive action in the SSL state machine. 
       
   354  */
       
   355 {
       
   356 	iSecureImplementation->CancelRecv();
       
   357 }
       
   358 
       
   359 EXPORT_C void CSecureSocket::CancelSend()
       
   360 /** 
       
   361  *Cancels a send action in the SSL state machine.
       
   362  */
       
   363 {
       
   364 	iSecureImplementation->CancelSend();
       
   365 }
       
   366 
       
   367 EXPORT_C const CX509Certificate* CSecureSocket::ClientCert()
       
   368 /** 
       
   369  * Gets the current client certificate.
       
   370  * 
       
   371  * When a secure socket is acting in server mode, the returned certificate will 
       
   372  * be the certificate that the remote client provided. When acting in client mode, 
       
   373  * the certificate returned will be local certificate. 
       
   374  * 
       
   375  * @return	A pointer to the client certificate, or NULL if none exists. 
       
   376  */
       
   377 {
       
   378 	return iSecureImplementation->ClientCert();
       
   379 }
       
   380 
       
   381 EXPORT_C TClientCertMode CSecureSocket::ClientCertMode()
       
   382 /** 
       
   383  * Gets the current client certificate mode.
       
   384  *
       
   385  * The client certificate mode is used when the socket is acting as a server, 
       
   386  * and determines whether a client certificate is requested. 
       
   387  *
       
   388  * @return	The current mode that is set. 
       
   389  */
       
   390 {
       
   391 	return iSecureImplementation->ClientCertMode();
       
   392 }
       
   393 
       
   394 EXPORT_C TDialogMode CSecureSocket::DialogMode()
       
   395 /** 
       
   396  * Gets the current dialog mode. 
       
   397  * 
       
   398  * @return The current dialog mode.
       
   399  */
       
   400 {
       
   401 	return iSecureImplementation->DialogMode();
       
   402 }
       
   403 
       
   404 EXPORT_C void CSecureSocket::Close()
       
   405 /** 
       
   406  * Closes the secure connection and the socket.
       
   407  *
       
   408  * Implementations should terminate the secure connection gracefully as 
       
   409  * appropriate to their protocol. The RSocket object is not destoyed: 
       
   410  * this is left to the client application. 
       
   411  */
       
   412 {
       
   413 	iSecureSocketState = ESecureSocketStateClosed;
       
   414 	iSecureImplementation->Close();
       
   415 }
       
   416 
       
   417 EXPORT_C TInt CSecureSocket::CurrentCipherSuite( TDes8& aCipherSuite )
       
   418 /** 
       
   419  * Gets the current cipher suite in use.
       
   420  * 
       
   421  * The current cipher suite is returned in the referenced buffer 
       
   422  * in two byte format as, i.e. [0x??][0x??].
       
   423  *
       
   424  * @param aCipherSuite	A reference to a descriptor at least 2 bytes long. 
       
   425  *						Implementations that differ from the [0x??][0x??] 
       
   426  *						format may require larger descriptors. See individual 
       
   427  *						implementation notes for details.
       
   428  * @return				KErrNone if successful; 
       
   429  *						otherwise, another of the system-wide error codes. 
       
   430  */
       
   431 {
       
   432 	return iSecureImplementation->CurrentCipherSuite( aCipherSuite );
       
   433 }
       
   434 
       
   435 EXPORT_C void CSecureSocket::FlushSessionCache()
       
   436 /** 
       
   437  *Flushes the session cache. 
       
   438  */
       
   439 {
       
   440 	iSecureImplementation->FlushSessionCache();
       
   441 }
       
   442 
       
   443 EXPORT_C TInt CSecureSocket::GetOpt(TUint aOptionName, TUint aOptionLevel, TDes8& aOption)
       
   444 /** 
       
   445  * Gets an option.
       
   446  *
       
   447  * Secure socket implementations may provide options that can 
       
   448  * be used with this function. 
       
   449  *
       
   450  * (nb. Getting the KSoServerNameIndication option is not supported).
       
   451  *
       
   452  * @param aOptionName	An integer constant which identifies an option. 
       
   453  * @param aOptionLevel	An integer constant which identifies the level of an option, 
       
   454  * 						i.e. an option level group of related options.
       
   455  * @param aOption		An option value packaged in a descriptor.
       
   456  * @return 				KErrNone if successful; 
       
   457  *						otherwise, another of the system-wide error codes. 
       
   458  */
       
   459 {
       
   460 	return iSecureImplementation->GetOpt(aOptionName, aOptionLevel, aOption);
       
   461 }
       
   462 
       
   463 EXPORT_C TInt CSecureSocket::GetOpt(TUint aOptionName, TUint aOptionLevel, TInt& aOption)
       
   464 /** 
       
   465  * Gets an option.
       
   466  *
       
   467  * Secure socket implementations may provide options that can 
       
   468  * be used with this method. 
       
   469  *
       
   470  * (nb. Getting the KSoServerNameIndication option is not supported).
       
   471  *
       
   472  * @param aOptionName	An integer constant which identifies an option. 
       
   473  * @param aOptionLevel	An integer constant which identifies the level of an option, 
       
   474  * 						i.e. an option level group of related options.
       
   475  * @param aOption		An integer option value.
       
   476  * @return 				KErrNone if successful; 
       
   477  *						otherwise, another of the system-wide error codes. 
       
   478  */
       
   479 {
       
   480 	return iSecureImplementation->GetOpt(aOptionName, aOptionLevel, aOption);
       
   481 }
       
   482 
       
   483 EXPORT_C TInt CSecureSocket::Protocol(TDes& aProtocol)
       
   484 /**
       
   485  * Gets the protocol in use.
       
   486  *
       
   487  * This method can be used to return the particular protocol/version that is 
       
   488  * being used by implementations that support different protocols/versions. 
       
   489  *
       
   490  * @param aProtocol	A descriptor containing the protocol name/version that is 
       
   491  *					being used. Protocol names can be up to 32 characters long, 
       
   492  *					and so a descriptor of at least that size is required.
       
   493  * @return			KErrNone 
       
   494  */
       
   495 {
       
   496 	return iSecureImplementation->Protocol( aProtocol );
       
   497 }
       
   498 
       
   499 EXPORT_C void CSecureSocket::Recv (TDes8& aDesc, TRequestStatus& aStatus )
       
   500 /**
       
   501  * Receives data from the socket.
       
   502  *
       
   503  * This is an asynchronous function, and completes 
       
   504  * when the descriptor has been filled. Only one Recv() or RecvOneOrMore() 
       
   505  * operation can be outstanding at any time.
       
   506  *
       
   507  * @param aDesc		A descriptor where data read will be placed.
       
   508  * @param aStatus 	On completion, KErrNone if successful; 
       
   509  *					KErrEof if a remote connection is closed and there is no more data; 
       
   510  *					KErrNotReady if called when an operation is still outstanding; 
       
   511  *					or another system-wide error code. 
       
   512  */
       
   513 {
       
   514 	iSecureImplementation->Recv( aDesc, aStatus );
       
   515 }
       
   516 
       
   517 EXPORT_C void CSecureSocket::RecvOneOrMore( TDes8& aDesc, TRequestStatus& aStatus, TSockXfrLength& aLen )
       
   518 /** 
       
   519  * Receives data from the socket.
       
   520  *
       
   521  * This is an asynchronous function, and will complete when at least one byte has been read. 
       
   522  * Only one Recv() or RecvOneOrMore() operation can be outstanding at any time.
       
   523  * 
       
   524  * @param aDesc		A descriptor where data read will be placed.
       
   525  * @param aStatus	On completion, KErrNone if successful;
       
   526  *					KErrEof if a remote connection is closed and there is no more data;
       
   527  * 					KErrNotReady if called when an operation is still outstanding;
       
   528  * 					or another system-wide error code.
       
   529  * @param aLen		On completion, the length of the descriptor, aDesc. 
       
   530  */
       
   531 {
       
   532 	iSecureImplementation->RecvOneOrMore( aDesc, aStatus, aLen );
       
   533 }
       
   534 
       
   535 EXPORT_C void CSecureSocket::RenegotiateHandshake(TRequestStatus& aStatus )
       
   536 /**
       
   537  * Initiates a renegotiation of the secure connection.
       
   538  *
       
   539  * This is an asynchronous function that completes when renegotiation is complete. 
       
   540  * It is valid for both client and server operation. There can only be one outstanding 
       
   541  * RenegotiateHandshake() operation at a time.
       
   542  *
       
   543  * @param aStatus	On completion, KErrNone if successful;
       
   544  * 					KErrNotReady if called when an operation is still outstanding;
       
   545  * 	 				or another system-wide error code. 
       
   546  */
       
   547 {
       
   548 	iSecureImplementation->RenegotiateHandshake( aStatus );
       
   549 }
       
   550 
       
   551 EXPORT_C void CSecureSocket::Send( const TDesC8& aDesc, TRequestStatus& aStatus, TSockXfrLength& aLen )
       
   552 /**
       
   553  * Sends data over the socket.
       
   554  *
       
   555  * This is an asynchronous function. Only one Send() operation can be outstanding at any time. 
       
   556  * 
       
   557  * @param aDesc		A constant descriptor with the data to be send.
       
   558  * @param aStatus	On completion, KErrNone if successful; 
       
   559  *					KErrNotReady if called when an operation is still outstanding;
       
   560  *				 	or another system-wise error code.
       
   561  * @param aLen		On completion, the amount of data sent.
       
   562  */
       
   563 {
       
   564 	iSecureImplementation->Send( aDesc, aStatus, aLen );
       
   565 }
       
   566 
       
   567 EXPORT_C void CSecureSocket::Send( const TDesC8& aDesc, TRequestStatus& aStatus )
       
   568 /** 
       
   569  * Sends data over the socket.
       
   570  *
       
   571  * This is an asynchronous function. Only one Send() operation can be outstanding 
       
   572  * at any time, and the function will complete with the error KErrNotReady if called 
       
   573  * when a send is still outstanding.
       
   574  *
       
   575  * @param aDesc		A constant descriptor. The application must not modify this  
       
   576  *					descriptor until the Send() completes.
       
   577  * @param aStatus	On completion, KErrNone;
       
   578  * 					KErrNotReady if called when a send is still outstanding, if successful;
       
   579  *					or another system-wide error code. 
       
   580  */
       
   581 {
       
   582 	iSecureImplementation->Send( aDesc, aStatus );
       
   583 }
       
   584 
       
   585 EXPORT_C const CX509Certificate* CSecureSocket::ServerCert()
       
   586 /** 
       
   587  * Gets the current server certificate.
       
   588  *
       
   589  * When a secure socket is acting in client mode, the returned certificate will be
       
   590  * the certificate for the remote server. When acting in server mode, the certificate
       
   591  * returned will be the local certificate. 
       
   592  *
       
   593  * Note that	the operation in server mode is currently reserved for future use, 
       
   594  * and returns NULL.
       
   595  * 
       
   596  * @return	Pointer to the certificate, or NULL if no certificate is available. 
       
   597  */
       
   598 {
       
   599 	return iSecureImplementation->ServerCert();
       
   600 }
       
   601 
       
   602 EXPORT_C TInt CSecureSocket::SetAvailableCipherSuites(const TDesC8& aCiphers)
       
   603 /**
       
   604  * Sets the list of cipher suites that are available for use.
       
   605  *
       
   606  * The list of cipher suites should be supplied in a descriptor in the format 
       
   607  * as per the TLS RFC, i.e. [0x??][0x??] for each suite. The order of suites is 
       
   608  * important, and so they should be listed with the preferred suites first. 
       
   609  *
       
   610  * Note that ciphersuites using NULL encryption or PSK key exchange will be considered
       
   611  * unsupported unless these features have been enabled via SetOpt.
       
   612  *
       
   613  * Unsupported ciphersuites are silently ignored except that if the list
       
   614  * becomes empty KErrNotSupported will be returned.
       
   615  *
       
   616  * @param aCiphers	Descriptor holding the cipher suites list.
       
   617  * @return			KErrNone if successful; otherwise, a system-wide error code. 
       
   618  */
       
   619 {
       
   620 	return iSecureImplementation->SetAvailableCipherSuites( aCiphers );
       
   621 }
       
   622 
       
   623 EXPORT_C TInt CSecureSocket::SetClientCert(const CX509Certificate& aCert)
       
   624 /**
       
   625  * Sets the client certificate to use.
       
   626  *
       
   627  * When a secure socket is acting in client mode, this method will set the certificate 
       
   628  * that will be used if a server requests one. When acting in server mode, if called 
       
   629  * this method will perform no action, but will return KErrNotSupported. 
       
   630  *
       
   631  * Note that this method is currently reserved for future use, and always returns 
       
   632  * KErrNotSupported. 
       
   633  * 
       
   634  * @param aCert	The client certificate.
       
   635  * @return		KErrNone if successful; otherwise, a system-wide error code.
       
   636  */
       
   637 {
       
   638 	return iSecureImplementation->SetClientCert( aCert );
       
   639 }
       
   640 
       
   641 EXPORT_C TInt CSecureSocket::SetClientCertMode(const TClientCertMode aClientCertMode)
       
   642 /** 
       
   643  * Sets the client certificate mode.
       
   644  *
       
   645  * @param aClientCertMode	The client certificate mode to set.
       
   646  * @return					KErrNone if successful; otherwise, a system-wide error code.
       
   647  */
       
   648 {
       
   649 	return iSecureImplementation->SetClientCertMode( aClientCertMode );
       
   650 }
       
   651 
       
   652 EXPORT_C TInt CSecureSocket::SetDialogMode(const TDialogMode aDialogMode)
       
   653 /** 
       
   654  * Sets the Dialog mode.
       
   655  * 
       
   656  * @param aDialogMode	Dialog mode to set.
       
   657  * @return				KErrNone if successful, otherwise, a system-wide error code.
       
   658  */
       
   659 {
       
   660 	return iSecureImplementation->SetDialogMode( aDialogMode );
       
   661 }
       
   662 
       
   663 EXPORT_C TInt CSecureSocket::SetProtocol(const TDesC& aProtocol)
       
   664 /** 
       
   665  * Sets the protocol
       
   666  * 
       
   667  * @param aProtocol	Descriptor holding the protocol name to be set, 
       
   668  * 					e.g. "SSL3.0" or "TLS1.0".
       
   669  * @return			KErrNone if successful, or KErrNotSupported if the protocol in 
       
   670  *					the descriptor isn't recognized.
       
   671  */
       
   672 {
       
   673 	return iSecureImplementation->SetProtocol( aProtocol );
       
   674 }
       
   675 
       
   676 EXPORT_C TInt CSecureSocket::SetOpt(TUint aOptionName, TUint aOptionLevel, const TDesC8& aOption)
       
   677 /** 
       
   678  * Sets an option.
       
   679  *
       
   680  * SecureSocket implementations may provide options that can be used with this method. 
       
   681  * See individual implementation notes for details.
       
   682  *
       
   683  * In order for full verification of the Server certificate during handshake negotiation
       
   684  * the domain name must be set.
       
   685  * This is done using the option KSoSSLDomainName, with the option level KSolInetSSL.
       
   686  *
       
   687  * In order to use a TLS PSK ciphersuite the user must use the the option KSoPskConfig,
       
   688  * with the option level KSolInetSSL.
       
   689  * The aOption argument should be a TPckgBuf<MSoPskKeyHandler *>. This passes in a pointer
       
   690  * to an object which implements the MSoPskKeyHandler interface to decide which PSK identity and
       
   691  * value the client wishes to use to secure the connection. See MSoPskKeyHandler for further details.
       
   692  * If the MSoPskKeyHandler is NULL then PSK ciphersuites will be disabled again. If you specified an exact list
       
   693  * of ciphersuites (by calling SetAvailableCipherSuites) you must update that list to exclude PSK ciphersuites.
       
   694  *
       
   695  * The option KSoServerNameIndication, with the option level KSolInetSSL can be used to include the 
       
   696  * RFC3546 server name indication in the ClientHello sent to the server. This can be used to facilitate
       
   697  * secure connections to servers that host multiple 'virtual' servers at a single underlying
       
   698  * network address. The aOption argument should be a TPckgBuf<CDesC8Array *>, ownership is passed in.
       
   699  * One or more UTF-8 FQDNs can be supplied. Neither trailing dots nor numeric IP addresses should be used.
       
   700  *
       
   701  * @param aOptionName	An integer constant which identifies an option.
       
   702  * @param aOptionLevel	An integer constant which identifies the level of an option: 
       
   703  * 						i.e. an option level group of related options.
       
   704  * @param aOption		An option value packaged in a descriptor.
       
   705  * @return				KErrNone if successful; otherwise, a system-wide error code.
       
   706  */
       
   707 {
       
   708 	return iSecureImplementation->SetOpt( aOptionName, aOptionLevel, aOption );
       
   709 }
       
   710 
       
   711 EXPORT_C TInt CSecureSocket::SetOpt(TUint aOptionName, TUint aOptionLevel, TInt aOption)
       
   712 /** 
       
   713  * Sets an option.
       
   714  *
       
   715  * SecureSocket implementations may provide options that can be used with this method. 
       
   716  * See individual implementation notes for details.
       
   717  *
       
   718  * By default the TLS_RSA_WITH_NULL_MD5 and TLS_RSA_WITH_NULL_SHA ciphersuites are disabled.
       
   719  * These ciphersuites use NULL encryption and therefore offer no protection against evesdropping.
       
   720  * Server authentication (and client, if a client certificate is used) is performed and data integrity
       
   721  * is still checked (nb. TLS_NULL_WITH_NULL_NULL is never supported).
       
   722  * In order to these ciphersuites the user must use the the option KSoEnableNullCiphers, with the
       
   723  * option level KSolInetSSL and a non-zero argument. Using an argument of zero will disable them.
       
   724  * 
       
   725  * @param aOptionName	An integer constant which identifies an option.
       
   726  * @param aOptionLevel	An integer constant which identifies the level of an option: 
       
   727  * 						i.e. an option level group of related options.
       
   728  * @param aOption		An option value as an integer .
       
   729  * @return				KErrNone if successful; otherwise, a system-wide error code.
       
   730  */
       
   731 {
       
   732 	return iSecureImplementation->SetOpt( aOptionName, aOptionLevel, aOption );
       
   733 }
       
   734 
       
   735 EXPORT_C TInt CSecureSocket::SetServerCert(const CX509Certificate& aCert)
       
   736 /** 
       
   737  * Sets the server X.509 certificate.
       
   738  * 
       
   739  * @param aCert	The certificate to use.
       
   740  * @return		KErrNone if successful; otherwise, a system-wide error code.
       
   741  */
       
   742 {
       
   743 	return iSecureImplementation->SetServerCert( aCert );
       
   744 }
       
   745 
       
   746 EXPORT_C void CSecureSocket::StartClientHandshake(TRequestStatus& aStatus)
       
   747 /** 
       
   748  * Starts the client handshake.
       
   749  * 
       
   750  * @param aStatus	On completion, KErrNone if successful; 
       
   751  *					otherwise, a system-wide error code.
       
   752  */
       
   753 {
       
   754 	iSecureImplementation->StartClientHandshake( aStatus );
       
   755 }
       
   756 
       
   757 EXPORT_C void CSecureSocket::StartServerHandshake(TRequestStatus& aStatus)
       
   758 /** 
       
   759  * Starts the server handshake.
       
   760  * 
       
   761  * @param aStatus	On completion, KErrNone if successful;
       
   762  *				 	otherwise, a system-wide error code.
       
   763  */
       
   764 {
       
   765 	iSecureImplementation->StartServerHandshake( aStatus );
       
   766 }
       
   767 
       
   768 TInt SetTLSData()
       
   769 /**
       
   770  * Sets the Thread local storage data.
       
   771  */
       
   772 {
       
   773 	TInt ret=KErrNone;
       
   774 
       
   775 	// Create a new DllGlobals class
       
   776 	TSecureSocketGlobals* global = new TSecureSocketGlobals;
       
   777 	if(!global)
       
   778 		{
       
   779 		return KErrNoMemory;
       
   780 		}
       
   781     
       
   782 	ret = Dll::SetTls( global );
       
   783 
       
   784 	if(ret)
       
   785 		{
       
   786 		delete global;
       
   787 		}
       
   788 	else
       
   789 		{
       
   790 		global->iUseCount=0;
       
   791 		}
       
   792 
       
   793 	return ret;
       
   794 }
       
   795 	
       
   796