javacommons/security/src.s60/ocspclient.cpp
branchRCL_3
changeset 19 04becd199f91
child 80 d6dafc5d983f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/security/src.s60/ocspclient.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2007-2007 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:
+*
+*/
+
+
+#include "ocspclient.h"
+
+using namespace java::security;
+using namespace std;
+using namespace java::util;
+
+const TInt KCertStoreUIDForSWInstallOCSPSigning = 268478646;
+
+OcspClient* OcspClient::createInstance(long iap, const char* defaultUrl)
+{
+    OcspClient* self = new OcspClient(iap);
+    TRAPD(err, self->ConstructL(defaultUrl));
+    if (err != KErrNone)
+    {
+        delete self;
+        self = NULL;
+    }
+    return self;
+}
+
+OcspClient::OcspClient(long iap)
+        : CActive(EPriorityNormal), iIap(TUint32(iap)), iDefaultUrl(NULL), iOcspClient(NULL), iCertStore(NULL), iInitialized(false), iOcspResponse(NULL), iCertArray(NULL), iMonitor(NULL)
+{
+    CActiveScheduler::Add(this);
+}
+
+void OcspClient::ConstructL(const char* defaultUrl)
+{
+    User::LeaveIfError(iRfs.Connect());
+    iCertStore = CUnifiedCertStore::NewL(iRfs, false /*aOpenForWrite*/);
+    iOcspResponse = OcspResponse::NewL();
+    // create the monitor
+    iMonitor = Monitor::createMonitor();
+    if (defaultUrl)
+    {
+        int len = strlen(defaultUrl);
+        iDefaultUrl = HBufC8::NewL(len);
+        TPtr8 defaultUrlPtr = iDefaultUrl->Des();
+        TPtr8 ptr((TUint8 *)defaultUrl, len);
+        ptr.SetLength(len);
+        defaultUrlPtr.Copy(ptr);
+    }
+}
+
+void OcspClient::RunL()
+{
+    switch (iState)
+    {
+    case ESendOcspRequest:
+        SendOcspRequestL();
+        iState = EProcessOcspResponse;
+        break;
+    case EProcessOcspResponse:
+        ProcessOcspResponse();
+        iMonitor->notify();
+        return;
+    }
+    // re-issue a new request
+    SetActive();
+}
+
+void OcspClient::DoCancel()
+{
+    if (iCertStore)
+    {
+        iCertStore->CancelInitialize();
+    }
+    if (iOcspClient)
+    {
+        iOcspClient->CancelCheck();
+    }
+}
+
+TInt OcspClient::RunError(TInt /*aError*/)
+{
+    return KErrNone;
+}
+
+OcspClient::~OcspClient()
+{
+    if (IsActive())
+    {
+        Cancel();
+    }
+    if (iCertStore)
+    {
+        delete iCertStore;
+        iCertStore = NULL;
+    }
+    if (iOcspClient)
+    {
+        delete iOcspClient;
+        iOcspClient = NULL;
+    }
+    if (iOcspResponse)
+    {
+        delete iOcspResponse;
+        iOcspResponse = NULL;
+    }
+    if (iCertArray)
+    {
+        iCertArray->ResetAndDestroy();
+        delete iCertArray;
+    }
+    if (iDefaultUrl)
+    {
+        delete iDefaultUrl;
+        iDefaultUrl = NULL;
+    }
+    if (iMonitor)
+    {
+        delete iMonitor;
+        iMonitor = NULL;
+    }
+    iRfs.Close();
+}
+
+void OcspClient::startOcspCheck(const char ** aCertChain, int aCertChainLen)
+{
+
+    // clear the response
+    iOcspResponse->Clear();
+    // build up the chain
+    iCertChain = aCertChain;
+    iCertChainLen = aCertChainLen;
+    // kick off the state machine
+    Start();
+}
+
+OcspResponse OcspClient::getOcspCheckResponse()
+{
+    // wait for completion
+    iMonitor->wait();
+    // return the result
+    return *iOcspResponse;
+}
+
+void OcspClient::cancelOcspCheck(bool doCleanup)
+{
+    // cancel the outstanding request (if any)
+    if (doCleanup)
+    {
+        if (IsActive())
+        {
+            Cancel();
+        }
+    }
+    iMonitor->notify();
+}
+
+void OcspClient::Start()
+{
+    // cancel the outstanding request (if any)
+    if (IsActive())
+    {
+        Cancel();
+    }
+
+    iState = ESendOcspRequest;
+    SetActive();
+    if (iInitialized)
+    {
+        // already initialized
+        CompleteRequest();
+        return;
+    }
+
+    // do the initialization
+    iCertStore->Initialize(iStatus);
+    iInitialized = true;
+}
+
+void OcspClient::SendOcspRequestL()
+{
+    InitOcspClientL();
+    iOcspClient->Check(iStatus);
+}
+
+void OcspClient::ProcessOcspResponse()
+{
+    int summary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
+    if (iStatus.Int() == KErrNone)
+    {
+        // set the summary
+        switch (iOcspClient->SummaryResult())
+        {
+        case OCSP::EGood:
+            summary = RESPONSE_GOOD;
+            break;
+        case OCSP::EUnknown:
+            summary = RESPONSE_UNKNOWN;
+            break;
+        case OCSP::ERevoked:
+            summary = RESPONSE_REVOKED;
+            break;
+        }
+        // set the individual responses
+        for (TInt index = 0 ; index < iOcspClient->TransactionCount() ; ++index)
+        {
+            const TOCSPOutcome& outcome = iOcspClient->Outcome(index);
+            switch (outcome.iStatus)
+            {
+            case OCSP::ETransportError:
+            case OCSP::EClientInternalError:
+            case OCSP::EMalformedRequest:
+            case OCSP::EServerInternalError:
+            case OCSP::ETryLater:
+            case OCSP::ESignatureRequired:
+            case OCSP::EClientUnauthorised:
+            case OCSP::EUnknownResponseType:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_CANNOT_OBTAIN_CERT_STATUS);
+                break;
+            case OCSP::ENoServerSpecified:
+            case OCSP::EInvalidURI:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_URI);
+                break;
+            case OCSP::EResponseSignatureValidationFailure:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_SIGNATURE_VALIDATION_FAILURE);
+                break;
+            case OCSP::EThisUpdateTooLate:
+            case OCSP::EThisUpdateTooEarly:
+            case OCSP::ENextUpdateTooEarly:
+            case OCSP::ENonceMismatch:
+            case OCSP::EMalformedResponse:
+            case OCSP::EUnknownCriticalExtension:
+            case OCSP::EMissingCertificates:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_REVOCATION_SERVER_RESPONSE);
+                break;
+            case OCSP::EMissingNonce:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_MISSING_NONCE);
+                break;
+            case OCSP::ECertificateNotValidAtValidationTime:
+                iOcspResponse->iIndividualResponses.push_back(RESPONSE_INVALID_CERT_STATUS_INFO);
+                break;
+            case OCSP::EValid:
+                switch (outcome.iResult)
+                {
+                case OCSP::EGood:
+                    iOcspResponse->iIndividualResponses.push_back(RESPONSE_GOOD);
+                    break;
+                case OCSP::EUnknown:
+                    iOcspResponse->iIndividualResponses.push_back(RESPONSE_UNKNOWN);
+                    break;
+                case OCSP::ERevoked:
+                    iOcspResponse->iIndividualResponses.push_back(RESPONSE_REVOKED);
+                    break;
+                default:
+                    ASSERT(EFalse);
+                }
+                break;
+            default:
+                ASSERT(EFalse);
+                break;
+            }
+        }
+    }
+    iOcspResponse->iSummary = summary;
+}
+
+void OcspClient::CompleteRequest()
+{
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete(status,KErrNone);
+}
+
+void OcspClient::InitOcspClientL()
+{
+    if (iOcspClient)
+    {
+        delete iOcspClient;
+        iOcspClient = NULL;
+    }
+    if (iCertArray)
+    {
+        iCertArray->ResetAndDestroy();
+        delete iCertArray;
+    }
+    COCSPParameters* ocspParams = COCSPParameters::NewL();
+    if (iDefaultUrl)
+    {
+        ocspParams->SetURIL(*iDefaultUrl, ETrue);
+    }
+    ocspParams->SetTransport(COCSPTransportDefault::NewL(iIap));
+    ocspParams->AddAllAuthorisationSchemesL(
+        TUid::Uid(KCertStoreUIDForSWInstallOCSPSigning), *iCertStore);
+    // add the certs
+    if (iCertChainLen >= 2)
+    {
+        iCertArray = new(ELeave) CArrayPtrFlat<CX509Certificate>(1);
+        std::string cert = JavaCommonUtils::base64decode(std::string(iCertChain[0], strlen(iCertChain[0])));
+        TPtr8 ptr8((TUint8 *)(cert.c_str()), cert.size());
+        ptr8.SetLength(cert.size());
+        CX509Certificate* issuerCert = CX509Certificate::NewL(ptr8);
+        iCertArray->AppendL(issuerCert);
+        CX509Certificate* subjectCert = NULL;
+        for (int i = 1; i < iCertChainLen; i++)
+        {
+            subjectCert = issuerCert;
+            cert = JavaCommonUtils::base64decode(std::string(iCertChain[i], strlen(iCertChain[i])));
+            TPtr8 ptr((TUint8 *)(cert.c_str()), cert.size());
+            ptr.SetLength(cert.size());
+            issuerCert = CX509Certificate::NewL(ptr);
+            iCertArray->AppendL(issuerCert);
+            ocspParams->AddCertificateL(*subjectCert, *issuerCert);
+        }
+    }
+    iOcspClient = COCSPClient::NewL(ocspParams);
+}
+
+OcspResponse* OcspResponse::NewL()
+{
+    OcspResponse* self = new(ELeave) OcspResponse();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+OcspResponse::OcspResponse()
+{
+    iIndividualResponses.clear();
+    iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
+}
+
+void OcspResponse::ConstructL()
+{
+}
+
+OcspResponse::~OcspResponse()
+{
+}
+
+void OcspResponse::Clear()
+{
+    iIndividualResponses.clear();
+    iSummary = RESPONSE_CANNOT_OBTAIN_CERT_STATUS;
+}
+
+OcspResponse& OcspResponse::operator=(const OcspResponse& x)
+{
+    iSummary = x.iSummary;
+    iIndividualResponses = x.iIndividualResponses;
+    return *this;
+}
+
+OcspResponse::OcspResponse(const OcspResponse& x)
+{
+    *this = x;
+}
+