You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by af...@apache.org on 2012/03/01 11:14:03 UTC
svn commit: r1295493 - in /incubator/ooo/trunk: ext_libraries/serf/
main/ucb/source/ucp/webdav/
Author: af
Date: Thu Mar 1 10:14:02 2012
New Revision: 1295493
URL: http://svn.apache.org/viewvc?rev=1295493&view=rev
Log:
118569: Use whole certification chain for verification.
Added:
incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68.patch
incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68b.patch
Modified:
incubator/ooo/trunk/ext_libraries/serf/makefile.mk
incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.cxx
incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.hxx
incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.cxx
incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.hxx
Modified: incubator/ooo/trunk/ext_libraries/serf/makefile.mk
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/ext_libraries/serf/makefile.mk?rev=1295493&r1=1295492&r2=1295493&view=diff
==============================================================================
--- incubator/ooo/trunk/ext_libraries/serf/makefile.mk (original)
+++ incubator/ooo/trunk/ext_libraries/serf/makefile.mk Thu Mar 1 10:14:02 2012
@@ -37,8 +37,15 @@ LIBSERFVERSION=$(SERF_MAJOR).$(SERF_MINO
TARFILE_NAME=$(PRJNAME)-$(LIBSERFVERSION)
TARFILE_MD5=3b179ed18f65c43141528aa6d2440db4
+# Apply patches that provide callbacks for ssl certificate verification with the
+# whole certificate chain (issue68.patch). The patch is taken from serf's
+# issue 68 (http://code.google.com/p/serf/issues/detail?id=68).
+# This patch needs some minor fixes (issue68b.patch) for proper initialization of
+# some callbacks and export of new functions.
+PATCH_FILES=$(TARFILE_NAME).issue68.patch $(TARFILE_NAME).issue68b.patch
+
# disable default used Transfer-Encoding = chunked for sending requests.
-PATCH_FILES=$(TARFILE_NAME).nochunkedtransferencoding.patch
+PATCH_FILES+=$(TARFILE_NAME).nochunkedtransferencoding.patch
.IF "$(OS)"=="WNT"
Added: incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68.patch
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68.patch?rev=1295493&view=auto
==============================================================================
--- incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68.patch (added)
+++ incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68.patch Thu Mar 1 10:14:02 2012
@@ -0,0 +1,164 @@
+--- misc/serf-1.0.0/buckets/ssl_buckets.c 2011-07-13 04:39:16.000000000 +0200
++++ misc/build/serf-1.0.0/buckets/ssl_buckets.c 2012-02-24 14:26:51.766979700 +0100
+@@ -173,6 +173,9 @@
+ serf_ssl_need_server_cert_t server_cert_callback;
+ void *server_cert_userdata;
+
++ serf_ssl_need_server_cert_chain_t server_cert_chain_callback;
++ void *server_cert_chain_userdata;
++
+ const char *cert_path;
+
+ X509 *cached_cert;
+@@ -385,6 +388,25 @@
+ #endif
+ };
+
++/* Returns a NULL terminated list of Base64 encoded DER certificates. */
++static const char **export_certificates(STACK_OF(X509) *chain,
++ apr_pool_t *pool)
++{
++ const char **certificates;
++ int i, depth;
++
++ depth = sk_X509_num(chain);
++ certificates = apr_pcalloc(pool, sizeof(*certificates) * (depth + 1));
++
++ for (i = 0; i < depth; ++i) {
++ serf_ssl_certificate_t cert;
++ cert.ssl_cert = sk_X509_value(chain, i);
++ *(certificates+i) = serf_ssl_cert_export(&cert, pool);
++ }
++
++ return certificates;
++}
++
+ static int
+ validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx)
+ {
+@@ -457,6 +479,39 @@
+ apr_pool_destroy(subpool);
+ }
+
++ /* This provides the entire chain so we only call it when the end
++ * entity certificate is reached. */
++ if (ctx->server_cert_chain_callback && depth == 0) {
++ apr_status_t status;
++ STACK_OF(X509) *chain;
++ const char **ascii_certs;
++ apr_pool_t *subpool;
++
++ apr_pool_create(&subpool, ctx->pool);
++
++ chain = X509_STORE_CTX_get1_chain(store_ctx);
++ /* Fallback to the current certificate if the chain cannot be
++ * retrieved. */
++ if ( ! chain) {
++ chain = sk_X509_new_null();
++ sk_X509_push(chain, X509_dup(server_cert));
++ }
++ ascii_certs = export_certificates(chain, subpool);
++
++ /* Callback for further verification. */
++ status =
++ ctx->server_cert_chain_callback(ctx->server_cert_chain_userdata,
++ failures, ascii_certs);
++ if (status == APR_SUCCESS)
++ cert_valid = 1;
++ else
++ /* Pass the error back to the caller through the context-run. */
++ ctx->pending_err = status;
++
++ sk_X509_pop_free(chain, X509_free);
++ apr_pool_destroy(subpool);
++ }
++
+ return cert_valid;
+ }
+
+@@ -1009,6 +1064,16 @@
+ context->server_cert_userdata = data;
+ }
+
++
++void serf_ssl_server_cert_chain_callback_set(
++ serf_ssl_context_t *context,
++ serf_ssl_need_server_cert_chain_t callback,
++ void *data)
++{
++ context->server_cert_chain_callback = callback;
++ context->server_cert_chain_userdata = data;
++}
++
+ static serf_ssl_context_t *ssl_init_context(void)
+ {
+ serf_ssl_context_t *ssl_ctx;
+--- misc/serf-1.0.0/serf_bucket_types.h 2011-06-25 18:01:01.000000000 +0200
++++ misc/build/serf-1.0.0/serf_bucket_types.h 2012-02-24 14:26:51.790981100 +0100
+@@ -486,6 +486,11 @@
+ int failures,
+ const serf_ssl_certificate_t *cert);
+
++typedef apr_status_t (*serf_ssl_need_server_cert_chain_t)(
++ void *data,
++ int failures,
++ const char **certs);
++
+ void serf_ssl_client_cert_provider_set(
+ serf_ssl_context_t *context,
+ serf_ssl_need_client_cert_t callback,
+@@ -508,6 +513,16 @@
+ void *data);
+
+ /**
++ * Set a callback to override the default SSL server certificate validation
++ * algorithm. This callback is provided with the certificate chain of the
++ * server.
++ */
++void serf_ssl_server_cert_chain_callback_set(
++ serf_ssl_context_t *context,
++ serf_ssl_need_server_cert_chain_t callback,
++ void *data);
++
++/**
+ * Use the default root CA certificates as included with the OpenSSL library.
+ */
+ apr_status_t serf_ssl_use_default_certificates(
+@@ -630,4 +645,4 @@
+ }
+ #endif
+
+-#endif /* !SERF_BUCKET_TYPES_H */
++#endif /* !SERF_BUCKET_TYPES_H */
+--- misc/serf-1.0.0/test/serf_get.c 2011-06-25 18:01:01.000000000 +0200
++++ misc/build/serf-1.0.0/test/serf_get.c 2012-02-24 14:29:02.520458400 +0100
+@@ -49,6 +49,21 @@
+ return APR_SUCCESS;
+ }
+
++static apr_status_t print_cert_chain(void *data, int failures,
++ const char **certs)
++{
++ const char *current;
++ while ((current = *certs) != NULL)
++ {
++ printf("-----BEGIN CERTIFICATE-----\n");
++ printf("%s\n", current);
++ printf("-----END CERTIFICATE-----\n");
++ ++certs;
++ }
++
++ return APR_SUCCESS;
++}
++
+ static apr_status_t conn_setup(apr_socket_t *skt,
+ serf_bucket_t **input_bkt,
+ serf_bucket_t **output_bkt,
+@@ -65,6 +80,7 @@
+ ctx->ssl_ctx = serf_bucket_ssl_decrypt_context_get(c);
+ }
+ serf_ssl_server_cert_callback_set(ctx->ssl_ctx, ignore_all_cert_errors, NULL);
++ serf_ssl_server_cert_chain_callback_set(ctx->ssl_ctx, print_cert_chain, NULL);
+ serf_ssl_set_hostname(ctx->ssl_ctx, ctx->hostinfo);
+
+ *output_bkt = serf_bucket_ssl_encrypt_create(*output_bkt, ctx->ssl_ctx,
Added: incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68b.patch
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68b.patch?rev=1295493&view=auto
==============================================================================
--- incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68b.patch (added)
+++ incubator/ooo/trunk/ext_libraries/serf/serf-1.0.0.issue68b.patch Thu Mar 1 10:14:02 2012
@@ -0,0 +1,108 @@
+--- misc/serf-1.0.0/buckets/ssl_buckets.c 2012-02-29 11:04:40.203782000 +0100
++++ misc/build/serf-1.0.0/buckets/ssl_buckets.c 2012-02-29 10:55:33.127491000 +0100
+@@ -481,37 +481,45 @@
+
+ /* This provides the entire chain so we only call it when the end
+ * entity certificate is reached. */
+- if (ctx->server_cert_chain_callback && depth == 0) {
+- apr_status_t status;
+- STACK_OF(X509) *chain;
+- const char **ascii_certs;
+- apr_pool_t *subpool;
++ if (ctx->server_cert_chain_callback != NULL)
++ {
++ if (depth == 0)
++ {
++ apr_status_t status;
++ STACK_OF(X509) *chain;
++ const char **ascii_certs;
++ apr_pool_t *subpool;
+
+- apr_pool_create(&subpool, ctx->pool);
++ apr_pool_create(&subpool, ctx->pool);
+
+- chain = X509_STORE_CTX_get1_chain(store_ctx);
+- /* Fallback to the current certificate if the chain cannot be
+- * retrieved. */
+- if ( ! chain) {
+- chain = sk_X509_new_null();
+- sk_X509_push(chain, X509_dup(server_cert));
+- }
+- ascii_certs = export_certificates(chain, subpool);
+-
+- /* Callback for further verification. */
+- status =
+- ctx->server_cert_chain_callback(ctx->server_cert_chain_userdata,
+- failures, ascii_certs);
+- if (status == APR_SUCCESS)
+- cert_valid = 1;
+- else
+- /* Pass the error back to the caller through the context-run. */
+- ctx->pending_err = status;
++ chain = X509_STORE_CTX_get1_chain(store_ctx);
++ /* Fallback to the current certificate if the chain cannot be
++ * retrieved. */
++ if ( ! chain) {
++ chain = sk_X509_new_null();
++ sk_X509_push(chain, X509_dup(server_cert));
++ }
++ ascii_certs = export_certificates(chain, subpool);
++
++ /* Callback for further verification. */
++ status =
++ ctx->server_cert_chain_callback(ctx->server_cert_chain_userdata,
++ failures, ascii_certs, sk_X509_num(chain));
++ if (status == APR_SUCCESS)
++ cert_valid = 1;
++ else
++ /* Pass the error back to the caller through the context-run. */
++ ctx->pending_err = status;
+
+- sk_X509_pop_free(chain, X509_free);
+- apr_pool_destroy(subpool);
++ sk_X509_pop_free(chain, X509_free);
++ apr_pool_destroy(subpool);
++ }
++ else
++ {
++ // Keep the process going until depth==0 is reached.
++ cert_valid = 1;
++ }
+ }
+-
+ return cert_valid;
+ }
+
+@@ -1091,6 +1099,10 @@
+ ssl_ctx->pool = pool;
+ ssl_ctx->allocator = allocator;
+
++ ssl_ctx->cert_callback = NULL;
++ ssl_ctx->server_cert_callback = NULL;
++ ssl_ctx->server_cert_chain_callback = NULL;
++
+ ssl_ctx->ctx = SSL_CTX_new(SSLv23_client_method());
+
+ SSL_CTX_set_client_cert_cb(ssl_ctx->ctx, ssl_need_client_cert);
+--- misc/serf-1.0.0/build/serf.def 2011-07-15 23:47:01.000000000 +0200
++++ misc/build/serf-1.0.0/build/serf.def 2012-02-27 14:24:23.526967200 +0100
+@@ -83,6 +83,7 @@
+ serf_ssl_client_cert_provider_set
+ serf_ssl_client_cert_password_set
+ serf_ssl_server_cert_callback_set
++serf_ssl_server_cert_chain_callback_set
+ serf_ssl_use_default_certificates
+ serf_ssl_set_hostname
+ serf_ssl_cert_depth
+--- misc/serf-1.0.0/serf_bucket_types.h 2012-02-29 11:04:40.226783300 +0100
++++ misc/build/serf-1.0.0/serf_bucket_types.h 2012-02-27 14:24:23.510966300 +0100
+@@ -489,7 +489,8 @@
+ typedef apr_status_t (*serf_ssl_need_server_cert_chain_t)(
+ void *data,
+ int failures,
+- const char **certs);
++ const char **certs,
++ int nCertificateChainLength);
+
+ void serf_ssl_client_cert_provider_set(
+ serf_ssl_context_t *context,
Modified: incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.cxx?rev=1295493&r1=1295492&r2=1295493&view=diff
==============================================================================
--- incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.cxx (original)
+++ incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.cxx Thu Mar 1 10:14:02 2012
@@ -61,13 +61,14 @@ extern "C" apr_status_t Serf_Credentials
pool );
}
-extern "C" apr_status_t Serf_CertificationValidation( void *data,
- int failures,
- const serf_ssl_certificate_t *cert )
+extern "C" apr_status_t Serf_CertificateChainValidation(
+ void* pSerfSession,
+ int nFailures,
+ const char** pCertificateChainBase64Encoded,
+ int nCertificateChainLength)
{
- SerfSession* pSerfSession = static_cast< SerfSession* >( data );
- return pSerfSession->verifySerfCertificate( failures,
- cert );
+ return static_cast<SerfSession*>(pSerfSession)
+ ->verifySerfCertificateChain(nFailures, pCertificateChainBase64Encoded, nCertificateChainLength);
}
extern "C" apr_status_t Serf_SetupRequest( serf_request_t *request,
Modified: incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.hxx?rev=1295493&r1=1295492&r2=1295493&view=diff
==============================================================================
--- incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.hxx (original)
+++ incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfCallbacks.hxx Thu Mar 1 10:14:02 2012
@@ -37,12 +37,14 @@ extern "C" apr_status_t Serf_Credentials
void *baton,
int code,
const char *authn_type,
- const char *realm,
- apr_pool_t *pool );
+ const char *realm,
+ apr_pool_t *pool );
-extern "C" apr_status_t Serf_CertificationValidation( void *data,
- int failures,
- const serf_ssl_certificate_t *cert );
+extern "C" apr_status_t Serf_CertificateChainValidation(
+ void* pSerfSession,
+ int nFailures,
+ const char** pCertificateChainBase64Encoded,
+ int nCertificateChainLength);
extern "C" apr_status_t Serf_SetupRequest( serf_request_t *request,
void *setup_baton,
Modified: incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.cxx?rev=1295493&r1=1295492&r2=1295493&view=diff
==============================================================================
--- incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.cxx (original)
+++ incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.cxx Thu Mar 1 10:14:02 2012
@@ -53,6 +53,7 @@
using namespace com::sun::star;
using namespace http_dav_ucp;
+
// -------------------------------------------------------------------
// static members!
bool SerfSession::m_bGlobalsInited = false;
@@ -269,9 +270,13 @@ apr_status_t SerfSession::setupSerfConne
tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt,
0,
getSerfBktAlloc() );
- serf_ssl_server_cert_callback_set( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
- Serf_CertificationValidation,
- this );
+ /** Set the callback that is called to authenticate the
+ certifcate (chain).
+ */
+ serf_ssl_server_cert_chain_callback_set(
+ serf_bucket_ssl_decrypt_context_get(tmpInputBkt),
+ Serf_CertificateChainValidation,
+ this);
serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ),
getHostinfo() );
@@ -365,131 +370,152 @@ namespace {
}
} // namespace
-apr_status_t SerfSession::verifySerfCertificate( int inFailures,
- const serf_ssl_certificate_t * inCert )
+
+apr_status_t SerfSession::verifySerfCertificateChain (
+ int,
+ const char** pCertificateChainBase64Encoded,
+ const int nCertificateChainLength)
{
- OSL_ASSERT( inCert );
+ // Check arguments.
+ if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0)
+ {
+ OSL_ASSERT(pCertificateChainBase64Encoded != NULL);
+ OSL_ASSERT(nCertificateChainLength>0);
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ }
+ // Create some crypto objects to decode and handle the base64
+ // encoded certificate chain.
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
uno::Reference< security::XCertificateContainer > xCertificateContainer;
+ uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext;
+ uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv;
try
{
- xCertificateContainer
- = uno::Reference< security::XCertificateContainer >(
- getMSF()->createInstance(
- rtl::OUString::createFromAscii(
- "com.sun.star.security.CertificateContainer" ) ),
- uno::UNO_QUERY );
- }
- catch ( uno::Exception const & )
- {
- }
+ // Create a certificate container.
+ xCertificateContainer = uno::Reference< security::XCertificateContainer >(
+ getMSF()->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.security.CertificateContainer" ) ),
+ uno::UNO_QUERY_THROW);
- if ( !xCertificateContainer.is() )
- return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
+ getMSF()->createInstance(
+ rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ),
+ uno::UNO_QUERY_THROW);
- inFailures = 0;
+ xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() );
+ if (xSecurityContext.is())
+ xSecurityEnv = xSecurityContext->getSecurityEnvironment();
- const char * subjectItem = static_cast<char*>(apr_hash_get( serf_ssl_cert_subject( inCert, getAprPool() ),
- "CN", APR_HASH_KEY_STRING ));
- if ( subjectItem == 0 )
- {
- subjectItem = static_cast<char*>(apr_hash_get( serf_ssl_cert_subject( inCert, getAprPool() ),
- "OU", APR_HASH_KEY_STRING ));
+ if ( ! xSecurityContext.is() || ! xSecurityEnv.is())
+ {
+ // Do we have to dispose xSEInitializer or xCertificateContainer?
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ }
}
- rtl::OUString cert_subject;
- if ( subjectItem != 0 )
+ catch ( uno::Exception const &)
{
- cert_subject = rtl::OUString( subjectItem, strlen( subjectItem ), RTL_TEXTENCODING_UTF8, 0 );
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
}
- else
+
+ // Decode the server certificate.
+ uno::Reference< security::XCertificate > xServerCertificate(
+ xSecurityEnv->createCertificateFromAscii(
+ rtl::OUString::createFromAscii(pCertificateChainBase64Encoded[0])));
+ if ( ! xServerCertificate.is())
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+
+ // Get the subject from the server certificate.
+ ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
+ sal_Int32 nIndex = 0;
+ while (nIndex >= 0)
{
- rtl::OUString::createFromAscii( "unknown subject" );
+ const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
+ if (sToken.compareToAscii("CN=", 3) == 0)
+ {
+ sServerCertificateSubject = sToken.copy(3);
+ break;
+ }
+ else if (sToken.compareToAscii(" CN=", 4) == 0)
+ {
+ sServerCertificateSubject = sToken.copy(4);
+ break;
+ }
}
- security::CertificateContainerStatus certificateContainer(
+ // When the certificate container already contains a (trusted)
+ // entry for the server then we do not have to authenticate any
+ // certificate.
+ const security::CertificateContainerStatus eStatus (
xCertificateContainer->hasCertificate(
- getHostName(), cert_subject ) );
-
- if ( certificateContainer != security::CertificateContainerStatus_NOCERT )
+ getHostName(), sServerCertificateSubject ) );
+ if (eStatus != security::CertificateContainerStatus_NOCERT)
{
- return certificateContainer == security::CertificateContainerStatus_TRUSTED
+ return eStatus == security::CertificateContainerStatus_TRUSTED
? APR_SUCCESS
: SERF_SSL_CERT_UNKNOWN_FAILURE;
}
- uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
- try
+ // The shortcut failed, so try to verify the whole chain. This is
+ // done outside the isDomainMatch() block because the result is
+ // used by the interaction handler.
+ std::vector< uno::Reference< security::XCertificate > > aChain;
+ for (int nIndex=1; nIndex<nCertificateChainLength; ++nIndex)
{
- xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >(
- getMSF()->createInstance(
- rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ),
- uno::UNO_QUERY );
- }
- catch ( uno::Exception const & )
- {
- }
-
- if ( !xSEInitializer.is() )
- return SERF_SSL_CERT_UNKNOWN_FAILURE;
-
- uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext(
- xSEInitializer->createSecurityContext( rtl::OUString() ) );
-
- uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv(
- xSecurityContext->getSecurityEnvironment() );
-
- //The end entity certificate
- const char * eeCertB64 = serf_ssl_cert_export( inCert, getAprPool() );
-
- rtl::OString sEECertB64( eeCertB64 );
-
- uno::Reference< security::XCertificate > xEECert(
- xSecurityEnv->createCertificateFromAscii(
- rtl::OStringToOUString( sEECertB64, RTL_TEXTENCODING_ASCII_US ) ) );
-
- std::vector< uno::Reference< security::XCertificate > > vecCerts;
- const serf_ssl_certificate_t * issuerCert = inCert;
- do
- {
- //get the intermediate certificate
- issuerCert = NULL; // TODO - figure out how to retrieve certificate chain - ssl_cert_signedby( issuerCert );
- if ( NULL == issuerCert )
- break;
-
- const char * imCertB64 = serf_ssl_cert_export( issuerCert, getAprPool() );
- rtl::OString sInterMediateCertB64( imCertB64 );
-
- uno::Reference< security::XCertificate> xImCert(
+ uno::Reference< security::XCertificate > xCertificate(
xSecurityEnv->createCertificateFromAscii(
- rtl::OStringToOUString(
- sInterMediateCertB64, RTL_TEXTENCODING_ASCII_US ) ) );
- if ( xImCert.is() )
- vecCerts.push_back( xImCert );
+ rtl::OUString::createFromAscii(pCertificateChainBase64Encoded[nIndex])));
+ if ( ! xCertificate.is())
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ aChain.push_back(xCertificate);
}
- while ( 1 );
-
- sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xEECert,
- ::comphelper::containerToSequence( vecCerts ) );
+ const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate(
+ xServerCertificate,
+ ::comphelper::containerToSequence(aChain)));
- if ( isDomainMatch( GetHostnamePart( xEECert.get()->getSubjectName() ) ) )
+ // When the certificate matches the host name then we can use the
+ // result of the verification.
+ if (isDomainMatch(sServerCertificateSubject))
{
- // if host name matched with certificate then look if the
- // certificate was ok
- if( certValidity == security::CertificateValidity::VALID )
+
+ if (nVerificationResult == 0)
+ {
+ // Certificate (chain) is valid.
+ xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True);
return APR_SUCCESS;
+ }
+ else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
+ {
+ // We do not have enough information for verification,
+ // neither automatically (as we just discovered) nor
+ // manually (so there is no point in showing any dialog.)
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ }
+ else if ((nVerificationResult &
+ (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0)
+ {
+ // Certificate (chain) is invalid.
+ xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False);
+ return SERF_SSL_CERT_UNKNOWN_FAILURE;
+ }
+ else
+ {
+ // For all other we have to ask the user.
+ }
}
+ // We have not been able to automatically verify (or falsify) the
+ // certificate chain. To resolve this we have to ask the user.
const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
if ( xEnv.is() )
{
- inFailures = static_cast< int >( certValidity );
-
uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
if ( xIH.is() )
{
rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
xRequest( new ucbhelper::SimpleCertificateValidationRequest(
- (sal_Int32)inFailures, xEECert, getHostName() ) );
+ static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
xIH->handle( xRequest.get() );
rtl::Reference< ucbhelper::InteractionContinuation > xSelection
@@ -501,13 +527,13 @@ apr_status_t SerfSession::verifySerfCert
xSelection.get(), uno::UNO_QUERY );
if ( xApprove.is() )
{
- xCertificateContainer->addCertificate( getHostName(), cert_subject, sal_True );
+ xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True );
return APR_SUCCESS;
}
else
{
// Don't trust cert
- xCertificateContainer->addCertificate( getHostName(), cert_subject, sal_False );
+ xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
return SERF_SSL_CERT_UNKNOWN_FAILURE;
}
}
@@ -515,10 +541,11 @@ apr_status_t SerfSession::verifySerfCert
else
{
// Don't trust cert
- xCertificateContainer->addCertificate( getHostName(), cert_subject, sal_False );
+ xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
return SERF_SSL_CERT_UNKNOWN_FAILURE;
}
}
+
return SERF_SSL_CERT_UNKNOWN_FAILURE;
}
Modified: incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.hxx?rev=1295493&r1=1295492&r2=1295493&view=diff
==============================================================================
--- incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.hxx (original)
+++ incubator/ooo/trunk/main/ucb/source/ucp/webdav/SerfSession.hxx Thu Mar 1 10:14:02 2012
@@ -91,11 +91,13 @@ public:
serf_request_t * inRequest,
int inCode,
const char *inAuthProtocol,
- const char *inRealm,
+ const char *inRealm,
apr_pool_t *inAprPool );
- apr_status_t verifySerfCertificate( int inFailures,
- const serf_ssl_certificate_t * inCert );
+ apr_status_t verifySerfCertificateChain (
+ int nFailures,
+ const char** pCertificateChainBase64Encoded,
+ int nCertificateChainLength);
serf_bucket_t* acceptSerfResponse( serf_request_t * inSerfRequest,
serf_bucket_t * inSerfStreamBucket,