diff options
Diffstat (limited to 'xmlsecurity/source')
-rw-r--r-- | xmlsecurity/source/dialogs/certificateviewer.cxx | 21 | ||||
-rw-r--r-- | xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx | 12 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/diagnose.cxx | 77 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/diagnose.hxx | 43 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/makefile.mk | 7 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/mscrypt/makefile.mk | 4 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx | 258 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx | 34 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/certerrors.h | 384 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/makefile.mk | 8 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/secerror.cxx | 165 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/secerror.hxx | 40 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx | 289 | ||||
-rw-r--r-- | xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx | 116 |
14 files changed, 1105 insertions, 353 deletions
diff --git a/xmlsecurity/source/dialogs/certificateviewer.cxx b/xmlsecurity/source/dialogs/certificateviewer.cxx index fca5d8192..887c0b42a 100644 --- a/xmlsecurity/source/dialogs/certificateviewer.cxx +++ b/xmlsecurity/source/dialogs/certificateviewer.cxx @@ -125,16 +125,8 @@ CertificateViewerGeneralTP::CertificateViewerGeneralTP( Window* _pParent, Certif //Verify the certificate sal_Int32 certStatus = mpDlg->mxSecurityEnvironment->verifyCertificate(mpDlg->mxCert, Sequence<Reference<css::security::XCertificate> >()); - //We currently have two status - //These errors are alloweds - sal_Int32 validCertErrors = css::security::CertificateValidity::VALID - | css::security::CertificateValidity::UNKNOWN_REVOKATION; - //Build a mask to filter out the allowed errors - sal_Int32 mask = ~validCertErrors; - // "subtract" the allowed error flags from the result - sal_Int32 certErrors = certStatus & mask; - bool bCertValid = certErrors > 0 ? false : true; + bool bCertValid = certStatus == css::security::CertificateValidity::VALID ? true : false; bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); if ( !bCertValid ) @@ -485,16 +477,7 @@ void CertificateViewerCertPathTP::ActivatePage() //Verify the certificate sal_Int32 certStatus = mpDlg->mxSecurityEnvironment->verifyCertificate(rCert, Sequence<Reference<css::security::XCertificate> >()); - //We currently have two status - //These errors are alloweds - sal_Int32 validCertErrors = css::security::CertificateValidity::VALID - | css::security::CertificateValidity::UNKNOWN_REVOKATION; - - //Build a mask to filter out the allowed errors - sal_Int32 mask = ~validCertErrors; - // "subtract" the allowed error flags from the result - sal_Int32 certErrors = certStatus & mask; - bool bCertValid = certErrors > 0 ? false : true; + bool bCertValid = certStatus == css::security::CertificateValidity::VALID ? true : false; pParent = InsertCert( pParent, sName, rCert, bCertValid); } diff --git a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx index 5eea33636..1f6a3c170 100644 --- a/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx +++ b/xmlsecurity/source/dialogs/digitalsignaturesdialog.cxx @@ -639,16 +639,8 @@ void DigitalSignaturesDialog::ImplFillSignaturesBox() try { sal_Int32 certResult = xSecEnv->verifyCertificate(xCert, Sequence<css::uno::Reference<css::security::XCertificate> >()); - - //These errors are alloweds - sal_Int32 validErrors = css::security::CertificateValidity::VALID - | css::security::CertificateValidity::UNKNOWN_REVOKATION; - - //Build a mask to filter out the allowed errors - sal_Int32 mask = ~validErrors; - // "subtract" the allowed error flags from the result - sal_Int32 errors = certResult & mask; - bCertValid = errors > 0 ? false : true; + + bCertValid = certResult == css::security::CertificateValidity::VALID ? true : false; if ( bCertValid ) nValidCerts++; diff --git a/xmlsecurity/source/xmlsec/diagnose.cxx b/xmlsecurity/source/xmlsec/diagnose.cxx new file mode 100644 index 000000000..eb8be87c8 --- /dev/null +++ b/xmlsecurity/source/xmlsec/diagnose.cxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmlstreamio.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "diagnose.hxx" +#include <stdio.h> +#include <stdarg.h> +#include "rtl/instance.hxx" +#include "rtl/bootstrap.hxx" + +namespace xmlsecurity { + +struct UseDiagnose : public rtl::StaticWithInit< + const bool, UseDiagnose> +{ + const bool operator () () + { + ::rtl::OUString value; + sal_Bool res = rtl::Bootstrap::get( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("XMLSECURITY_TRACE")), value); + return res == sal_True ? true : false; + } +}; + +/* the function will print the string when + - build with debug + - the bootstrap variable XMLSECURITY_TRACE is set. + */ +void xmlsec_trace(const char* pszFormat, ...) +{ + bool bDebug = false; + +#if OSL_DEBUG_LEVEL > 1 + bDebug = true; +#endif + if (bDebug || UseDiagnose::get()) + { + va_list args; + fprintf(stderr, "[xmlsecurity] "); + va_start(args, pszFormat); + vfprintf(stderr, pszFormat, args); + va_end(args); + + fprintf(stderr,"\n"); + fflush(stderr); + } +} + + + +} diff --git a/xmlsecurity/source/xmlsec/diagnose.hxx b/xmlsecurity/source/xmlsec/diagnose.hxx new file mode 100644 index 000000000..347f80d24 --- /dev/null +++ b/xmlsecurity/source/xmlsec/diagnose.hxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: xmlstreamio.hxx,v $ + * $Revision: 1.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef XMLSECURITY_DIAGNOSE_HXX +#define XMLSECURITY_DIAGNOSE_HXX + + +namespace xmlsecurity +{ + + void xmlsec_trace(const char* pszFormat, ...); +} + + + +#endif //XMLSECURITY_DIAGNOSE_HXX diff --git a/xmlsecurity/source/xmlsec/makefile.mk b/xmlsecurity/source/xmlsec/makefile.mk index 1127419e1..44b668b84 100644 --- a/xmlsecurity/source/xmlsec/makefile.mk +++ b/xmlsecurity/source/xmlsec/makefile.mk @@ -41,10 +41,12 @@ ENABLE_EXCEPTIONS = TRUE CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS) .ENDIF -.IF "$(WITH_MOZILLA)" == "NO" +.IF "$(WITH_MOZILLA)" == "NO" || "$(ENABLE_NSS_MODULE)"!="YES" +.IF "$(SYSTEM_MOZILLA)" != "YES" @all: @echo "No mozilla -> no nss -> no libxmlsec -> no xmlsecurity.." .ENDIF +.ENDIF .IF "$(CRYPTO_ENGINE)" == "mscrypto" CDEFS += -DXMLSEC_CRYPTO_MSCRYPTO -DXMLSEC_NO_XSLT @@ -62,7 +64,8 @@ SLOFILES = \ $(SLO)$/certificateextension_xmlsecimpl.obj \ $(SLO)$/xmlstreamio.obj \ $(SLO)$/errorcallback.obj \ - $(SLO)$/xsec_xmlsec.obj + $(SLO)$/xsec_xmlsec.obj \ + $(SLO)$/diagnose.obj # --- Targets ------------------------------------------------------ diff --git a/xmlsecurity/source/xmlsec/mscrypt/makefile.mk b/xmlsecurity/source/xmlsec/mscrypt/makefile.mk index fd02aa776..20153edf1 100644 --- a/xmlsecurity/source/xmlsec/mscrypt/makefile.mk +++ b/xmlsecurity/source/xmlsec/mscrypt/makefile.mk @@ -43,10 +43,12 @@ LIBTARGET=NO .IF "$(CRYPTO_ENGINE)" == "mscrypto" -.IF "$(WITH_MOZILLA)" == "NO" +.IF "$(WITH_MOZILLA)" == "NO" || "$(ENABLE_NSS_MODULE)"!="YES" +.IF "$(SYSTEM_MOZILLA)" != "YES" @all: @echo "No mozilla -> no nss -> no libxmlsec -> no xmlsecurity/nss" .ENDIF +.ENDIF CDEFS += -DXMLSEC_CRYPTO_MSCRYPTO -DXMLSEC_NO_XSLT diff --git a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx index 5d2c9be2c..eb9162e8b 100644 --- a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx +++ b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx @@ -37,6 +37,7 @@ #pragma warning(pop) #endif #include <sal/config.h> +#include <osl/thread.h> #include "securityenvironment_mscryptimpl.hxx" #ifndef _X509CERTIFICATE_NSSIMPL_HXX_ @@ -60,7 +61,11 @@ #include <osl/process.h> //CP : end +#include <rtl/memory.h> +#include "../diagnose.hxx" + +using namespace xmlsecurity; using namespace ::com::sun::star::uno ; using namespace ::com::sun::star::lang ; using ::com::sun::star::lang::XMultiServiceFactory ; @@ -69,9 +74,58 @@ using ::rtl::OUString ; using ::com::sun::star::xml::crypto::XSecurityEnvironment ; using ::com::sun::star::security::XCertificate ; +namespace css = ::com::sun::star; extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ; +struct CertErrorToString{ + DWORD error; + char * name; +}; + +CertErrorToString arErrStrings[] = +{ + { 0x00000000, "CERT_TRUST_NO_ERROR"}, + { 0x00000001, "CERT_TRUST_IS_NOT_TIME_VALID"}, + { 0x00000002, "CERT_TRUST_IS_NOT_TIME_NESTED"}, + { 0x00000004, "CERT_TRUST_IS_REVOKED" }, + { 0x00000008, "CERT_TRUST_IS_NOT_SIGNATURE_VALID" }, + { 0x00000010, "CERT_TRUST_IS_NOT_SIGNATURE_VALID"}, + { 0x00000020, "CERT_TRUST_IS_UNTRUSTED_ROOT"}, + { 0x00000040, "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"}, + { 0x00000080, "CERT_TRUST_IS_CYCLIC"}, + { 0x00000100, "CERT_TRUST_INVALID_EXTENSION"}, + { 0x00000200, "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"}, + { 0x00000400, "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"}, + { 0x00000800, "CERT_TRUST_INVALID_NAME_CONSTRAINTS"}, + { 0x00001000, "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"}, + { 0x00002000, "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"}, + { 0x00004000, "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"}, + { 0x00008000, "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"}, + { 0x01000000, "CERT_TRUST_IS_OFFLINE_REVOCATION"}, + { 0x02000000, "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"}, + { 0x04000000, "CERT_TRUST_IS_EXPLICIT_DISTRUST"}, + { 0x08000000, "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"}, + //Chain errors + { 0x00010000, "CERT_TRUST_IS_PARTIAL_CHAIN"}, + { 0x00020000, "CERT_TRUST_CTL_IS_NOT_TIME_VALID"}, + { 0x00040000, "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"}, + { 0x00080000, "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"} +}; + +void traceTrustStatus(DWORD err) +{ + int numErrors = sizeof(arErrStrings) / sizeof(CertErrorToString); + xmlsec_trace("The certificate error status is: "); + if (err == 0) + xmlsec_trace("%s", arErrStrings[0].name); + for (int i = 1; i < numErrors; i++) + { + if (arErrStrings[i].error & err) + xmlsec_trace("%s", arErrStrings[i].name); + } +} + SecurityEnvironment_MSCryptImpl :: SecurityEnvironment_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_hProv( NULL ) , m_pszContainer( NULL ) , m_hKeyStore( NULL ), m_hCertStore( NULL ), m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList(), m_xServiceManager( aFactory ), m_bEnableDefault( sal_False ) { } @@ -891,6 +945,11 @@ HCERTSTORE getCertStoreForIntermediatCerts( for (int i = 0; i < seqCerts.getLength(); i++) { + xmlsec_trace("Added temporary certificate: \n%s", + OUStringToOString(seqCerts[i]->getSubjectName(), + osl_getThreadTextEncoding()).getStr()); + + Sequence<sal_Int8> data = seqCerts[i]->getEncoded(); PCCERT_CONTEXT cert = CertCreateCertificateContext( X509_ASN_ENCODING, ( const BYTE* )&data[0], data.getLength()); @@ -901,6 +960,11 @@ HCERTSTORE getCertStoreForIntermediatCerts( } return store; } + +//We return only valid or invalid, as long as the API documentation expresses +//explicitly that all validation steps are carried out even if one or several +//errors occur. See also +//http://wiki.services.openoffice.org/wiki/Certificate_Path_Validation#Validation_status sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate( const Reference< ::com::sun::star::security::XCertificate >& aCert, const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts) @@ -910,24 +974,28 @@ sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate( PCCERT_CHAIN_CONTEXT pChainContext = NULL; PCCERT_CONTEXT pCertContext = NULL; const X509Certificate_MSCryptImpl* xcert = NULL; - DWORD chainStatus ; - - CERT_ENHKEY_USAGE enhKeyUsage ; - CERT_USAGE_MATCH certUsage ; - CERT_CHAIN_PARA chainPara ; - + Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; if( !xCertTunnel.is() ) { throw RuntimeException() ; } + xmlsec_trace("Start verification of certificate: \n %s", + OUStringToOString( + aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr()); + xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; if( xcert == NULL ) { throw RuntimeException() ; } - + pCertContext = xcert->getMswcryCert() ; + CERT_ENHKEY_USAGE enhKeyUsage ; + CERT_USAGE_MATCH certUsage ; + CERT_CHAIN_PARA chainPara ; + rtl_zeroMemory(&chainPara, sizeof(CERT_CHAIN_PARA)); + //Prepare parameter for CertGetCertificateChain enhKeyUsage.cUsageIdentifier = 0 ; enhKeyUsage.rgpszUsageIdentifier = NULL ; @@ -973,132 +1041,94 @@ sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate( 0); } - + //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST + //We do not check revocation of the root. In most cases there are none. + //Then we would get CERT_TRUST_REVOCATION_STATUS_UNKNOWN + xmlsec_trace("Verifying cert using revocation information."); bChain = CertGetCertificateChain( NULL , pCertContext , NULL , //use current system time hCollectionStore, &chainPara , - CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME , + CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, NULL , &pChainContext); - if (!bChain) - pChainContext = NULL; - - } - - if(bChain && pChainContext != NULL ) - { - chainStatus = pChainContext->TrustStatus.dwErrorStatus ; - - // JL & TKR: Until we have a test suite to test all error types we just say that the cert is - // valid or invalid with no further separation. - // Error CERT_TRUST_IS_OFFLINE_REVOCATION and CERT_TRUST_REVOCATION_STATUS_UNKNOWN are treated separate - // because they are ignored ( Bad! ) in the currently situation - - if( chainStatus == CERT_TRUST_NO_ERROR ) + if (bChain && pChainContext->cChain > 0) { - validity = ::com::sun::star::security::CertificateValidity::VALID ; - } - - if ( ( chainStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ) == CERT_TRUST_IS_OFFLINE_REVOCATION ) { - validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ; - } - - if ( ( chainStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) == CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) { - validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ; - } - - if (chainStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE - || chainStatus & CERT_TRUST_IS_CYCLIC - || chainStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS - || chainStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS - || chainStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS - || chainStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY - || chainStatus & CERT_TRUST_CTL_IS_NOT_TIME_VALID - || chainStatus & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID - || chainStatus & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE - || chainStatus & CERT_TRUST_IS_NOT_TIME_VALID - || chainStatus & CERT_TRUST_IS_NOT_TIME_NESTED - || chainStatus & CERT_TRUST_IS_REVOKED - || chainStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID - || chainStatus & CERT_TRUST_IS_UNTRUSTED_ROOT - || chainStatus & CERT_TRUST_INVALID_EXTENSION - || chainStatus & CERT_TRUST_IS_PARTIAL_CHAIN ) - { - validity = ::com::sun::star::security::CertificateValidity::INVALID; - } -/* - - if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_VALID ) == CERT_TRUST_IS_NOT_TIME_VALID ) { - validity |= ::com::sun::star::security::CertificateValidity::TIME_INVALID ; - } - - if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_NESTED ) == CERT_TRUST_IS_NOT_TIME_NESTED ) { - validity |= ::com::sun::star::security::CertificateValidity::NOT_TIME_NESTED; - } - - if( ( chainStatus & CERT_TRUST_IS_REVOKED ) == CERT_TRUST_IS_REVOKED ) { - validity |= ::com::sun::star::security::CertificateValidity::REVOKED ; - } - - //JL My interpretation is that CERT_TRUST_IS_OFFLINE_REVOCATION does not mean that the certificate was revoked. - //Instead the CRL cannot be retrieved from the net, or an available CRL is stale (too old). - //This error may also occurs if the certificate does not contain the CDP (Certificate Distribution Point)extension - if( ( chainStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ) == CERT_TRUST_IS_OFFLINE_REVOCATION ) { - validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ; - } - - if( ( chainStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID ) == CERT_TRUST_IS_NOT_SIGNATURE_VALID ) { - validity |= ::com::sun::star::security::CertificateValidity::SIGNATURE_INVALID ; - } - - if( ( chainStatus & CERT_TRUST_IS_UNTRUSTED_ROOT ) == CERT_TRUST_IS_UNTRUSTED_ROOT ) { - validity |= ::com::sun::star::security::CertificateValidity::ROOT_UNTRUSTED ; - } + xmlsec_trace("Overall error status (all chains):"); + traceTrustStatus(pChainContext->TrustStatus.dwErrorStatus); + //highest quality chains come first + PCERT_SIMPLE_CHAIN pSimpleChain = pChainContext->rgpChain[0]; + xmlsec_trace("Error status of first chain: "); + traceTrustStatus(pSimpleChain->TrustStatus.dwErrorStatus); + + //CERT_TRUST_REVOCATION_STATUS_UNKNOWN is also set if a certificate + //has no AIA(OCSP) or CRLDP extension and there is no CRL locally installed. + DWORD revocationFlags = CERT_TRUST_REVOCATION_STATUS_UNKNOWN | + CERT_TRUST_IS_OFFLINE_REVOCATION; + DWORD otherErrorsMask = ~revocationFlags; + if( !(pSimpleChain->TrustStatus.dwErrorStatus & otherErrorsMask)) - if( ( chainStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) == CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) { - validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ; - } - - if( ( chainStatus & CERT_TRUST_INVALID_EXTENSION ) == CERT_TRUST_INVALID_EXTENSION ) { - validity |= ::com::sun::star::security::CertificateValidity::EXTENSION_INVALID ; - } - - if( ( chainStatus & CERT_TRUST_IS_PARTIAL_CHAIN ) == CERT_TRUST_IS_PARTIAL_CHAIN ) { - validity |= ::com::sun::star::security::CertificateValidity::CHAIN_INCOMPLETE ; + { + //No errors except maybe those caused by missing revocation information + //Check if there are errors + if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags) + { + //No revocation information. Because MSDN documentation is not + //clear about if all other tests are performed if an error occurrs, + //we test again, without requiring revocation checking. + CertFreeCertificateChain(pChainContext); + pChainContext = NULL; + xmlsec_trace("Checking again but without requiring revocation information."); + bChain = CertGetCertificateChain( + NULL , + pCertContext , + NULL , //use current system time + hCollectionStore, + &chainPara , + 0, + NULL , + &pChainContext); + if (bChain + && pChainContext->cChain > 0 + && pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) + { + xmlsec_trace("Certificate is valid.\n"); + validity = ::com::sun::star::security::CertificateValidity::VALID; + } + else + { + xmlsec_trace("Certificate is invalid.\n"); + } + } + else + { + //valid and revocation information available + xmlsec_trace("Certificate is valid.\n"); + validity = ::com::sun::star::security::CertificateValidity::VALID; + } + } + else + { + //invalid + xmlsec_trace("Certificate is invalid.\n"); + validity = ::com::sun::star::security::CertificateValidity::INVALID ; + } } - //todo - if (chainStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE - || chainStatus & CERT_TRUST_IS_CYCLIC - || chainStatus & CERT_TRUST_INVALID_POLICY_CONSTRAINTS - || chainStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS - || chainStatus & CERT_TRUST_INVALID_NAME_CONSTRAINTS - || chainStatus & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT - || chainStatus & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY - || chainStatus & CERT_TRUST_CTL_IS_NOT_TIME_VALID - || chainStatus & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID - || chainStatus & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE) + else { - validity = ::com::sun::star::security::CertificateValidity::INVALID; + xmlsec_trace("CertGetCertificateChaine failed.\n"); } -*/ - } else { - validity = ::com::sun::star::security::CertificateValidity::INVALID ; } if (pChainContext) + { CertFreeCertificateChain(pChainContext); + pChainContext = NULL; + } //Close the additional store, do not destroy the contained certs CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx index 74f5e4fa9..bc628e2b8 100644 --- a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx +++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx @@ -260,24 +260,27 @@ sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::su } } -::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) { - if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { - char* subject ; +::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) + { + wchar_t* subject ; DWORD cbSubject ; - cbSubject = CertNameToStr( + cbSubject = CertNameToStrW( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , &( m_pCertContext->pCertInfo->Subject ), CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , NULL, 0 ) ; - if( cbSubject != 0 ) { - subject = new char[ cbSubject ] ; + if( cbSubject != 0 ) + { + subject = new wchar_t[ cbSubject ] ; if( subject == NULL ) throw RuntimeException() ; - cbSubject = CertNameToStr( + cbSubject = CertNameToStrW( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , &( m_pCertContext->pCertInfo->Subject ), CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , @@ -289,22 +292,17 @@ sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::su throw RuntimeException() ; } - // By CP , for correct encoding - sal_uInt16 encoding ; - rtl_Locale *pLocale = NULL ; - osl_getProcessLocale( &pLocale ) ; - encoding = osl_getTextEncodingFromLocale( pLocale ) ; - // CP end - - if(subject[cbSubject-1] == 0) cbSubject--; //delimit the last 0x00; - OUString xSubject(subject , cbSubject ,encoding ) ; //By CP + OUString xSubject(subject); delete [] subject ; return replaceTagSWithTagST(xSubject); - } else { + } else + { return OUString() ; } - } else { + } + else + { return OUString() ; } } diff --git a/xmlsecurity/source/xmlsec/nss/certerrors.h b/xmlsecurity/source/xmlsec/nss/certerrors.h new file mode 100644 index 000000000..2b68e2d13 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/certerrors.h @@ -0,0 +1,384 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: securityenvironment_nssimpl.cxx,v $ + * $Revision: 1.23 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +{SEC_ERROR_IO, "An I/O error occurred during security authorization."}, + +{SEC_ERROR_LIBRARY_FAILURE, "security library failure."}, + +{SEC_ERROR_BAD_DATA, "security library: received bad data."}, + +{SEC_ERROR_OUTPUT_LEN, "security library: output length error."}, + +{SEC_ERROR_INPUT_LEN, "security library has experienced an input length error."}, + +{SEC_ERROR_INVALID_ARGS, "security library: invalid arguments."}, + +{SEC_ERROR_INVALID_ALGORITHM, "security library: invalid algorithm."}, + +{SEC_ERROR_INVALID_AVA, "security library: invalid AVA."}, + +{SEC_ERROR_INVALID_TIME, "Improperly formatted time string."}, + +{SEC_ERROR_BAD_DER, "security library: improperly formatted DER-encoded message."}, + +{SEC_ERROR_BAD_SIGNATURE, "Peer's certificate has an invalid signature."}, + +{SEC_ERROR_EXPIRED_CERTIFICATE, "Peer's Certificate has expired."}, + +{SEC_ERROR_REVOKED_CERTIFICATE, "Peer's Certificate has been revoked."}, + +{SEC_ERROR_UNKNOWN_ISSUER, "Peer's Certificate issuer is not recognized."}, + +{SEC_ERROR_BAD_KEY, "Peer's public key is invalid."}, + +{SEC_ERROR_BAD_PASSWORD, "The security password entered is incorrect."}, + +{SEC_ERROR_RETRY_PASSWORD, "New password entered incorrectly. Please try again."}, + +{SEC_ERROR_NO_NODELOCK, "security library: no nodelock."}, + +{SEC_ERROR_BAD_DATABASE, "security library: bad database."}, + +{SEC_ERROR_NO_MEMORY, "security library: memory allocation failure."}, + +{SEC_ERROR_UNTRUSTED_ISSUER, "Peer's certificate issuer has been marked as not trusted by the user."}, + +{SEC_ERROR_UNTRUSTED_CERT, "Peer's certificate has been marked as not trusted by the user."}, + +{SEC_ERROR_DUPLICATE_CERT, "Certificate already exists in your database."}, + +{SEC_ERROR_DUPLICATE_CERT_NAME, "Downloaded certificate's name duplicates one already in your database."}, + +{SEC_ERROR_ADDING_CERT, "Error adding certificate to database."}, + +{SEC_ERROR_FILING_KEY, "Error refiling the key for this certificate."}, + +{SEC_ERROR_NO_KEY, "The private key for this certificate cannot be found in key database"}, + +{SEC_ERROR_CERT_VALID, "This certificate is valid."}, + +{SEC_ERROR_CERT_NOT_VALID, "This certificate is not valid."}, + +{SEC_ERROR_CERT_NO_RESPONSE, "Cert Library: No Response"}, + +{SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, "The certificate issuer's certificate has expired. Check your system date and time."}, + +{SEC_ERROR_CRL_EXPIRED, "The CRL for the certificate's issuer has expired. Update it or check your system date and time."}, + +{SEC_ERROR_CRL_BAD_SIGNATURE, "The CRL for the certificate's issuer has an invalid signature."}, + +{SEC_ERROR_CRL_INVALID, "New CRL has an invalid format."}, + +{SEC_ERROR_EXTENSION_VALUE_INVALID, "Certificate extension value is invalid."}, + +{SEC_ERROR_EXTENSION_NOT_FOUND, "Certificate extension not found."}, + +{SEC_ERROR_CA_CERT_INVALID, "Issuer certificate is invalid."}, + +{SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, "Certificate path length constraint is invalid."}, + +{SEC_ERROR_CERT_USAGES_INVALID, "Certificate usages field is invalid."}, + +{SEC_INTERNAL_ONLY, "**Internal ONLY module**"}, + +{SEC_ERROR_INVALID_KEY, "The key does not support the requested operation."}, + +{SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, "Certificate contains unknown critical extension."}, + +{SEC_ERROR_OLD_CRL, "New CRL is not later than the current one."}, + +{SEC_ERROR_NO_EMAIL_CERT, "Not encrypted or signed: you do not yet have an email certificate."}, + +{SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, "Not encrypted: you do not have certificates for each of the recipients."}, + +{SEC_ERROR_NOT_A_RECIPIENT, "Cannot decrypt: you are not a recipient, or matching certificate and \ +private key not found."}, + +{SEC_ERROR_PKCS7_KEYALG_MISMATCH, "Cannot decrypt: key encryption algorithm does not match your certificate."}, + +{SEC_ERROR_PKCS7_BAD_SIGNATURE, "Signature verification failed: no signer found, too many signers found, \ +or improper or corrupted data."}, + +{SEC_ERROR_UNSUPPORTED_KEYALG, "Unsupported or unknown key algorithm."}, + +{SEC_ERROR_DECRYPTION_DISALLOWED, "Cannot decrypt: encrypted using a disallowed algorithm or key size."}, + + +/* Fortezza Alerts */ +{XP_SEC_FORTEZZA_BAD_CARD, "Fortezza card has not been properly initialized. \ +Please remove it and return it to your issuer."}, + +{XP_SEC_FORTEZZA_NO_CARD, "No Fortezza cards Found"}, + +{XP_SEC_FORTEZZA_NONE_SELECTED, "No Fortezza card selected"}, + +{XP_SEC_FORTEZZA_MORE_INFO, "Please select a personality to get more info on"}, + +{XP_SEC_FORTEZZA_PERSON_NOT_FOUND, "Personality not found"}, + +{XP_SEC_FORTEZZA_NO_MORE_INFO, "No more information on that Personality"}, + +{XP_SEC_FORTEZZA_BAD_PIN, "Invalid Pin"}, + +{XP_SEC_FORTEZZA_PERSON_ERROR, "Couldn't initialize Fortezza personalities."}, +/* end fortezza alerts. */ + +{SEC_ERROR_NO_KRL, "No KRL for this site's certificate has been found."}, + +{SEC_ERROR_KRL_EXPIRED, "The KRL for this site's certificate has expired."}, + +{SEC_ERROR_KRL_BAD_SIGNATURE, "The KRL for this site's certificate has an invalid signature."}, + +{SEC_ERROR_REVOKED_KEY, "The key for this site's certificate has been revoked."}, + +{SEC_ERROR_KRL_INVALID, "New KRL has an invalid format."}, + +{SEC_ERROR_NEED_RANDOM, "security library: need random data."}, + +{SEC_ERROR_NO_MODULE, "security library: no security module can perform the requested operation."}, + +{SEC_ERROR_NO_TOKEN, "The security card or token does not exist, needs to be initialized, or has been removed."}, + +{SEC_ERROR_READ_ONLY, "security library: read-only database."}, + +{SEC_ERROR_NO_SLOT_SELECTED, "No slot or token was selected."}, + +{SEC_ERROR_CERT_NICKNAME_COLLISION, "A certificate with the same nickname already exists."}, + +{SEC_ERROR_KEY_NICKNAME_COLLISION, "A key with the same nickname already exists."}, + +{SEC_ERROR_SAFE_NOT_CREATED, "error while creating safe object"}, + +{SEC_ERROR_BAGGAGE_NOT_CREATED, "error while creating baggage object"}, + +{XP_JAVA_REMOVE_PRINCIPAL_ERROR, "Couldn't remove the principal"}, + +{XP_JAVA_DELETE_PRIVILEGE_ERROR, "Couldn't delete the privilege"}, + +{XP_JAVA_CERT_NOT_EXISTS_ERROR, "This principal doesn't have a certificate"}, + +{SEC_ERROR_BAD_EXPORT_ALGORITHM, "Required algorithm is not allowed."}, + +{SEC_ERROR_EXPORTING_CERTIFICATES, "Error attempting to export certificates."}, + +{SEC_ERROR_IMPORTING_CERTIFICATES, "Error attempting to import certificates."}, + +{SEC_ERROR_PKCS12_DECODING_PFX, "Unable to import. Decoding error. File not valid."}, + +{SEC_ERROR_PKCS12_INVALID_MAC, "Unable to import. Invalid MAC. Incorrect password or corrupt file."}, + +{SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, "Unable to import. MAC algorithm not supported."}, + +{SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE, "Unable to import. Only password integrity and privacy modes supported."}, + +{SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, "Unable to import. File structure is corrupt."}, + +{SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, "Unable to import. Encryption algorithm not supported."}, + +{SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, "Unable to import. File version not supported."}, + +{SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT, "Unable to import. Incorrect privacy password."}, + +{SEC_ERROR_PKCS12_CERT_COLLISION, "Unable to import. Same nickname already exists in database."}, + +{SEC_ERROR_USER_CANCELLED, "The user pressed cancel."}, + +{SEC_ERROR_PKCS12_DUPLICATE_DATA, "Not imported, already in database."}, + +{SEC_ERROR_MESSAGE_SEND_ABORTED, "Message not sent."}, + +{SEC_ERROR_INADEQUATE_KEY_USAGE, "Certificate key usage inadequate for attempted operation."}, + +{SEC_ERROR_INADEQUATE_CERT_TYPE, "Certificate type not approved for application."}, + +{SEC_ERROR_CERT_ADDR_MISMATCH, "Address in signing certificate does not match address in message headers."}, + +{SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, "Unable to import. Error attempting to import private key."}, + +{SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, "Unable to import. Error attempting to import certificate chain."}, + +{SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, "Unable to export. Unable to locate certificate or key by nickname."}, + +{SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, "Unable to export. Private Key could not be located and exported."}, + +{SEC_ERROR_PKCS12_UNABLE_TO_WRITE, "Unable to export. Unable to write the export file."}, + +{SEC_ERROR_PKCS12_UNABLE_TO_READ, "Unable to import. Unable to read the import file."}, + +{SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, "Unable to export. Key database corrupt or deleted."}, + +{SEC_ERROR_KEYGEN_FAIL, "Unable to generate public/private key pair."}, + +{SEC_ERROR_INVALID_PASSWORD, "Password entered is invalid. Please pick a different one."}, + +{SEC_ERROR_RETRY_OLD_PASSWORD, "Old password entered incorrectly. Please try again."}, + +{SEC_ERROR_BAD_NICKNAME, "Certificate nickname already in use."}, + +{SEC_ERROR_NOT_FORTEZZA_ISSUER, "Peer FORTEZZA chain has a non-FORTEZZA Certificate."}, + +{SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, "A sensitive key cannot be moved to the slot where it is needed."}, + +{SEC_ERROR_JS_INVALID_MODULE_NAME, "Invalid module name."}, + +{SEC_ERROR_JS_INVALID_DLL, "Invalid module path/filename"}, + +{SEC_ERROR_JS_ADD_MOD_FAILURE, "Unable to add module"}, + +{SEC_ERROR_JS_DEL_MOD_FAILURE, "Unable to delete module"}, + +{SEC_ERROR_OLD_KRL, "New KRL is not later than the current one."}, + +{SEC_ERROR_CKL_CONFLICT, "New CKL has different issuer than current CKL. Delete current CKL."}, + +{SEC_ERROR_CERT_NOT_IN_NAME_SPACE, "The Certifying Authority for this certificate is not permitted to issue a \ +certificate with this name."}, + +{SEC_ERROR_KRL_NOT_YET_VALID, "The key revocation list for this certificate is not yet valid."}, + +{SEC_ERROR_CRL_NOT_YET_VALID, "The certificate revocation list for this certificate is not yet valid."}, + +{SEC_ERROR_UNKNOWN_CERT, "The requested certificate could not be found."}, + +{SEC_ERROR_UNKNOWN_SIGNER, "The signer's certificate could not be found."}, + +{SEC_ERROR_CERT_BAD_ACCESS_LOCATION, "The location for the certificate status server has invalid format."}, + +{SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, "The OCSP response cannot be fully decoded; it is of an unknown type."}, + +{SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, "The OCSP server returned unexpected/invalid HTTP data."}, + +{SEC_ERROR_OCSP_MALFORMED_REQUEST, "The OCSP server found the request to be corrupted or improperly formed."}, + +{SEC_ERROR_OCSP_SERVER_ERROR, "The OCSP server experienced an internal error."}, + +{SEC_ERROR_OCSP_TRY_SERVER_LATER, "The OCSP server suggests trying again later."}, + +{SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, "The OCSP server requires a signature on this request."}, + +{SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, "The OCSP server has refused this request as unauthorized."}, + +{SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, "The OCSP server returned an unrecognizable status."}, + +{SEC_ERROR_OCSP_UNKNOWN_CERT, "The OCSP server has no status for the certificate."}, + +{SEC_ERROR_OCSP_NOT_ENABLED, "You must enable OCSP before performing this operation."}, + +{SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, "You must set the OCSP default responder before performing this operation."}, + +{SEC_ERROR_OCSP_MALFORMED_RESPONSE, "The response from the OCSP server was corrupted or improperly formed."}, + +{SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, "The signer of the OCSP response is not authorized to give status for \ +this certificate."}, + +{SEC_ERROR_OCSP_FUTURE_RESPONSE, "The OCSP response is not yet valid (contains a date in the future},."}, + +{SEC_ERROR_OCSP_OLD_RESPONSE, "The OCSP response contains out-of-date information."}, + +{SEC_ERROR_DIGEST_NOT_FOUND, "The CMS or PKCS #7 Digest was not found in signed message."}, + +{SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, "The CMS or PKCS #7 Message type is unsupported."}, + +{SEC_ERROR_MODULE_STUCK, "PKCS #11 module could not be removed because it is still in use."}, + +{SEC_ERROR_BAD_TEMPLATE, "Could not decode ASN.1 data. Specified template was invalid."}, + +{SEC_ERROR_CRL_NOT_FOUND, "No matching CRL was found."}, + +{SEC_ERROR_REUSED_ISSUER_AND_SERIAL, "You are attempting to import a cert with the same issuer/serial as \ +an existing cert, but that is not the same cert."}, + +{SEC_ERROR_BUSY, "NSS could not shutdown. Objects are still in use."}, + +{SEC_ERROR_EXTRA_INPUT, "DER-encoded message contained extra unused data."}, + +{SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, "Unsupported elliptic curve."}, + +{SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, "Unsupported elliptic curve point form."}, + +{SEC_ERROR_UNRECOGNIZED_OID, "Unrecognized Object Identifier."}, + +{SEC_ERROR_OCSP_INVALID_SIGNING_CERT, "Invalid OCSP signing certificate in OCSP response."}, + +{SEC_ERROR_REVOKED_CERTIFICATE_CRL, "Certificate is revoked in issuer's certificate revocation list."}, + +{SEC_ERROR_REVOKED_CERTIFICATE_OCSP, "Issuer's OCSP responder reports certificate is revoked."}, + +{SEC_ERROR_CRL_INVALID_VERSION, "Issuer's Certificate Revocation List has an unknown version number."}, + +{SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, "Issuer's V1 Certificate Revocation List has a critical extension."}, + +{SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, "Issuer's V2 Certificate Revocation List has an unknown critical extension."}, + +{SEC_ERROR_UNKNOWN_OBJECT_TYPE, "Unknown object type specified."}, + +{SEC_ERROR_INCOMPATIBLE_PKCS11, "PKCS #11 driver violates the spec in an incompatible way."}, + +{SEC_ERROR_NO_EVENT, "No new slot event is available at this time."}, + +{SEC_ERROR_CRL_ALREADY_EXISTS, "CRL already exists."}, + +{SEC_ERROR_NOT_INITIALIZED, "NSS is not initialized."}, + +{SEC_ERROR_TOKEN_NOT_LOGGED_IN, "The operation failed because the PKCS#11 token is not logged in."}, + +{SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, "Configured OCSP responder's certificate is invalid."}, + +{SEC_ERROR_OCSP_BAD_SIGNATURE, "OCSP response has an invalid signature."}, + +{SEC_ERROR_OUT_OF_SEARCH_LIMITS, "Cert validation search is out of search limits"}, + +{SEC_ERROR_INVALID_POLICY_MAPPING, "Policy mapping contains anypolicy"}, + +{SEC_ERROR_POLICY_VALIDATION_FAILED, "Cert chain fails policy validation"}, + +{SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, "Unknown location type in cert AIA extension"}, + +{SEC_ERROR_BAD_HTTP_RESPONSE, "Server returned bad HTTP response"}, + +{SEC_ERROR_BAD_LDAP_RESPONSE, "Server returned bad LDAP response"}, + +{SEC_ERROR_FAILED_TO_ENCODE_DATA, "Failed to encode data with ASN1 encoder"}, + +{SEC_ERROR_BAD_INFO_ACCESS_LOCATION, "Bad information access location in cert extension"}, + +{SEC_ERROR_LIBPKIX_INTERNAL, "Libpkix internal error occured during cert validation."}, + +{SEC_ERROR_PKCS11_GENERAL_ERROR, "A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred."}, + +{SEC_ERROR_PKCS11_FUNCTION_FAILED, "A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed."}, + +{SEC_ERROR_PKCS11_DEVICE_ERROR, "A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot."}, + +{SEC_ERROR_BAD_INFO_ACCESS_METHOD, "Unknown information access method in certificate extension."}, + +{SEC_ERROR_CRL_IMPORT_FAILED, "Error attempting to import a CRL."}, + diff --git a/xmlsecurity/source/xmlsec/nss/makefile.mk b/xmlsecurity/source/xmlsec/nss/makefile.mk index df5bb7131..227b6de88 100644 --- a/xmlsecurity/source/xmlsec/nss/makefile.mk +++ b/xmlsecurity/source/xmlsec/nss/makefile.mk @@ -47,10 +47,12 @@ LIBTARGET=NO .IF "$(CRYPTO_ENGINE)" == "nss" -.IF "$(WITH_MOZILLA)" == "NO" +.IF "$(WITH_MOZILLA)" == "NO" || "$(ENABLE_NSS_MODULE)"!="YES" +.IF "$(SYSTEM_MOZILLA)" != "YES" @all: @echo "No mozilla -> no nss -> no libxmlsec -> no xmlsecurity/nss" .ENDIF +.ENDIF .IF "$(SYSTEM_MOZILLA)" != "YES" MOZ_INC = $(SOLARVERSION)$/$(INPATH)$/inc$(UPDMINOREXT)$/mozilla @@ -128,7 +130,9 @@ SLOFILES = \ $(SLO)$/xmlsignature_nssimpl.obj \ $(SLO)$/x509certificate_nssimpl.obj \ $(SLO)$/seinitializer_nssimpl.obj \ - $(SLO)$/xsec_nss.obj + $(SLO)$/xsec_nss.obj \ + $(SLO)$/secerror.obj + .ENDIF diff --git a/xmlsecurity/source/xmlsec/nss/secerror.cxx b/xmlsecurity/source/xmlsec/nss/secerror.cxx new file mode 100644 index 000000000..4c440fa2e --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/secerror.cxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: securityenvironment_nssimpl.cxx,v $ + * $Revision: 1.23 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#include "secerr.h" +#include "sslerr.h" +#include "nspr.h" +#include "certt.h" + +#include "../diagnose.hxx" + +using namespace xmlsecurity; + +struct ErrDesc { + PRErrorCode errNum; + const char * errString; +}; + + + +const ErrDesc allDesc[] = { + +#include "certerrors.h" + +}; + + + +/* Returns a UTF-8 encoded constant error string for "errNum". + * Returns NULL of errNum is unknown. + */ +const char * +getCertError(PRErrorCode errNum) +{ + static char sEmpty[] = ""; + const int numDesc = sizeof(allDesc) / sizeof(ErrDesc); + for (int i = 0; i < numDesc; i++) + { + if (allDesc[i].errNum == errNum) + return allDesc[i].errString; + } + + return sEmpty; +} + +void +printChainFailure(CERTVerifyLog *log) +{ + unsigned long errorFlags = 0; + unsigned int depth = (unsigned int)-1; + const char * specificError = NULL; + const char * issuer = NULL; + CERTVerifyLogNode *node = NULL; + + if (log->count > 0) + { + xmlsec_trace("Bad certifcation path:"); + for (node = log->head; node; node = node->next) + { + if (depth != node->depth) + { + depth = node->depth; + xmlsec_trace("Certificate: %d. %s %s:", depth, + node->cert->subjectName, + depth ? "[Certificate Authority]": ""); + } + xmlsec_trace(" ERROR %ld: %s", node->error, + getCertError(node->error)); + specificError = NULL; + issuer = NULL; + switch (node->error) + { + case SEC_ERROR_INADEQUATE_KEY_USAGE: + errorFlags = (unsigned long)node->arg; + switch (errorFlags) + { + case KU_DIGITAL_SIGNATURE: + specificError = "Certificate cannot sign."; + break; + case KU_KEY_ENCIPHERMENT: + specificError = "Certificate cannot encrypt."; + break; + case KU_KEY_CERT_SIGN: + specificError = "Certificate cannot sign other certs."; + break; + default: + specificError = "[unknown usage]."; + break; + } + case SEC_ERROR_INADEQUATE_CERT_TYPE: + errorFlags = (unsigned long)node->arg; + switch (errorFlags) + { + case NS_CERT_TYPE_SSL_CLIENT: + case NS_CERT_TYPE_SSL_SERVER: + specificError = "Certificate cannot be used for SSL."; + break; + case NS_CERT_TYPE_SSL_CA: + specificError = "Certificate cannot be used as an SSL CA."; + break; + case NS_CERT_TYPE_EMAIL: + specificError = "Certificate cannot be used for SMIME."; + break; + case NS_CERT_TYPE_EMAIL_CA: + specificError = "Certificate cannot be used as an SMIME CA."; + break; + case NS_CERT_TYPE_OBJECT_SIGNING: + specificError = "Certificate cannot be used for object signing."; + break; + case NS_CERT_TYPE_OBJECT_SIGNING_CA: + specificError = "Certificate cannot be used as an object signing CA."; + break; + default: + specificError = "[unknown usage]."; + break; + } + case SEC_ERROR_UNKNOWN_ISSUER: + specificError = "Unknown issuer:"; + issuer = node->cert->issuerName; + break; + case SEC_ERROR_UNTRUSTED_ISSUER: + specificError = "Untrusted issuer:"; + issuer = node->cert->issuerName; + break; + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + specificError = "Expired issuer certificate:"; + issuer = node->cert->issuerName; + break; + default: + break; + } + if (specificError) + xmlsec_trace("%s", specificError); + if (issuer) + xmlsec_trace("%s", issuer); + } + } +} diff --git a/xmlsecurity/source/xmlsec/nss/secerror.hxx b/xmlsecurity/source/xmlsec/nss/secerror.hxx new file mode 100644 index 000000000..b2f0ff645 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/secerror.hxx @@ -0,0 +1,40 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: securityenvironment_nssimpl.hxx,v $ + * $Revision: 1.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _XSECERROR_HXX_ +#define _XSECERROR_HXX_ + +const char * +getCertError(PRErrorCode errNum); + +void +printChainFailure(CERTVerifyLog *log); +#endif // _XSECERROR_HXX_ + diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx index b4d3a78b1..89c05360f 100644 --- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx +++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx @@ -33,12 +33,13 @@ #include "nssrenam.h" #include "cert.h" #include "secerr.h" +#include "ocsp.h" #include <sal/config.h> #include "securityenvironment_nssimpl.hxx" #include "x509certificate_nssimpl.hxx" #include <rtl/uuid.h> - +#include "../diagnose.hxx" #include <sal/types.h> //For reasons that escape me, this is what xmlsec does when size_t is not 4 @@ -62,9 +63,12 @@ #include <vector> #include "boost/scoped_array.hpp" +#include "secerror.hxx" + // MM : added for password exception #include <com/sun/star/security/NoPasswordException.hpp> namespace csss = ::com::sun::star::security; +using namespace xmlsecurity; using namespace ::com::sun::star::security; using namespace com::sun::star; using namespace ::com::sun::star::uno ; @@ -80,6 +84,14 @@ extern X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert ) ; extern X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* ) ; +struct UsageDescription +{ + SECCertificateUsage usage; + char const * const description; +}; + + + char* GetPasswordFunction( PK11SlotInfo* pSlot, PRBool bRetry, void* /*arg*/ ) { uno::Reference< lang::XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() ); @@ -750,7 +762,7 @@ verifyCertificate( const Reference< csss::XCertificate >& aCert, const Sequence< Reference< csss::XCertificate > >& intermediateCerts ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) { - sal_Int32 validity = 0; + sal_Int32 validity = csss::CertificateValidity::INVALID; const X509Certificate_NssImpl* xcert ; const CERTCertificate* cert ; ::std::vector<CERTCertificate*> vecTmpNSSCertificates; @@ -759,23 +771,26 @@ verifyCertificate( const Reference< csss::XCertificate >& aCert, throw RuntimeException() ; } - OSL_TRACE("[xmlsecurity] Start verification of certificate: %s", + xmlsec_trace("Start verification of certificate: \n %s \n", OUStringToOString( - aCert->getIssuerName(), osl_getThreadTextEncoding()).getStr()); - - + aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr()); + xcert = reinterpret_cast<X509Certificate_NssImpl*>( sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ; if( xcert == NULL ) { throw RuntimeException() ; } + //CERT_PKIXVerifyCert does not take a db as argument. It will therefore + //internally use CERT_GetDefaultCertDB + //Make sure m_pHandler is the default DB + OSL_ASSERT(m_pHandler == CERT_GetDefaultCertDB()); + CERTCertDBHandle * certDb = m_pHandler != NULL ? m_pHandler : CERT_GetDefaultCertDB(); cert = xcert->getNssCert() ; if( cert != NULL ) { //prepare the intermediate certificates - CERTCertDBHandle * certDb = m_pHandler != NULL ? m_pHandler : CERT_GetDefaultCertDB(); for (sal_Int32 i = 0; i < intermediateCerts.getLength(); i++) { Sequence<sal_Int8> der = intermediateCerts[i]->getEncoded(); @@ -790,140 +805,172 @@ verifyCertificate( const Reference< csss::XCertificate >& aCert, PR_TRUE /* copyDER */); if (!certTmp) { - OSL_TRACE("[xmlsecurity] Failed to add a temporary certificate: %s", + xmlsec_trace("Failed to add a temporary certificate: %s", OUStringToOString(intermediateCerts[i]->getIssuerName(), osl_getThreadTextEncoding()).getStr()); } else { - OSL_TRACE("[xmlsecurity] Added temporary certificate: %s", + xmlsec_trace("Added temporary certificate: %s", certTmp->subjectName ? certTmp->subjectName : ""); vecTmpNSSCertificates.push_back(certTmp); } } + - - int64 timeboundary ; SECStatus status ; + + CERTVerifyLog log; + log.arena = PORT_NewArena(512); + log.head = log.tail = NULL; + log.count = 0; - //Get the system clock time - timeboundary = PR_Now() ; - SECCertificateUsage usage = 0; - - // create log - - CERTVerifyLog realLog; - CERTVerifyLog *log; - - log = &realLog; - - - log->count = 0; - log->head = NULL; - log->tail = NULL; - log->arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); + CERT_EnableOCSPChecking(certDb); + CERT_DisableOCSPDefaultResponder(certDb); + CERTValOutParam cvout[5]; + CERTValInParam cvin[3]; + + cvin[0].type = cert_pi_useAIACertFetch; + cvin[0].value.scalar.b = PR_TRUE; + + PRUint64 revFlagsLeaf[2]; + PRUint64 revFlagsChain[2]; + CERTRevocationFlags rev; + rev.leafTests.number_of_defined_methods = 2; + rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf; + //the flags are defined in cert.h + //We check both leaf and chain. + //It is enough if one revocation method has fresh info, + //but at least one must have some. Otherwise validation fails. + //!!! using leaf test and CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE + // when validating a root certificate will result in "revoked". Usually + //there is no revocation information available for the root cert because + //it must be trusted anyway and it does itself issue revocation information. + //When we use the flag here and OOo shows the certification path then the root + //cert is invalid while all other can be valid. It would probably best if + //this interface method returned the whole chain. + //Otherwise we need to check if the certificate is self-signed and if it is + //then not use the flag when doing the leaf-test. + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + CERT_REV_M_TEST_USING_THIS_METHOD + | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE; + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + CERT_REV_M_TEST_USING_THIS_METHOD + | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE; + rev.leafTests.number_of_preferred_methods = 0; + rev.leafTests.preferred_methods = NULL; + rev.leafTests.cert_rev_method_independent_flags = + CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; +// | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE; + + rev.chainTests.number_of_defined_methods = 2; + rev.chainTests.cert_rev_flags_per_method = revFlagsChain; + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + CERT_REV_M_TEST_USING_THIS_METHOD + | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE; + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + CERT_REV_M_TEST_USING_THIS_METHOD + | CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE; + rev.chainTests.number_of_preferred_methods = 0; + rev.chainTests.preferred_methods = NULL; + rev.chainTests.cert_rev_method_independent_flags = + CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; +// | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE; + - //CERTVerifyLog *log; - //PRArenaPool *arena; - - //arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - //log = PORT_ArenaZNew( arena, CERTVerifyLog ); - //log->arena = arena; - validity = csss::CertificateValidity::INVALID; + cvin[1].type = cert_pi_revocationFlags; + cvin[1].value.pointer.revocation = &rev; + // does not work, not implemented yet in 3.12.4 +// cvin[2].type = cert_pi_keyusage; +// cvin[2].value.scalar.ui = KU_DIGITAL_SIGNATURE; + cvin[2].type = cert_pi_end; + + cvout[0].type = cert_po_trustAnchor; + cvout[0].value.pointer.cert = NULL; + cvout[1].type = cert_po_errorLog; + cvout[1].value.pointer.log = &log; + cvout[2].type = cert_po_end; - if( m_pHandler != NULL ) + // We check SSL server certificates, CA certificates and signing sertificates. + // + // ToDo check keyusage, looking at CERT_KeyUsageAndTypeForCertUsage ( + // mozilla/security/nss/lib/certdb/certdb.c indicates that + // certificateUsageSSLClient, certificateUsageSSLServer and certificateUsageSSLCA + // are sufficient. They cover the key usages for digital signature, key agreement + // and encipherment and certificate signature + + //never use the following usages because they are not checked properly + // certificateUsageUserCertImport + // certificateUsageVerifyCA + // certificateUsageAnyCA + // certificateUsageProtectedObjectSigner + + UsageDescription arUsages[] = { - //JL: We must not pass a particular usage in the requiredUsages argument (the 4th) because, - //then ONLY these are verified. For example, we pass - //certificateUsageSSLClient | certificateUsageSSLServer. Then checking a certificate which - // is a valid certificateUsageEmailSigner but no certificateUsageSSLClient | certificateUsageSSLServer - //will result in CertificateValidity::INVALID. - //Only if the argument "requiredUsages" has a value (other than zero) - //then the function will return SECFailure in case - //the certificate is not suitable for the provided usage. That is, in the previous - //example the function returns SECFailure. - status = CERT_VerifyCertificate( - m_pHandler, ( CERTCertificate* )cert, PR_TRUE, - (SECCertificateUsage)0, timeboundary , NULL, log, &usage); - } - else + {certificateUsageSSLClient, "certificateUsageSSLClient" }, + {certificateUsageSSLServer, "certificateUsageSSLServer" }, + {certificateUsageSSLCA, "certificateUsageSSLCA" }, + {certificateUsageEmailSigner, "certificateUsageEmailSigner"}, //only usable for end certs + {certificateUsageEmailRecipient, "certificateUsageEmailRecipient"} + }; + + int numUsages = sizeof(arUsages) / sizeof(UsageDescription); + for (int i = 0; i < numUsages; i++) { - status = CERT_VerifyCertificate( - CERT_GetDefaultCertDB(), ( CERTCertificate* )cert, - PR_TRUE, (SECCertificateUsage)0, timeboundary ,NULL, log, &usage); - } - - if( status == SECSuccess ) - { - // JL & TKR : certificateUsageUserCertImport, - // certificateUsageVerifyCA and certificateUsageAnyCA dont check the chain + xmlsec_trace("Testing usage %d of %d: %s (0x%x)", i + 1, + numUsages, arUsages[i].description, (int) arUsages[i].usage); - //When an intermediate or root certificate is checked then we expect the usage - //certificateUsageSSLCA. This, however, will be only set when in the trust settings dialog - //the button "This certificate can identify websites" is checked. If for example only - //"This certificate can identify mail users" is set then the end certificate can - //be validated and the returned usage will conain certificateUsageEmailRecipient. - //But checking directly the root or intermediate certificate will fail. In the - //certificate path view the end certificate will be shown as valid but the others - //will be displayed as invalid. - - if (usage & certificateUsageEmailSigner - || usage & certificateUsageEmailRecipient - || usage & certificateUsageSSLCA - || usage & certificateUsageSSLServer - || usage & certificateUsageSSLClient - // || usage & certificateUsageUserCertImport - // || usage & certificateUsageVerifyCA - || usage & certificateUsageStatusResponder ) - // || usage & certificateUsageAnyCA ) + status = CERT_PKIXVerifyCert(const_cast<CERTCertificate *>(cert), arUsages[i].usage, + cvin, cvout, NULL); + if( status == SECSuccess ) + { + xmlsec_trace("CERT_PKIXVerifyCert returned SECSuccess."); + //When an intermediate or root certificate is checked then we expect the usage + //certificateUsageSSLCA. This, however, will be only set when in the trust settings dialog + //the button "This certificate can identify websites" is checked. If for example only + //"This certificate can identify mail users" is set then the end certificate can + //be validated and the returned usage will conain certificateUsageEmailRecipient. + //But checking directly the root or intermediate certificate will fail. In the + //certificate path view the end certificate will be shown as valid but the others + //will be displayed as invalid. + validity = csss::CertificateValidity::VALID; + xmlsec_trace("Certificate is valid.\n"); + CERTCertificate * issuerCert = cvout[0].value.pointer.cert; + if (issuerCert) + { + xmlsec_trace("Root certificate: %s", issuerCert->subjectName); + CERT_DestroyCertificate(issuerCert); + }; + + break; + } else - validity = csss::CertificateValidity::INVALID; - + { + PRIntn err = PR_GetError(); + xmlsec_trace("Error: , %d = %s", err, getCertError(err)); + + /* Display validation results */ + if ( log.count > 0) + { + CERTVerifyLogNode *node = NULL; + printChainFailure(&log); + + for (node = log.head; node; node = node->next) { + if (node->cert) + CERT_DestroyCertificate(node->cert); + } + log.head = log.tail = NULL; + log.count = 0; + } + xmlsec_trace("Certificate is invalid.\n"); + } } - // always check what kind of error occured, even SECStatus says Success - //JL: When we call CERT_VerifyCertificate whit the parameter requiredUsages == 0 then all - //possible usages are checked. Then there are certainly usages for which the certificate - //is not intended. For these usages there will be NO flag set in the argument returnedUsages - // (the last arg) and there will be error codes set in the log. Therefore we cannot - //set the CertificateValidity to INVALID because there is a log entry. -// CERTVerifyLogNode *logNode = 0; - -// logNode = log->head; -// while ( logNode != NULL ) -// { -// sal_Int32 errorCode = 0; -// errorCode = logNode->error; -// switch ( errorCode ) -// { -// // JL & TKR: Any error are treated as invalid because we cannot say that we get all occurred errors from NSS -// /* -// case ( SEC_ERROR_REVOKED_CERTIFICATE ): -// validity |= csss::CertificateValidity::REVOKED; -// break; -// case ( SEC_ERROR_EXPIRED_CERTIFICATE ): -// validity |= csss::CertificateValidity::TIME_INVALID; -// break; -// case ( SEC_ERROR_CERT_USAGES_INVALID): -// validity |= csss::CertificateValidity::INVALID; -// break; -// case ( SEC_ERROR_UNTRUSTED_ISSUER ): -// case ( SEC_ERROR_UNTRUSTED_CERT ): -// validity |= csss::CertificateValidity::UNTRUSTED; -// break; -// */ -// default: -// validity |= csss::CertificateValidity::INVALID; -// break; -// } -// logNode = logNode->next; -// } } else - { - + { validity = ::com::sun::star::security::CertificateValidity::INVALID ; } @@ -931,15 +978,9 @@ verifyCertificate( const Reference< csss::XCertificate >& aCert, std::vector<CERTCertificate*>::const_iterator cert_i; for (cert_i = vecTmpNSSCertificates.begin(); cert_i != vecTmpNSSCertificates.end(); cert_i++) { - OSL_TRACE("[xmlsecurity] Destroying temporary certificate"); + xmlsec_trace("Destroying temporary certificate"); CERT_DestroyCertificate(*cert_i); } -#if OSL_DEBUG_LEVEL > 1 - if (validity == ::com::sun::star::security::CertificateValidity::VALID) - OSL_TRACE("[xmlsecurity] Certificate is valid."); - else - OSL_TRACE("[xmlsecurity] Certificate is invalid."); -#endif return validity ; } diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx index ea57e333c..4717b10ba 100644 --- a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx +++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx @@ -61,6 +61,7 @@ #include <rtl/logfile.hxx> #include "seinitializer_nssimpl.hxx" +#include "../diagnose.hxx" #include "securityenvironment_nssimpl.hxx" #include <com/sun/star/mozilla/XMozillaBootstrap.hpp> @@ -76,6 +77,7 @@ namespace cssu = com::sun::star::uno; namespace cssl = com::sun::star::lang; namespace cssxc = com::sun::star::xml::crypto; +using namespace xmlsecurity; using namespace com::sun::star; using ::rtl::OUString; using ::rtl::OString; @@ -109,7 +111,7 @@ struct InitNSSInitialize bInitialized = nsscrypto_initialize(m_sProfile.getStr(), bNSSInit); if (bNSSInit) atexit(nsscrypto_finalize ); - return & bInitialized; + return & bInitialized; } }; @@ -139,7 +141,7 @@ void deleteRootsModule() { if (PK11_HasRootCerts(slot)) { - OSL_TRACE("[xmlsecurity] The root certifificates module \"%s" + xmlsec_trace("The root certifificates module \"%s" "\" is already loaded: \n%s", module->commonName, module->dllName); @@ -157,11 +159,11 @@ void deleteRootsModule() PRInt32 modType; if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType)) { - OSL_TRACE("[xmlsecurity] Deleted module \"%s\".", RootsModule->commonName); + xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName); } else { - OSL_TRACE("[xmlsecurity] Failed to delete \"%s\" : \n%s", + xmlsec_trace("Failed to delete \"%s\" : \n%s", RootsModule->commonName, RootsModule->dllName); } SECMOD_DestroyModule(RootsModule); @@ -194,18 +196,36 @@ bool nsscrypto_initialize( const char* token, bool & out_nss_init ) { bool return_value = true; - OSL_TRACE("[xmlsecurity] Using profile: %s", token); + xmlsec_trace("Using profile: %s", token); PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ; - - if( NSS_InitReadWrite( token ) != SECSuccess ) + + //token may be an empty string + if (token != NULL && strlen(token) > 0) { - char * error = NULL; - - PR_GetErrorText(error); - if (error) - printf("%s",error); - return false ; + if( NSS_InitReadWrite( token ) != SECSuccess ) + { + xmlsec_trace("Initializing NSS with profile failed."); + char * error = NULL; + + PR_GetErrorText(error); + if (error) + xmlsec_trace("%s",error); + return false ; + } + } + else + { + xmlsec_trace("Initializing NSS without profile."); + if ( NSS_NoDB_Init(NULL) != SECSuccess ) + { + xmlsec_trace("Initializing NSS without profile failed."); + char * error = NULL; + PR_GetErrorText(error); + if (error) + xmlsec_trace("%s",error); + return false ; + } } out_nss_init = true; @@ -247,18 +267,18 @@ bool nsscrypto_initialize( const char* token, bool & out_nss_init ) SECMOD_DestroyModule(RootsModule); RootsModule = 0; if (found) - OSL_TRACE("[xmlsecurity] Added new root certificate module " + xmlsec_trace("Added new root certificate module " "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); else { - OSL_TRACE("[xmlsecurity] FAILED to load the new root certificate module " + xmlsec_trace("FAILED to load the new root certificate module " "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); return_value = false; } } else { - OSL_TRACE("[xmlsecurity] FAILED to add new root certifice module: " + xmlsec_trace("FAILED to add new root certifice module: " "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); return_value = false; @@ -266,7 +286,7 @@ bool nsscrypto_initialize( const char* token, bool & out_nss_init ) } else { - OSL_TRACE("[xmlsecurity] Adding new root certificate module failed."); + xmlsec_trace("Adding new root certificate module failed."); return_value = false; } #if SYSTEM_MOZILLA @@ -287,17 +307,17 @@ extern "C" void nsscrypto_finalize() if (SECSuccess == SECMOD_UnloadUserModule(RootsModule)) { - OSL_TRACE("[xmlsecurity] Unloaded module \""ROOT_CERTS"\"."); + xmlsec_trace("Unloaded module \""ROOT_CERTS"\"."); } else { - OSL_TRACE("[xmlsecurity] Failed unloadeding module \""ROOT_CERTS"\"."); + xmlsec_trace("Failed unloadeding module \""ROOT_CERTS"\"."); } SECMOD_DestroyModule(RootsModule); } else { - OSL_TRACE("[xmlsecurity] Unloading module \""ROOT_CERTS + xmlsec_trace("Unloading module \""ROOT_CERTS "\" failed because it was not found."); } PK11_LogoutAll(); @@ -312,23 +332,22 @@ bool getMozillaCurrentProfile( /* * first, try to get the profile from "MOZILLA_CERTIFICATE_FOLDER" */ - char * env = getenv("MOZILLA_CERTIFICATE_FOLDER"); - if (env) - { - profilePath = rtl::OUString::createFromAscii( env ); - RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", rtl::OUStringToOString( profilePath, RTL_TEXTENCODING_ASCII_US ).getStr() ); - return true; - } - else - { - RTL_LOGFILE_TRACE( "getMozillaCurrentProfile: Using MozillaBootstrap..." ); - mozilla::MozillaProductType productTypes[4] = { + char * env = getenv("MOZILLA_CERTIFICATE_FOLDER"); + if (env) + { + profilePath = rtl::OUString::createFromAscii( env ); + RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using env MOZILLA_CERTIFICATE_FOLDER: %s", rtl::OUStringToOString( profilePath, RTL_TEXTENCODING_ASCII_US ).getStr() ); + return true; + } + else + { + mozilla::MozillaProductType productTypes[4] = { mozilla::MozillaProductType_Thunderbird, mozilla::MozillaProductType_Mozilla, mozilla::MozillaProductType_Firefox, mozilla::MozillaProductType_Default }; int nProduct = 4; - + uno::Reference<uno::XInterface> xInstance = rxMSF->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.mozilla.MozillaBootstrap")) ); OSL_ENSURE( xInstance.is(), "failed to create instance" ); @@ -342,9 +361,7 @@ bool getMozillaCurrentProfile( for (int i=0; i<nProduct; i++) { ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]); - - RTL_LOGFILE_TRACE2( "getMozillaCurrentProfile: getDefaultProfile [%i] returns %s", i, rtl::OUStringToOString( profile, RTL_TEXTENCODING_ASCII_US ).getStr() ); - + if (profile != NULL && profile.getLength()>0) { profilePath = xMozillaBootstrap->getProfilePath(productTypes[i],profile); @@ -401,36 +418,9 @@ cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL } - if( !sCertDir.getLength() ) - { - RTL_LOGFILE_TRACE( "XMLSEC: Error - No certificate directory!" ); - // return NULL; - } - - - /* Initialize NSPR and NSS */ - /* Replaced with new methods by AF. ---- - //PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1 ) ; - PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ; - - if (NSS_Init(sCertDir.getStr()) != SECSuccess ) - { - PK11_LogoutAll(); - return NULL; - } - ----*/ if( ! *initNSS( sCertDir.getStr() ) ) { - RTL_LOGFILE_TRACE( "XMLSEC: Error - nsscrypto_initialize() failed." ); - if ( NSS_NoDB_Init(NULL) != SECSuccess ) - { - RTL_LOGFILE_TRACE( "XMLSEC: NSS_NoDB_Init also failed, NSS Security not available!" ); - return NULL; - } - else - { - RTL_LOGFILE_TRACE( "XMLSEC: NSS_NoDB_Init works, enough for verifying signatures..." ); - } + return NULL; } pCertHandle = CERT_GetDefaultCertDB() ; |