diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_sec_engine_8cpp-source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/_sec_engine_8cpp-source.html Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,415 @@ + + +TB10.1 Example Applications: examples/Networking/SecureSockets/SecEngine.cpp Source File + + + + +

examples/Networking/SecureSockets/SecEngine.cpp

00001 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+00002 // All rights reserved.
+00003 // This component and the accompanying materials are made available
+00004 // under the terms of "Eclipse Public License v1.0"
+00005 // which accompanies this distribution, and is available
+00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
+00007 //
+00008 // Initial Contributors:
+00009 // Nokia Corporation - initial contribution.
+00010 //
+00011 // Contributors:
+00012 //
+00013 // Description:
+00014 //
+00015 
+00016 #include "SecEngine.h"
+00017 
+00018 // Send buffer size
+00019 const TInt KSendBufferSize = 256;
+00020 // Receive buffer size
+00021 const TInt KReceiveBufferSize = 256;
+00022 
+00023 // HTTP messages
+00024 _LIT8(KSimpleGet, "GET ");
+00025 _LIT8(KNewLine, "\n"); 
+00026 
+00027 // Progress messages
+00028 _LIT(KConnnectedMessage, "\nConnecting to %S:%d%S\n");
+00029 _LIT(KSecureConnnectingMessage, "\nMaking secure connection");
+00030 _LIT(KGettingPageMessage, "\nRequesting web page");
+00031 _LIT(KReceivingMessage,"\nReceiving server response");
+00032 _LIT(KCipherSuiteInUseMessage,"\nCipher suite in use: %S");
+00033 _LIT(KProtocolMessage, "\nProtocol used in connection: %S");
+00034 _LIT(KReceivedMessage,"\nReceived server response");
+00035 _LIT(KCompleteMessage,"\nTransaction complete: bytes recieved %d");
+00036 _LIT(KFileErrorMessage,"\nError in writing data to file");
+00037 _LIT(KCancelledMessage,"\nConnection closed");
+00038 
+00039 // State reporting messages
+00040 _LIT( KStateErrESocketConnected, "\nError in state ESocketConnected: %d\n" );
+00041 _LIT( KStateErrESettingCiphers, "\nError in state ESettingCiphers: %d\n" );
+00042 _LIT( KStateErrSecureConnected, "\nError in state ESecureConnected: %d\n" );
+00043 _LIT( KStateErrGetRequestSent, "\nError in state EGetRequestSent: %d\n" );
+00044 _LIT( KStateErrEDataReceived, "\nError in state EDataReceived: %d\n" );
+00045 
+00046 // Panic code
+00047 _LIT( KSecEnginePanic, "SEC-ENGINE");
+00048 
+00049 //
+00050 // CSecEngine
+00051 //
+00052 
+00053 CSecEngine* CSecEngine::NewL()
+00054         {
+00055         CSecEngine* self = new(ELeave) CSecEngine;
+00056         CleanupStack::PushL( self );
+00057         self->ConstructL();
+00058         CleanupStack::Pop();            
+00059         return self;
+00060         }
+00061 
+00062 // Constructor should also call the parent constructor to set the priority
+00063 // of the active object.
+00064 CSecEngine::CSecEngine() 
+00065 : CActive(0), iSndBuffer(0,0), iRcvBuffer(0,0)
+00066         {
+00067         }
+00068 
+00069 CSecEngine::~CSecEngine()
+00070         {
+00071         // Cancel any outstanding request- this cleans up
+00072         // resources created during a connection
+00073         //Cancel();     
+00074         ConnectionClosed();
+00075         // Clean up engine's permanent resources
+00076         delete iSndBuffer.Ptr();    
+00077         delete iRcvBuffer.Ptr();                        
+00078         iTimer.Close();
+00079         iSocketServ.Close();
+00080         }
+00081 
+00082 void CSecEngine::ConstructL()
+00083         {
+00084         iSndBuffer.Set((TUint8*)User::AllocL(KSendBufferSize),0,KSendBufferSize);
+00085         iRcvBuffer.Set((TUint8*)User::AllocL(KReceiveBufferSize),0,KReceiveBufferSize);
+00086         // Connect the socket server
+00087         User::LeaveIfError( iSocketServ.Connect());     
+00088         // Create a local timer
+00089         User::LeaveIfError( iTimer.CreateLocal());
+00090         // Set initial state
+00091         iRunState = ESocketConnected;
+00092         iInUse = EFalse;
+00093 
+00094         CActiveScheduler::Add( this );
+00095         }
+00096 
+00097 void CSecEngine::ConnectL(const TConnectSettings& aConnectSettings)
+00098         {
+00099         iConnectSettings = &aConnectSettings;
+00100 
+00101         // Set initial values for flags & buffers
+00102         iSuccess = ETrue;
+00103         iInUse = ETrue;
+00104         iRunState = ESocketConnected;
+00105         iSndBuffer.SetLength( 0 );
+00106         iRcvBuffer.SetLength( 0 );
+00107         iTotalBytesRead = 0;
+00108 
+00109         // Interpret server address
+00110         if (iInetAddr.Input(iConnectSettings->iAddress) != KErrNone)
+00111                 // Success if already in dotted-decimal format
+00112                 {
+00113                 // Connect to a host resolver (for DNS resolution) - happens sychronously
+00114                 User::LeaveIfError( iHostResolver.Open( iSocketServ, KAfInet, KProtocolInetTcp ));
+00115                 // Try to resolve symbolic name
+00116                 TNameEntry nameEntry;
+00117                 User::LeaveIfError (iHostResolver.GetByName( iConnectSettings->iAddress, nameEntry ));
+00118                 TSockAddr sockAddr = nameEntry().iAddr;
+00119                 iInetAddr = iInetAddr.Cast( sockAddr );
+00120                 iHostResolver.Close();
+00121                 }
+00122         // Store other connection parameters
+00123         iInetAddr.SetPort( iConnectSettings->iPortNum );
+00124                                                         
+00125         // Open a TCP socket
+00126         User::LeaveIfError( iSocket.Open( iSocketServ, KAfInet, KSockStream, KProtocolInetTcp ) );      
+00127 
+00128         // Connect to the server, asynchronously
+00129         iSocket.Connect( iInetAddr, iStatus );  
+00130         SetActive();
+00131 
+00132         // Print status
+00133         iConsole->Printf(KConnnectedMessage, 
+00134                 &iConnectSettings->iAddress, 
+00135                 iConnectSettings->iPortNum, 
+00136                 &iConnectSettings->iPage );     
+00137         }
+00138 
+00139 void CSecEngine::SetConsole( CConsoleBase& aConsole )
+00140         {
+00141         iConsole = &aConsole;
+00142         }
+00143 
+00144 void CSecEngine::SetOutputFile( RFile& aOutputFile )
+00145         {
+00146         iOutputFile = &aOutputFile;
+00147         }
+00148 
+00149 TBool CSecEngine::InUse()
+00150         {
+00151         return iInUse;
+00152         }
+00153 
+00154 void CSecEngine::RunL()
+00155         {
+00156         switch ( iRunState )
+00157                 {
+00158         case ESocketConnected:
+00159                 MakeSecureConnectionL();
+00160                 break;
+00161 
+00162         case ESecureConnected:
+00163                 MakePageRequestL();
+00164                 break;
+00165 
+00166         case EGetRequestSent:
+00167                 GetServerResponseL();
+00168                 break;
+00169 
+00170         case EDataReceived:
+00171                 ReadServerResponseL();
+00172                 break;
+00173 
+00174         case EConnectionClosed:
+00175                 ConnectionClosed();
+00176                 break;
+00177 
+00178         default:
+00179                 break;
+00180                 } // end switch
+00181         }
+00182 
+00183 TInt CSecEngine::RunError( TInt aError )
+00184         {
+00185         // Panic prevents looping
+00186         __ASSERT_ALWAYS(iRunState != EConnectionClosed, 
+00187                 User::Panic(KSecEnginePanic,0));
+00188 
+00189         // do a switch on the state to get the right err message
+00190         switch (iRunState)
+00191                 {
+00192                 case ESocketConnected:
+00193                         iConsole->Printf(KStateErrESocketConnected, aError );
+00194                         break;
+00195                 case ESettingCiphers:
+00196                         iConsole->Printf(KStateErrESettingCiphers, aError );
+00197                         break;
+00198                 case ESecureConnected:
+00199                         iConsole->Printf(KStateErrSecureConnected, aError);
+00200                         break;
+00201                 case EGetRequestSent:
+00202                         iConsole->Printf(KStateErrGetRequestSent, aError);
+00203                         break;
+00204                 case EDataReceived:
+00205                         iConsole->Printf(KStateErrEDataReceived, aError);
+00206                         break;
+00207                 default:
+00208                         break;
+00209                 }
+00210 
+00211         iRunState = EConnectionClosed;
+00212         iSuccess = EFalse;
+00213         iTimer.After( iStatus, 1000000 );
+00214         SetActive();
+00215 
+00216         return KErrNone;
+00217         }
+00218 
+00219 void CSecEngine::DoCancel()
+00220         {
+00221         iConsole->Printf(KCancelledMessage);
+00222         ConnectionClosed();
+00223         }
+00224 
+00225 void CSecEngine::MakeSecureConnectionL()
+00226         {
+00227         User::LeaveIfError(iStatus.Int()); // errors caught by RunError()
+00228 
+00229         // Construct the TLS socket, to use the TLS1.0 protocol.
+00230         // Specifying SSL3.0 would also use the same implementation
+00231         iConsole->Printf(KSecureConnnectingMessage);
+00232         _LIT(KTLS1,"TLS1.0");
+00233         iTlsSocket = CSecureSocket::NewL( iSocket, KTLS1 );
+00234 
+00235         // Set any options before the handshake starts
+00236 
+00237         // Clears any previous options
+00238         iTlsSocket->FlushSessionCache();
+00239         
+00240 /*      Note: You could here set the available ciphers with code such as the following:
+00241         TBuf8<2> buf;
+00242         buf.SetLength(2);
+00243         buf[0]=0; buf[1]=10;
+00244         iTlsSocket->SetAvailableCipherSuites( buf ); */
+00245         
+00246         // start the handshake 
+00247         iTlsSocket->StartClientHandshake( iStatus );
+00248 
+00249         iRunState = ESecureConnected;
+00250         SetActive();
+00251         }
+00252 
+00253 void CSecEngine::MakePageRequestL()
+00254         {
+00255         // The secure connection has now been made.
+00256         // Send a get request for the page.
+00257         User::LeaveIfError(iStatus.Int());
+00258         iConsole->Printf(KGettingPageMessage);
+00259         
+00260         // Create a GET request
+00261         iSndBuffer+=KSimpleGet;
+00262         iSndBuffer+=iConnectSettings->iPage;
+00263         iSndBuffer+=KNewLine;
+00264 
+00265         // Send the request
+00266         iRunState = EGetRequestSent;
+00267         iTlsSocket->Send( iSndBuffer, iStatus, iBytesSent );
+00268         SetActive();
+00269         }
+00270 
+00271 void CSecEngine::GetServerResponseL()           
+00272         {
+00273         // The get request has been sent, can now try and receive the data
+00274         User::LeaveIfError(iStatus.Int());
+00275         iConsole->Printf(KReceivingMessage);
+00276         
+00277         // Print the cipher suite that has been negotiated.
+00278         TBuf8<2> buf; 
+00279         User::LeaveIfError(iTlsSocket->CurrentCipherSuite( buf ));
+00280         PrintCipherNameL(buf);
+00281 
+00282         // Print the protocol version string
+00283         TBuf<32> protocol;
+00284         User::LeaveIfError(iTlsSocket->Protocol( protocol ));
+00285         iConsole->Printf(KProtocolMessage, &protocol );
+00286         
+00287         // Print info about the server's certificate
+00288         const CX509Certificate *servCert = iTlsSocket->ServerCert();
+00289         if ( servCert ) PrintCertInfo( *servCert );
+00290         
+00291         // Read asynchonously-returns when buffer full
+00292         iRunState = EDataReceived;
+00293         iTlsSocket->Recv( iRcvBuffer, iStatus );
+00294         SetActive();
+00295         }
+00296 
+00297 void CSecEngine::ReadServerResponseL()
+00298         {
+00299         // Any error other than KErrEof means the test is a failure
+00300         if (iStatus!=KErrEof) User::LeaveIfError(iStatus.Int());
+00301         iConsole->Printf(KReceivedMessage);
+00302 
+00303         // Put the received data in the output file & reset the receive buffer
+00304         iTotalBytesRead += iRcvBuffer.Length();
+00305         TInt ret = iOutputFile->Write(iRcvBuffer);
+00306         if (ret != KErrNone) iConsole->Printf(KFileErrorMessage);
+00307         
+00308         // Case 1: error is KErrEof (message complete) or no data received, so stop
+00309         if ( ( iStatus==KErrEof ) || ( iRcvBuffer.Length() == 0 ) )
+00310                 {
+00311                 iConsole->Printf(KCompleteMessage, iTotalBytesRead);
+00312                 // Close the socket neatly
+00313                 iRunState = EConnectionClosed;
+00314                 iTimer.After( iStatus, 1000000 );
+00315                 SetActive();
+00316                 return; 
+00317                 }
+00318 
+00319         // Case 2: there's more data to get from the server
+00320         iRcvBuffer.SetLength( 0 );
+00321         iRunState = EDataReceived;
+00322         iTlsSocket->Recv( iRcvBuffer, iStatus );
+00323         SetActive(); 
+00324         }
+00325 
+00326 void CSecEngine::ConnectionClosed()
+00327         {
+00328         if (!iInUse) return;
+00329         // Clean up
+00330         iHostResolver.Close();
+00331         delete iTlsSocket;
+00332         iTlsSocket =0;
+00333         iSocket.Close();
+00334 
+00335         // Wait here for an unload of the ssl.dll to make sure that a session is not
+00336         // reconnected next time. 
+00337         User::After( 1000000 );
+00338         iInUse = EFalse;
+00339         }
+00340 
+00341 void CSecEngine::PrintCipherNameL(const TDes8& aBuf)
+00342         {
+00343         TLex8 lex(aBuf);
+00344         TUint cipherCode=aBuf[1];
+00345         if ((cipherCode<1) || (cipherCode > 0x1B))
+00346                 User::Leave(KErrArgument);
+00347         const TText* KCipherNameArray[0x1B] = 
+00348                 {
+00349                 _S("TLS_RSA_WITH_NULL_MD5"),
+00350                 _S("TLS_RSA_WITH_NULL_SHA"),
+00351                 _S("TLS_RSA_EXPORT_WITH_RC4_40_MD5"),
+00352                 _S("TLS_RSA_WITH_RC4_128_MD5"),
+00353                 _S("TLS_RSA_WITH_RC4_128_SHA"),
+00354                 _S("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"),
+00355                 _S("TLS_RSA_WITH_IDEA_CBC_SHA"),
+00356                 _S("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+00357                 _S("TLS_RSA_WITH_DES_CBC_SHA"),
+00358                 _S("TLS_RSA_WITH_3DES_EDE_CBC_SHA"),
+00359                 _S("TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"),
+00360                 _S("TLS_DH_DSS_WITH_DES_CBC_SHA"),
+00361                 _S("TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"),
+00362                 _S("TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+00363                 _S("TLS_DH_RSA_WITH_DES_CBC_SHA"),
+00364                 _S("TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"),
+00365                 _S("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"),
+00366                 _S("TLS_DHE_DSS_WITH_DES_CBC_SHA"),
+00367                 _S("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"),
+00368                 _S("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"),
+00369                 _S("TLS_DHE_RSA_WITH_DES_CBC_SHA"),
+00370                 _S("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"),
+00371                 _S("TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"),
+00372                 _S("TLS_DH_anon_WITH_RC4_128_MD5"),
+00373                 _S("TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"),
+00374                 _S("TLS_DH_anon_WITH_DES_CBC_SHA"),
+00375                 _S("TLS_DH_anon_WITH_3DES_EDE_CBC_SHA")
+00376                 };
+00377 
+00378         TPtrC name(KCipherNameArray[cipherCode-1]);
+00379         iConsole->Printf(KCipherSuiteInUseMessage, &name );
+00380         }
+00381 
+00382 void CSecEngine::PrintCertInfo(const CX509Certificate& aSource)
+00383         {
+00384         _LIT(KCertInfoMessage1, "\nCertificate received: \n\tIssuer %S \n\tSubject %S");
+00385         _LIT(KCertInfoMessage2, "\n\tValid from %S to %S");
+00386         _LIT(KDateString,"%F%/0%M%/1%Y%/2%D%/3");
+00387 
+00388         TRAP_IGNORE(
+00389                 // Print issuer and subject
+00390                 HBufC* issuer = aSource.IssuerL();
+00391                 HBufC* subject = aSource.SubjectL();
+00392                 iConsole->Printf(KCertInfoMessage1, issuer, subject);
+00393                 delete issuer;
+00394                 delete subject;
+00395                 
+00396                 // Print validity period
+00397                 TBuf<20> startTime;
+00398                 TBuf<20> finishTime;
+00399                 aSource.ValidityPeriod().Start().FormatL(startTime,KDateString);
+00400                 aSource.ValidityPeriod().Finish().FormatL(finishTime,KDateString);
+00401                 iConsole->Printf(KCertInfoMessage2, &startTime, &finishTime);
+00402                 );
+00403         }
+

Generated on Thu Jan 21 10:33:00 2010 for TB10.1 Example Applications by  + +doxygen 1.5.3
+ +