summaryrefslogtreecommitdiff
path: root/ucb/source/ucp/webdav/NeonSession.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'ucb/source/ucp/webdav/NeonSession.cxx')
-rw-r--r--ucb/source/ucp/webdav/NeonSession.cxx46
1 files changed, 38 insertions, 8 deletions
diff --git a/ucb/source/ucp/webdav/NeonSession.cxx b/ucb/source/ucp/webdav/NeonSession.cxx
index 128606b7ac..292884c3db 100644
--- a/ucb/source/ucp/webdav/NeonSession.cxx
+++ b/ucb/source/ucp/webdav/NeonSession.cxx
@@ -32,6 +32,7 @@
#include "precompiled_ucb.hxx"
#include <hash_map>
+#include <vector>
#include <string.h>
#include <rtl/string.h>
#include <ne_socket.h>
@@ -41,6 +42,8 @@
#include <ne_ssl.h>
#include "libxml/parser.h"
#include <rtl/ustrbuf.hxx>
+#include "comphelper/sequence.hxx"
+
#include "DAVAuthListener.hxx"
#include "NeonTypes.hxx"
#include "NeonSession.hxx"
@@ -395,6 +398,7 @@ extern "C" int NeonSession_CertificationNotify( void *userdata,
int failures,
const ne_ssl_certificate *cert )
{
+ OSL_ASSERT(cert);
NeonSession * pSession = static_cast< NeonSession * >( userdata );
uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecurityEnv;
uno::Reference< ::com::sun::star::security::XCertificateContainer > xCertificateContainer;
@@ -442,18 +446,44 @@ extern "C" int NeonSession_CertificationNotify( void *userdata,
xSecurityEnv = mxSecurityContext->getSecurityEnvironment();
- char * rawCert;
-
- rawCert = ne_ssl_cert_export( cert );
+ //The end entity certificate
+ char * eeCertB64 = ne_ssl_cert_export( cert );
- ::rtl::OString sRawCert( rawCert );
+ ::rtl::OString sEECertB64( eeCertB64 );
- uno::Reference< com::sun::star::security::XCertificate> xCert = xSecurityEnv->createCertificateFromAscii( ::rtl::OStringToOUString( sRawCert, RTL_TEXTENCODING_ASCII_US ) );
+ uno::Reference< com::sun::star::security::XCertificate> xEECert =
+ xSecurityEnv->createCertificateFromAscii(
+ ::rtl::OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) );
- sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xCert );
+ free(eeCertB64);
+ eeCertB64 = NULL;
+
+ std::vector<uno::Reference<com::sun::star::security::XCertificate> > vecCerts;
+ const ne_ssl_certificate * issuerCert = cert;
+ do
+ {
+ //get the intermediate certificate
+ //the returned value is const ! Therfore it does not need to be freed
+ //with ne_ssl_cert_free, which takes a non-const argument
+ issuerCert = ne_ssl_cert_signedby(issuerCert);
+ if (NULL == issuerCert)
+ break;
+
+ char * imCertB64 = ne_ssl_cert_export(issuerCert);
+ ::rtl::OString sInterMediateCertB64(imCertB64);
+ free(imCertB64);
+ uno::Reference< com::sun::star::security::XCertificate> xImCert =
+ xSecurityEnv->createCertificateFromAscii(
+ ::rtl::OStringToOUString( sInterMediateCertB64, RTL_TEXTENCODING_ASCII_US ) );
+ if (xImCert.is())
+ vecCerts.push_back(xImCert);
+ }while (1);
+
+ sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xEECert,
+ ::comphelper::containerToSequence(vecCerts) );
- if ( pSession->isDomainMatch( GetHostnamePart( xCert.get()->getSubjectName())) )
+ if ( pSession->isDomainMatch( GetHostnamePart( xEECert.get()->getSubjectName())) )
{
//if host name matched with certificate then look if the certificate was ok
if( certValidity == ::security::CertificateValidity::VALID )
@@ -472,7 +502,7 @@ extern "C" int NeonSession_CertificationNotify( void *userdata,
if ( xIH.is() )
{
rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > xRequest
- = new ucbhelper::SimpleCertificateValidationRequest((sal_Int32)failures, xCert, pSession->getHostName() );
+ = new ucbhelper::SimpleCertificateValidationRequest((sal_Int32)failures, xEECert, pSession->getHostName() );
xIH->handle( xRequest.get() );
rtl::Reference< ucbhelper::InteractionContinuation > xSelection