--- /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;
+}
+