javacommons/security/src.s60/ocspclient.cpp
changeset 21 2a9601315dfc
child 80 d6dafc5d983f
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 2007-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ocspclient.h"
       
    20 
       
    21 using namespace java::security;
       
    22 using namespace std;
       
    23 using namespace java::util;
       
    24 
       
    25 const TInt KCertStoreUIDForSWInstallOCSPSigning = 268478646;
       
    26 
       
    27 OcspClient* OcspClient::createInstance(long iap, const char* defaultUrl)
       
    28 {
       
    29     OcspClient* self = new OcspClient(iap);
       
    30     TRAPD(err, self->ConstructL(defaultUrl));
       
    31     if (err != KErrNone)
       
    32     {
       
    33         delete self;
       
    34         self = NULL;
       
    35     }
       
    36     return self;
       
    37 }
       
    38 
       
    39 OcspClient::OcspClient(long iap)
       
    40         : CActive(EPriorityNormal), iIap(TUint32(iap)), iDefaultUrl(NULL), iOcspClient(NULL), iCertStore(NULL), iInitialized(false), iOcspResponse(NULL), iCertArray(NULL), iMonitor(NULL)
       
    41 {
       
    42     CActiveScheduler::Add(this);
       
    43 }
       
    44 
       
    45 void OcspClient::ConstructL(const char* defaultUrl)
       
    46 {
       
    47     User::LeaveIfError(iRfs.Connect());
       
    48     iCertStore = CUnifiedCertStore::NewL(iRfs, false /*aOpenForWrite*/);
       
    49     iOcspResponse = OcspResponse::NewL();
       
    50     // create the monitor
       
    51     iMonitor = Monitor::createMonitor();
       
    52     if (defaultUrl)
       
    53     {
       
    54         int len = strlen(defaultUrl);
       
    55         iDefaultUrl = HBufC8::NewL(len);
       
    56         TPtr8 defaultUrlPtr = iDefaultUrl->Des();
       
    57         TPtr8 ptr((TUint8 *)defaultUrl, len);
       
    58         ptr.SetLength(len);
       
    59         defaultUrlPtr.Copy(ptr);
       
    60     }
       
    61 }
       
    62 
       
    63 void OcspClient::RunL()
       
    64 {
       
    65     switch (iState)
       
    66     {
       
    67     case ESendOcspRequest:
       
    68         SendOcspRequestL();
       
    69         iState = EProcessOcspResponse;
       
    70         break;
       
    71     case EProcessOcspResponse:
       
    72         ProcessOcspResponse();
       
    73         iMonitor->notify();
       
    74         return;
       
    75     }
       
    76     // re-issue a new request
       
    77     SetActive();
       
    78 }
       
    79 
       
    80 void OcspClient::DoCancel()
       
    81 {
       
    82     if (iCertStore)
       
    83     {
       
    84         iCertStore->CancelInitialize();
       
    85     }
       
    86     if (iOcspClient)
       
    87     {
       
    88         iOcspClient->CancelCheck();
       
    89     }
       
    90 }
       
    91 
       
    92 TInt OcspClient::RunError(TInt /*aError*/)
       
    93 {
       
    94     return KErrNone;
       
    95 }
       
    96 
       
    97 OcspClient::~OcspClient()
       
    98 {
       
    99     if (IsActive())
       
   100     {
       
   101         Cancel();
       
   102     }
       
   103     if (iCertStore)
       
   104     {
       
   105         delete iCertStore;
       
   106         iCertStore = NULL;
       
   107     }
       
   108     if (iOcspClient)
       
   109     {
       
   110         delete iOcspClient;
       
   111         iOcspClient = NULL;
       
   112     }
       
   113     if (iOcspResponse)
       
   114     {
       
   115         delete iOcspResponse;
       
   116         iOcspResponse = NULL;
       
   117     }
       
   118     if (iCertArray)
       
   119     {
       
   120         iCertArray->ResetAndDestroy();
       
   121         delete iCertArray;
       
   122     }
       
   123     if (iDefaultUrl)
       
   124     {
       
   125         delete iDefaultUrl;
       
   126         iDefaultUrl = NULL;
       
   127     }
       
   128     if (iMonitor)
       
   129     {
       
   130         delete iMonitor;
       
   131         iMonitor = NULL;
       
   132     }
       
   133     iRfs.Close();
       
   134 }
       
   135 
       
   136 void OcspClient::startOcspCheck(const char ** aCertChain, int aCertChainLen)
       
   137 {
       
   138 
       
   139     // clear the response
       
   140     iOcspResponse->Clear();
       
   141     // build up the chain
       
   142     iCertChain = aCertChain;
       
   143     iCertChainLen = aCertChainLen;
       
   144     // kick off the state machine
       
   145     Start();
       
   146 }
       
   147 
       
   148 OcspResponse OcspClient::getOcspCheckResponse()
       
   149 {
       
   150     // wait for completion
       
   151     iMonitor->wait();
       
   152     // return the result
       
   153     return *iOcspResponse;
       
   154 }
       
   155 
       
   156 void OcspClient::cancelOcspCheck(bool doCleanup)
       
   157 {
       
   158     // cancel the outstanding request (if any)
       
   159     if (doCleanup)
       
   160     {
       
   161         if (IsActive())
       
   162         {
       
   163             Cancel();
       
   164         }
       
   165     }
       
   166     iMonitor->notify();
       
   167 }
       
   168 
       
   169 void OcspClient::Start()
       
   170 {
       
   171     // cancel the outstanding request (if any)
       
   172     if (IsActive())
       
   173     {
       
   174         Cancel();
       
   175     }
       
   176 
       
   177     iState = ESendOcspRequest;
       
   178     SetActive();
       
   179     if (iInitialized)
       
   180     {
       
   181         // already initialized
       
   182         CompleteRequest();
       
   183         return;
       
   184     }
       
   185 
       
   186     // do the initialization
       
   187     iCertStore->Initialize(iStatus);
       
   188     iInitialized = true;
       
   189 }
       
   190 
       
   191 void OcspClient::SendOcspRequestL()
       
   192 {
       
   193     InitOcspClientL();
       
   194     iOcspClient->Check(iStatus);
       
   195 }
       
   196 
       
   197 void OcspClient::ProcessOcspResponse()
       
   198 {
       
   199     int summary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
       
   200     if (iStatus.Int() == KErrNone)
       
   201     {
       
   202         // set the summary
       
   203         switch (iOcspClient->SummaryResult())
       
   204         {
       
   205         case OCSP::EGood:
       
   206             summary = RESPONSE_GOOD;
       
   207             break;
       
   208         case OCSP::EUnknown:
       
   209             summary = RESPONSE_UNKNOWN;
       
   210             break;
       
   211         case OCSP::ERevoked:
       
   212             summary = RESPONSE_REVOKED;
       
   213             break;
       
   214         }
       
   215         // set the individual responses
       
   216         for (TInt index = 0 ; index < iOcspClient->TransactionCount() ; ++index)
       
   217         {
       
   218             const TOCSPOutcome& outcome = iOcspClient->Outcome(index);
       
   219             switch (outcome.iStatus)
       
   220             {
       
   221             case OCSP::ETransportError:
       
   222             case OCSP::EClientInternalError:
       
   223             case OCSP::EMalformedRequest:
       
   224             case OCSP::EServerInternalError:
       
   225             case OCSP::ETryLater:
       
   226             case OCSP::ESignatureRequired:
       
   227             case OCSP::EClientUnauthorised:
       
   228             case OCSP::EUnknownResponseType:
       
   229                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_CANNOT_OBTAIN_CERT_STATUS);
       
   230                 break;
       
   231             case OCSP::ENoServerSpecified:
       
   232             case OCSP::EInvalidURI:
       
   233                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_URI);
       
   234                 break;
       
   235             case OCSP::EResponseSignatureValidationFailure:
       
   236                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_SIGNATURE_VALIDATION_FAILURE);
       
   237                 break;
       
   238             case OCSP::EThisUpdateTooLate:
       
   239             case OCSP::EThisUpdateTooEarly:
       
   240             case OCSP::ENextUpdateTooEarly:
       
   241             case OCSP::ENonceMismatch:
       
   242             case OCSP::EMalformedResponse:
       
   243             case OCSP::EUnknownCriticalExtension:
       
   244             case OCSP::EMissingCertificates:
       
   245                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_RESPONSE);
       
   246                 break;
       
   247             case OCSP::EMissingNonce:
       
   248                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_MISSING_NONCE);
       
   249                 break;
       
   250             case OCSP::ECertificateNotValidAtValidationTime:
       
   251                 iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_CERT_STATUS_INFO);
       
   252                 break;
       
   253             case OCSP::EValid:
       
   254                 switch (outcome.iResult)
       
   255                 {
       
   256                 case OCSP::EGood:
       
   257                     iOcspResponse->iIndividualResponses.push_back(RESPONSE_GOOD);
       
   258                     break;
       
   259                 case OCSP::EUnknown:
       
   260                     iOcspResponse->iIndividualResponses.push_back(RESPONSE_UNKNOWN);
       
   261                     break;
       
   262                 case OCSP::ERevoked:
       
   263                     iOcspResponse->iIndividualResponses.push_back(RESPONSE_REVOKED);
       
   264                     break;
       
   265                 default:
       
   266                     ASSERT(EFalse);
       
   267                 }
       
   268                 break;
       
   269             default:
       
   270                 ASSERT(EFalse);
       
   271                 break;
       
   272             }
       
   273         }
       
   274     }
       
   275     iOcspResponse->iSummary = summary;
       
   276 }
       
   277 
       
   278 void OcspClient::CompleteRequest()
       
   279 {
       
   280     TRequestStatus* status = &iStatus;
       
   281     User::RequestComplete(status,KErrNone);
       
   282 }
       
   283 
       
   284 void OcspClient::InitOcspClientL()
       
   285 {
       
   286     if (iOcspClient)
       
   287     {
       
   288         delete iOcspClient;
       
   289         iOcspClient = NULL;
       
   290     }
       
   291     if (iCertArray)
       
   292     {
       
   293         iCertArray->ResetAndDestroy();
       
   294         delete iCertArray;
       
   295     }
       
   296     COCSPParameters* ocspParams = COCSPParameters::NewL();
       
   297     if (iDefaultUrl)
       
   298     {
       
   299         ocspParams->SetURIL(*iDefaultUrl, ETrue);
       
   300     }
       
   301     ocspParams->SetTransport(COCSPTransportDefault::NewL(iIap));
       
   302     ocspParams->AddAllAuthorisationSchemesL(
       
   303         TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning), *iCertStore);
       
   304     // add the certs
       
   305     if (iCertChainLen >= 2)
       
   306     {
       
   307         iCertArray = new(ELeave) CArrayPtrFlat<CX509Certificate>(1);
       
   308         std::string cert = JavaCommonUtils::base64decode(std::string(iCertChain[0], strlen(iCertChain[0])));
       
   309         TPtr8 ptr8((TUint8 *)(cert.c_str()), cert.size());
       
   310         ptr8.SetLength(cert.size());
       
   311         CX509Certificate* issuerCert = CX509Certificate::NewL(ptr8);
       
   312         iCertArray->AppendL(issuerCert);
       
   313         CX509Certificate* subjectCert = NULL;
       
   314         for (int i = 1; i < iCertChainLen; i++)
       
   315         {
       
   316             subjectCert = issuerCert;
       
   317             cert = JavaCommonUtils::base64decode(std::string(iCertChain[i], strlen(iCertChain[i])));
       
   318             TPtr8 ptr((TUint8 *)(cert.c_str()), cert.size());
       
   319             ptr.SetLength(cert.size());
       
   320             issuerCert = CX509Certificate::NewL(ptr);
       
   321             iCertArray->AppendL(issuerCert);
       
   322             ocspParams->AddCertificateL(*subjectCert, *issuerCert);
       
   323         }
       
   324     }
       
   325     iOcspClient = COCSPClient::NewL(ocspParams);
       
   326 }
       
   327 
       
   328 OcspResponse* OcspResponse::NewL()
       
   329 {
       
   330     OcspResponse* self = new(ELeave) OcspResponse();
       
   331     CleanupStack::PushL(self);
       
   332     self->ConstructL();
       
   333     CleanupStack::Pop(self);
       
   334     return self;
       
   335 }
       
   336 
       
   337 OcspResponse::OcspResponse()
       
   338 {
       
   339     iIndividualResponses.clear();
       
   340     iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
       
   341 }
       
   342 
       
   343 void OcspResponse::ConstructL()
       
   344 {
       
   345 }
       
   346 
       
   347 OcspResponse::~OcspResponse()
       
   348 {
       
   349 }
       
   350 
       
   351 void OcspResponse::Clear()
       
   352 {
       
   353     iIndividualResponses.clear();
       
   354     iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
       
   355 }
       
   356 
       
   357 OcspResponse& OcspResponse::operator=(const OcspResponse& x)
       
   358 {
       
   359     iSummary = x.iSummary;
       
   360     iIndividualResponses = x.iIndividualResponses;
       
   361     return *this;
       
   362 }
       
   363 
       
   364 OcspResponse::OcspResponse(const OcspResponse& x)
       
   365 {
       
   366     *this = x;
       
   367 }
       
   368