diff options
Diffstat (limited to 'xmlsecurity/source/xmlsec')
51 files changed, 12236 insertions, 0 deletions
diff --git a/xmlsecurity/source/xmlsec/biginteger.cxx b/xmlsecurity/source/xmlsec/biginteger.cxx new file mode 100644 index 000000000000..100708938cdb --- /dev/null +++ b/xmlsecurity/source/xmlsec/biginteger.cxx @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <xmlsecurity/biginteger.hxx> + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include <xmlsec/xmlsec.h> +#include <xmlsec/bn.h> +#include <com/sun/star/uno/Sequence.hxx> + +using namespace ::com::sun::star::uno ; +using ::rtl::OUString ; + +Sequence< sal_Int8 > numericStringToBigInteger ( OUString numeral ) +{ + if( numeral.getStr() != NULL ) + { + xmlChar* chNumeral ; + const xmlSecByte* bnInteger ; + xmlSecSize length ; + xmlSecBn bn ; + + rtl::OString onumeral = rtl::OUStringToOString( numeral , RTL_TEXTENCODING_ASCII_US ) ; + + chNumeral = xmlStrndup( ( const xmlChar* )onumeral.getStr(), ( int )onumeral.getLength() ) ; + + if( xmlSecBnInitialize( &bn, 0 ) < 0 ) { + xmlFree( chNumeral ) ; + return Sequence< sal_Int8 >(); + } + + if( xmlSecBnFromDecString( &bn, chNumeral ) < 0 ) { + xmlFree( chNumeral ) ; + xmlSecBnFinalize( &bn ) ; + return Sequence< sal_Int8 >(); + } + + xmlFree( chNumeral ) ; + + length = xmlSecBnGetSize( &bn ) ; + if( length <= 0 ) { + xmlSecBnFinalize( &bn ) ; + return Sequence< sal_Int8 >(); + } + + bnInteger = xmlSecBnGetData( &bn ) ; + if( bnInteger == NULL ) { + xmlSecBnFinalize( &bn ) ; + return Sequence< sal_Int8 >(); + } + + Sequence< sal_Int8 > integer( length ) ; + for( unsigned int i = 0 ; i < length ; i ++ ) + { + integer[i] = *( bnInteger + i ) ; + } + + xmlSecBnFinalize( &bn ) ; + return integer ; + } + + return Sequence< sal_Int8 >(); +} + +OUString bigIntegerToNumericString ( Sequence< sal_Int8 > integer ) +{ + OUString aRet ; + + if( integer.getLength() ) { + xmlSecBn bn ; + xmlChar* chNumeral ; + + if( xmlSecBnInitialize( &bn, 0 ) < 0 ) + return aRet ; + + if( xmlSecBnSetData( &bn, ( const unsigned char* )&integer[0], integer.getLength() ) < 0 ) { + xmlSecBnFinalize( &bn ) ; + return aRet ; + } + + chNumeral = xmlSecBnToDecString( &bn ) ; + if( chNumeral == NULL ) { + xmlSecBnFinalize( &bn ) ; + return aRet ; + } + + aRet = OUString::createFromAscii( ( const char* )chNumeral ) ; + + xmlSecBnFinalize( &bn ) ; + xmlFree( chNumeral ) ; + } + + return aRet ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.cxx b/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.cxx new file mode 100644 index 000000000000..c7e3c0fa61be --- /dev/null +++ b/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.cxx @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> + +#ifndef _certificateextension_nssimpl_hxx_ +#include "certificateextension_xmlsecimpl.hxx" +#endif + +using namespace ::com::sun::star::uno ; +using ::rtl::OUString ; + +using ::com::sun::star::security::XCertificateExtension ; + +CertificateExtension_XmlSecImpl :: CertificateExtension_XmlSecImpl() : + m_critical( sal_False ) , + m_xExtnId() , + m_xExtnValue() +{ +} + +CertificateExtension_XmlSecImpl :: ~CertificateExtension_XmlSecImpl() { +} + + +//Methods from XCertificateExtension +sal_Bool SAL_CALL CertificateExtension_XmlSecImpl :: isCritical() throw( ::com::sun::star::uno::RuntimeException ) { + return m_critical ; +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL CertificateExtension_XmlSecImpl :: getExtensionId() throw( ::com::sun::star::uno::RuntimeException ) { + return m_xExtnId ; +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL CertificateExtension_XmlSecImpl :: getExtensionValue() throw( ::com::sun::star::uno::RuntimeException ) { + return m_xExtnValue ; +} + +//Helper method +void CertificateExtension_XmlSecImpl :: setCertExtn( ::com::sun::star::uno::Sequence< sal_Int8 > extnId, ::com::sun::star::uno::Sequence< sal_Int8 > extnValue, sal_Bool critical ) { + m_critical = critical ; + m_xExtnId = extnId ; + m_xExtnValue = extnValue ; +} + +void CertificateExtension_XmlSecImpl :: setCertExtn( unsigned char* value, unsigned int vlen, unsigned char* id, unsigned int idlen, sal_Bool critical ) { + unsigned int i ; + if( value != NULL && vlen != 0 ) { + Sequence< sal_Int8 > extnv( vlen ) ; + for( i = 0; i < vlen ; i ++ ) + extnv[i] = *( value + i ) ; + + m_xExtnValue = extnv ; + } else { + m_xExtnValue = Sequence<sal_Int8>(); + } + + if( id != NULL && idlen != 0 ) { + Sequence< sal_Int8 > extnId( idlen ) ; + for( i = 0; i < idlen ; i ++ ) + extnId[i] = *( id + i ) ; + + m_xExtnId = extnId ; + } else { + m_xExtnId = Sequence<sal_Int8>(); + } + + m_critical = critical ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.hxx b/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.hxx new file mode 100644 index 000000000000..bbfecbbcd760 --- /dev/null +++ b/xmlsecurity/source/xmlsec/certificateextension_xmlsecimpl.hxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _CERTIFICATEEXTENSION_XMLSECIMPL_HXX_ +#define _CERTIFICATEEXTENSION_XMLSECIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include "com/sun/star/uno/SecurityException.hpp" +#include <com/sun/star/security/XCertificateExtension.hpp> + +class CertificateExtension_XmlSecImpl : public ::cppu::WeakImplHelper1< + ::com::sun::star::security::XCertificateExtension > +{ + private : + sal_Bool m_critical ; + ::com::sun::star::uno::Sequence< sal_Int8 > m_xExtnId ; + ::com::sun::star::uno::Sequence< sal_Int8 > m_xExtnValue ; + + public : + CertificateExtension_XmlSecImpl() ; + virtual ~CertificateExtension_XmlSecImpl() ; + + //Methods from XCertificateExtension + virtual sal_Bool SAL_CALL isCritical() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getExtensionId() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getExtensionValue() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper method + void setCertExtn( ::com::sun::star::uno::Sequence< sal_Int8 > extnId, ::com::sun::star::uno::Sequence< sal_Int8 > extnValue, sal_Bool critical ) ; + + void setCertExtn( unsigned char* value, unsigned int vlen, unsigned char* id, unsigned int idlen, sal_Bool critical ) ; +} ; + +#endif // _CERTIFICATEEXTENSION_XMLSECIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/certvalidity.cxx b/xmlsecurity/source/xmlsec/certvalidity.cxx new file mode 100644 index 000000000000..e53863d1dd01 --- /dev/null +++ b/xmlsecurity/source/xmlsec/certvalidity.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <xmlsecurity/certvalidity.hxx> +#include <com/sun/star/security/CertificateValidity.hpp> + +using ::rtl::OUString ; +using namespace ::com::sun::star::security ; + +#define VALID_STR "valid certificate" +#define INVALID_STR "invalid certificate" +#define UNTRUSTED_STR "untrusted certificate" +#define TIME_INVALID_STR "expired certificate" +#define NOT_NESTED_TIME_STR "invalid time nesting" +#define REVOKED_STR "revoked certificate" +#define UNKNOWN_REVOKATION_STR "unknown certificate revocation status" +#define SIGNATURE_INVALID_STR "invalid certificate signature" +#define EXTENSION_INVALID_STR "invalid certificate extension" +#define EXTENSION_UNKNOWN_STR "unknown critical certificate extension" +#define ISSUER_UNKNOWN_STR "unknown certificate issuer" +#define ISSUER_UNTRUSTED_STR "untrusted certificate issuer" +#define ISSUER_INVALID_STR "invalid certificate issuer" +#define ROOT_UNKNOWN_STR "unknown root certificate" +#define ROOT_UNTRUSTED_STR "untrusted root certificate" +#define ROOT_INVALID_STR "invalid root certificate" +#define CHAIN_INCOMPLETE_STR "invalid certification path" + +rtl::OUString certificateValidityToOUString( ::sal_Int32 certValidity ) { + OUString aValidity ; + + if( (certValidity & CertificateValidity::VALID) == CertificateValidity::VALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(VALID_STR )) ; + } else if( ( certValidity & CertificateValidity::INVALID ) == CertificateValidity::INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::UNTRUSTED ) == CertificateValidity::UNTRUSTED ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(UNTRUSTED_STR )) ; + } else if( ( certValidity & CertificateValidity::TIME_INVALID ) == CertificateValidity::TIME_INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(TIME_INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::NOT_TIME_NESTED ) == CertificateValidity::NOT_TIME_NESTED ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(NOT_NESTED_TIME_STR )) ; + } else if( ( certValidity & CertificateValidity::REVOKED ) == CertificateValidity::REVOKED ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(REVOKED_STR )) ; + } else if( ( certValidity & CertificateValidity::UNKNOWN_REVOKATION ) == CertificateValidity::UNKNOWN_REVOKATION ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(UNKNOWN_REVOKATION_STR )) ; + } else if( ( certValidity & CertificateValidity::SIGNATURE_INVALID ) == CertificateValidity::SIGNATURE_INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(SIGNATURE_INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::EXTENSION_INVALID ) == CertificateValidity::EXTENSION_INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(EXTENSION_INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::EXTENSION_UNKNOWN ) == CertificateValidity::EXTENSION_UNKNOWN ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(EXTENSION_UNKNOWN_STR )) ; + } else if( ( certValidity & CertificateValidity::ISSUER_UNKNOWN ) == CertificateValidity::ISSUER_UNKNOWN ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ISSUER_UNKNOWN_STR )) ; + } else if( ( certValidity & CertificateValidity::ISSUER_UNTRUSTED ) == CertificateValidity::ISSUER_UNTRUSTED ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ISSUER_UNTRUSTED_STR )) ; + } else if( ( certValidity & CertificateValidity::ISSUER_INVALID ) == CertificateValidity::ISSUER_INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ISSUER_INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::ROOT_UNKNOWN ) == CertificateValidity::ROOT_UNKNOWN ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ROOT_UNKNOWN_STR )) ; + } else if( ( certValidity & CertificateValidity::ROOT_UNTRUSTED ) == CertificateValidity::ROOT_UNTRUSTED ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ROOT_UNTRUSTED_STR )) ; + } else if( ( certValidity & CertificateValidity::ROOT_INVALID ) == CertificateValidity::ROOT_INVALID ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(ROOT_INVALID_STR )) ; + } else if( ( certValidity & CertificateValidity::CHAIN_INCOMPLETE ) == CertificateValidity::CHAIN_INCOMPLETE ) { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(CHAIN_INCOMPLETE_STR )) ; + } else { + aValidity = OUString(RTL_CONSTASCII_USTRINGPARAM(INVALID_STR )) ; + } + + return aValidity ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/diagnose.cxx b/xmlsecurity/source/xmlsec/diagnose.cxx new file mode 100644 index 000000000000..05bf0275f3d1 --- /dev/null +++ b/xmlsecurity/source/xmlsec/diagnose.cxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * + * 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> +{ + bool operator () () const + { + ::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); + } +} + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/diagnose.hxx b/xmlsecurity/source/xmlsec/diagnose.hxx new file mode 100644 index 000000000000..33bd9cb8a6a4 --- /dev/null +++ b/xmlsecurity/source/xmlsec/diagnose.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * + * 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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/errorcallback.cxx b/xmlsecurity/source/xmlsec/errorcallback.cxx new file mode 100644 index 000000000000..6a1558108b61 --- /dev/null +++ b/xmlsecurity/source/xmlsec/errorcallback.cxx @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +/* + * Implementation of the I/O interfaces based on stream and URI binding + */ +#include "errorcallback.hxx" + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include "xmlsec/xmlsec.h" +#include "xmlsec/errors.h" + +using namespace ::com::sun::star::xml::crypto; + + +extern "C" +void errorCallback(const char * /*file*/, + int /*line*/, + const char * /*func*/, + const char * /*errorObject*/, + const char * /*errorSubject*/, + int /*reason*/, + const char * /*msg*/) +{ +#if OSL_DEBUG_LEVEL > 1 +// const char * afunc = func ? func : ""; +// const char * errObj = errorObject ? errorObject : ""; +// const char * errSub = errorSubject ? errorSubject : ""; +// const char * amsg = msg ? msg : ""; +// fprintf(stdout, "xmlsec error: %s, %s, %s, %i %s \n", afunc, errObj, errSub, reason, amsg); +#endif +} + +void setErrorRecorder() +{ + xmlSecErrorsSetCallback(errorCallback); +} + +void clearErrorRecorder() +{ + xmlSecErrorsSetCallback(NULL); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/errorcallback.hxx b/xmlsecurity/source/xmlsec/errorcallback.hxx new file mode 100644 index 000000000000..c861263a0f22 --- /dev/null +++ b/xmlsecurity/source/xmlsec/errorcallback.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _ERRORCALLBACK_XMLSECIMPL_HXX_ +#define _ERRORCALLBACK_XMLSECIMPL_HXX_ + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp> +#include <com/sun/star/xml/crypto/XXMLEncryptionTemplate.hpp> + +// Only used for logging +void setErrorRecorder(); +//ToDo +//void setErrorRecorder(const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate >& xTemplate); +void clearErrorRecorder(); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/makefile.mk b/xmlsecurity/source/xmlsec/makefile.mk new file mode 100644 index 000000000000..44b668b84765 --- /dev/null +++ b/xmlsecurity/source/xmlsec/makefile.mk @@ -0,0 +1,72 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME = xmlsecurity +TARGET = xs_comm + +ENABLE_EXCEPTIONS = TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/target.pmk + +.IF "$(SYSTEM_LIBXML)" == "YES" +CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS) +.ENDIF + +.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 +.ELSE +CDEFS += -DXMLSEC_CRYPTO_NSS -DXMLSEC_NO_XSLT +.ENDIF + +# --- Files -------------------------------------------------------- +SLOFILES = \ + $(SLO)$/biginteger.obj \ + $(SLO)$/certvalidity.obj \ + $(SLO)$/saxhelper.obj \ + $(SLO)$/xmldocumentwrapper_xmlsecimpl.obj \ + $(SLO)$/xmlelementwrapper_xmlsecimpl.obj \ + $(SLO)$/certificateextension_xmlsecimpl.obj \ + $(SLO)$/xmlstreamio.obj \ + $(SLO)$/errorcallback.obj \ + $(SLO)$/xsec_xmlsec.obj \ + $(SLO)$/diagnose.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/xmlsecurity/source/xmlsec/mscrypt/makefile.mk b/xmlsecurity/source/xmlsec/mscrypt/makefile.mk new file mode 100644 index 000000000000..20153edf18e6 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME = xmlsecurity +TARGET = xs_mscrypt + +ENABLE_EXCEPTIONS = TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/target.pmk + +.IF "$(CRYPTO_ENGINE)" != "mscrypto" +LIBTARGET=NO +.ENDIF + +.IF "$(CRYPTO_ENGINE)" == "mscrypto" + +.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 + +# --- Files -------------------------------------------------------- +INCLOCAL = \ + .. + +SLOFILES = \ + $(SLO)$/securityenvironment_mscryptimpl.obj \ + $(SLO)$/xmlencryption_mscryptimpl.obj \ + $(SLO)$/xmlsecuritycontext_mscryptimpl.obj \ + $(SLO)$/xmlsignature_mscryptimpl.obj \ + $(SLO)$/x509certificate_mscryptimpl.obj \ + $(SLO)$/seinitializer_mscryptimpl.obj \ + $(SLO)$/xsec_mscrypt.obj + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/xmlsecurity/source/xmlsec/mscrypt/oid.hxx b/xmlsecurity/source/xmlsec/mscrypt/oid.hxx new file mode 100644 index 000000000000..c46456d4dc87 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/oid.hxx @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _OID_HXX_ +#define _OID_HXX_ + +typedef struct OIDItemStr OIDItem; + +struct OIDItemStr { + char *oid; + char *desc; +}; + +OIDItem OIDs[] = { + {"1.2.840.113549", "RSA Data Security Inc."}, + {"1.2.840.113549.1", "PKCS"}, + {"1.2.840.113549.2", "RSA digest algorithm"}, + {"1.2.840.113549.3", "RSA cipher algorithm"}, + {"1.2.840.113549.1.1", "PKCS #1"}, + {"1.2.840.113549.1.2", "Unknown"}, + {"1.2.840.113549.1.3", "Unknown"}, + {"1.2.840.113549.1.4", "Unknown"}, + {"1.2.840.113549.1.5", "PKCS #5"}, + {"1.2.840.113549.1.6", "Unknown"}, + {"1.2.840.113549.1.7", "PKCS #7"}, + {"1.2.840.113549.1.8", "Unknown"}, + {"1.2.840.113549.1.9", "PKCS #9"}, + {"1.2.840.113549.1.10", "Unknown"}, + {"1.2.840.113549.1.12", "PKCS #12"}, + {"1.2.840.113549.1.1.2", "PKCS #1 MD2 With RSA Encryption"}, + {"1.2.840.113549.1.1.3", "PKCS #1 MD4 With RSA Encryption"}, + {"1.2.840.113549.1.1.4", "PKCS #1 MD5 With RSA Encryption"}, + {"1.2.840.113549.1.1.1", "PKCS #1 RSA Encryption"}, + {"1.2.840.113549.1.1.2", "PKCS #1 MD2 With RSA Encryption"}, + {"1.2.840.113549.1.1.3", "PKCS #1 MD4 With RSA Encryption"}, + {"1.2.840.113549.1.1.4", "PKCS #1 MD5 With RSA Encryption"}, + {"1.2.840.113549.1.1.5", "PKCS #1 SHA-1 With RSA Encryption"}, + {"1.2.840.113549.1.1.5", "PKCS #1 SHA-1 With RSA Encryption"}, + {"1.2.840.113549.1.3.1", "Unknown"}, + {"1.2.840.113549.1.7.1", "PKCS #7 Data"}, + {"1.2.840.113549.1.7.2", "PKCS #7 Signed Data"}, + {"1.2.840.113549.1.7.3", "PKCS #7 Enveloped Data"}, + {"1.2.840.113549.1.7.4", "PKCS #7 Signed and Enveloped Data"}, + {"1.2.840.113549.1.7.5", "PKCS #7 Digested Data"}, + {"1.2.840.113549.1.7.5", "PKCS #7 Digested Data"}, + {"1.2.840.113549.1.7.6", "PKCS #7 Encrypted Data"}, + {"1.2.840.113549.1.9.1", "PKCS #9 Email Address"}, + {"1.2.840.113549.1.9.2", "PKCS #9 Unstructured Name"}, + {"1.2.840.113549.1.9.3", "PKCS #9 Content Type"}, + {"1.2.840.113549.1.9.4", "PKCS #9 Message Digest"}, + {"1.2.840.113549.1.9.5", "PKCS #9 Signing Time"}, + {"1.2.840.113549.1.9.6", "PKCS #9 Counter Signature"}, + {"1.2.840.113549.1.9.7", "PKCS #9 Challenge Password"}, + {"1.2.840.113549.1.9.8", "PKCS #9 Unstructured Address"}, + {"1.2.840.113549.1.9.9", "PKCS #9 Extended Certificate Attributes"}, + {"1.2.840.113549.1.9.15", "PKCS #9 S/MIME Capabilities"}, + {"1.2.840.113549.1.9.15.1", "Unknown"}, + {"1.2.840.113549.3.2", "RC2-CBC"}, + {"1.2.840.113549.3.4", "RC4"}, + {"1.2.840.113549.3.7", "DES-EDE3-CBC"}, + {"1.2.840.113549.3.9", "RC5-CBCPad"}, + {"1.2.840.10046", "ANSI X9.42"}, + {"1.2.840.10046.2.1", "Diffie-Hellman Public Key Algorithm"}, + {"1.2.840.10040", "ANSI X9.57"}, + {"1.2.840.10040.4.1", "ANSI X9.57 DSA Signature"}, + {"1.2.840.10040.4.3", "ANSI X9.57 Algorithm DSA Signature with SHA-1 Digest"}, + {"2.5", "Directory"}, + {"2.5.8", "X.500-defined algorithms"}, + {"2.5.8.1", "X.500-defined encryption algorithms"}, + {"2.5.8.2", "Unknown"}, + {"2.5.8.3", "Unknown"}, + {"2.5.8.1.1", "RSA Encryption Algorithm"}, + {"1.3.14", "Open Systems Implementors Workshop"}, + {"1.3.14.3.2", "OIW SECSIG Algorithm"}, + {"1.3.14.3.2.2", "Unknown"}, + {"1.3.14.3.2.3", "Unknown"}, + {"1.3.14.3.2.4", "Unknown"}, + {"1.3.14.3.2.6", "DES-ECB"}, + {"1.3.14.3.2.7", "DES-CBC"}, + {"1.3.14.3.2.8", "DES-OFB"}, + {"1.3.14.3.2.9", "DES-CFB"}, + {"1.3.14.3.2.10", "DES-MAC"}, + {"1.3.14.3.2.11", "Unknown"}, + {"1.3.14.3.2.12", "Unknown"}, + {"1.3.14.3.2.13", "Unknown"}, + {"1.3.14.3.2.14", "Unknown"}, + {"1.3.14.3.2.15", "ISO SHA with RSA Signature"}, + {"1.3.14.3.2.16", "Unknown"}, + {"1.3.14.3.2.17", "DES-EDE"}, + {"1.3.14.3.2.18", "Unknown"}, + {"1.3.14.3.2.19", "Unknown"}, + {"1.3.14.3.2.20", "Unknown"}, + {"1.3.14.3.2.21", "Unknown"}, + {"1.3.14.3.2.22", "Unknown"}, + {"1.3.14.3.2.23", "Unknown"}, + {"1.3.14.3.2.24", "Unknown"}, + {"1.3.14.3.2.25", "Unknown"}, + {"1.3.14.3.2.26", "SHA-1"}, + {"1.3.14.3.2.27", "Forgezza DSA Signature with SHA-1 Digest"}, + {"1.3.14.3.2.28", "Unknown"}, + {"1.3.14.3.2.29", "Unknown"}, + {"1.3.14.7.2", "Unknown"}, + {"1.3.14.7.2.1", "Unknown"}, + {"1.3.14.7.2.2", "Unknown"}, + {"1.3.14.7.2.3", "Unknown"}, + {"1.3.14.7.2.2.1", "Unknown"}, + {"1.3.14.7.2.3.1", "Unknown"}, + {"2.16.840.1.101.2.1", "US DOD Infosec"}, + {"2.16.840.1.101.2.1.1.1", "Unknown"}, + {"2.16.840.1.101.2.1.1.2", "MISSI DSS Algorithm (Old)"}, + {"2.16.840.1.101.2.1.1.3", "Unknown"}, + {"2.16.840.1.101.2.1.1.4", "Skipjack CBC64"}, + {"2.16.840.1.101.2.1.1.5", "Unknown"}, + {"2.16.840.1.101.2.1.1.6", "Unknown"}, + {"2.16.840.1.101.2.1.1.7", "Unknown"}, + {"2.16.840.1.101.2.1.1.8", "Unknown"}, + {"2.16.840.1.101.2.1.1.9", "Unknown"}, + {"2.16.840.1.101.2.1.1.10", "MISSI KEA Algorithm"}, + {"2.16.840.1.101.2.1.1.11", "Unknown"}, + {"2.16.840.1.101.2.1.1.12", "MISSI KEA and DSS Algorithm (Old)"}, + {"2.16.840.1.101.2.1.1.13", "Unknown"}, + {"2.16.840.1.101.2.1.1.14", "Unknown"}, + {"2.16.840.1.101.2.1.1.15", "Unknown"}, + {"2.16.840.1.101.2.1.1.16", "Unknown"}, + {"2.16.840.1.101.2.1.1.17", "Unknown"}, + {"2.16.840.1.101.2.1.1.18", "Unknown"}, + {"2.16.840.1.101.2.1.1.19", "MISSI DSS Algorithm"}, + {"2.16.840.1.101.2.1.1.20", "MISSI KEA and DSS Algorithm"}, + {"2.16.840.1.101.2.1.1.21", "Unknown"} +}; + +int nOID = 115; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx new file mode 100644 index 000000000000..94017fe97286 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.cxx @@ -0,0 +1,1281 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#ifdef _MSC_VER +#pragma warning(push,1) +#endif +#include "Windows.h" +#include "WinCrypt.h" +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include <sal/config.h> +#include <sal/macros.h> +#include <osl/thread.h> +#include "securityenvironment_mscryptimpl.hxx" + +#include "x509certificate_mscryptimpl.hxx" +#include <rtl/uuid.h> + +#include <xmlsec/xmlsec.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/crypto.h> +#include <xmlsec/base64.h> + +#include <xmlsecurity/biginteger.hxx> + +#include "xmlsec/keysmngr.h" +#include "xmlsec/mscrypto/akmngr.h" + +#include <rtl/locale.h> +#include <osl/nlsupport.h> +#include <osl/process.h> + +#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 ; +using ::com::sun::star::lang::XSingleServiceFactory ; +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) +{ + xmlsec_trace("The certificate error status is: "); + if (err == 0) + xmlsec_trace("%s", arErrStrings[0].name); + for (int i = 1; i < SAL_N_ELEMENTS(arErrStrings); 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 ) { + +} + +SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() { + + if( m_hProv != NULL ) { + CryptReleaseContext( m_hProv, 0 ) ; + m_hProv = NULL ; + } + + if( m_pszContainer != NULL ) { + //TODO: Don't know whether or not it should be released now. + m_pszContainer = NULL ; + } + + if( m_hCertStore != NULL ) { + CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; + m_hCertStore = NULL ; + } + + if( m_hKeyStore != NULL ) { + CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; + m_hKeyStore = NULL ; + } + + if( !m_tSymKeyList.empty() ) { + std::list< HCRYPTKEY >::iterator symKeyIt ; + + for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; ++symKeyIt ) + CryptDestroyKey( *symKeyIt ) ; + } + + if( !m_tPubKeyList.empty() ) { + std::list< HCRYPTKEY >::iterator pubKeyIt ; + + for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; ++pubKeyIt ) + CryptDestroyKey( *pubKeyIt ) ; + } + + if( !m_tPriKeyList.empty() ) { + std::list< HCRYPTKEY >::iterator priKeyIt ; + + for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; ++priKeyIt ) + CryptDestroyKey( *priKeyIt ) ; + } + +} + +/* XInitialization */ +void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + //TODO +} ; + +/* XServiceInfo */ +OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.SecurityEnvironment")) ; + return seqServiceNames ; +} + +OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* XUnoTunnel */ +sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) + throw( RuntimeException ) +{ + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { + return ( sal_Int64 )this ; + } + return 0 ; +} + +/* XUnoTunnel extension */ +const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() { + static Sequence< sal_Int8 >* pSeq = 0 ; + if( !pSeq ) { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if( !pSeq ) { + static Sequence< sal_Int8> aSeq( 16 ) ; + rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; + pSeq = &aSeq ; + } + } + return *pSeq ; +} + +/* XUnoTunnel extension */ +SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) { + Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; + if( xUT.is() ) { + return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ; + } else + return NULL ; +} + +/* Native methods */ +HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { + return m_hProv ; +} + +void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { + if( m_hProv != NULL ) { + CryptReleaseContext( m_hProv, 0 ) ; + m_hProv = NULL ; + } + + if( aProv != NULL ) { + m_hProv = aProv ; + } +} + +LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { + return m_pszContainer ; +} + +void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { + //TODO: Don't know whether or not it should be copied. + m_pszContainer = aKeyContainer ; +} + + +HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) { + return m_hKeyStore ; +} + +void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) { + if( m_hKeyStore != NULL ) { + CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; + m_hKeyStore = NULL ; + } + + if( aSlot != NULL ) { + m_hKeyStore = CertDuplicateStore( aSlot ) ; + } +} + +HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) { + return m_hCertStore ; +} + +void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) { + if( m_hCertStore != NULL ) { + CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ; + m_hCertStore = NULL ; + } + + if( aCertDb != NULL ) { + m_hCertStore = CertDuplicateStore( aCertDb ) ; + } +} + +void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY symkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aSymKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) { + if( *keyIt == aSymKey ) + return ; + } + + //If we do not find the key in the list, add a new node + symkey = aSymKey ; + + try { + m_tSymKeyList.push_back( symkey ) ; + } catch ( Exception& ) { + CryptDestroyKey( symkey ) ; + } + } +} + +void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY symkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aSymKey != NULL ) { + for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) { + if( *keyIt == aSymKey ) { + symkey = *keyIt ; + CryptDestroyKey( symkey ) ; + m_tSymKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) { + HCRYPTKEY symkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + unsigned int pos ; + + symkey = NULL ; + for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; ++pos , ++keyIt ) ; + + if( pos == position && keyIt != m_tSymKeyList.end() ) + symkey = *keyIt ; + + return symkey ; +} + +void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY pubkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aPubKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) { + if( *keyIt == aPubKey ) + return ; + } + + //If we do not find the key in the list, add a new node + pubkey = aPubKey ; + + try { + m_tPubKeyList.push_back( pubkey ) ; + } catch ( Exception& ) { + CryptDestroyKey( pubkey ) ; + } + } +} + +void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY pubkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aPubKey != NULL ) { + for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) { + if( *keyIt == aPubKey ) { + pubkey = *keyIt ; + CryptDestroyKey( pubkey ) ; + m_tPubKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) { + HCRYPTKEY pubkey ; + std::list< HCRYPTKEY >::iterator keyIt ; + unsigned int pos ; + + pubkey = NULL ; + for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; ++pos , ++keyIt ) ; + + if( pos == position && keyIt != m_tPubKeyList.end() ) + pubkey = *keyIt ; + + return pubkey ; +} + +void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY prikey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aPriKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) { + if( *keyIt == aPriKey ) + return ; + } + + //If we do not find the key in the list, add a new node + prikey = aPriKey ; + + try { + m_tPriKeyList.push_back( prikey ) ; + } catch ( Exception& ) { + CryptDestroyKey( prikey ) ; + } + } +} + +void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) { + HCRYPTKEY prikey ; + std::list< HCRYPTKEY >::iterator keyIt ; + + if( aPriKey != NULL ) { + for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) { + if( *keyIt == aPriKey ) { + prikey = *keyIt ; + CryptDestroyKey( prikey ) ; + m_tPriKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) { + HCRYPTKEY prikey ; + std::list< HCRYPTKEY >::iterator keyIt ; + unsigned int pos ; + + prikey = NULL ; + for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; ++pos , ++keyIt ) ; + + if( pos == position && keyIt != m_tPriKeyList.end() ) + prikey = *keyIt ; + + return prikey ; +} + +//Methods from XSecurityEnvironment +Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException ) +{ + sal_Int32 length ; + X509Certificate_MSCryptImpl* xcert ; + std::list< X509Certificate_MSCryptImpl* > certsList ; + PCCERT_CONTEXT pCertContext = NULL; + + //firstly, we try to find private keys in given key store. + if( m_hKeyStore != NULL ) { + pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ); + while (pCertContext) + { + xcert = MswcryCertContextToXCert( pCertContext ) ; + if( xcert != NULL ) + certsList.push_back( xcert ) ; + pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ); + } + } + + //secondly, we try to find certificate from registered private keys. + if( !m_tPriKeyList.empty() ) { + //TODO: Don't know whether or not it is necessary ans possible. + } + + //Thirdly, we try to find certificate from system default key store. + if( m_bEnableDefault ) { + HCERTSTORE hSystemKeyStore ; + DWORD dwKeySpec; + HCRYPTPROV hCryptProv; + + hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ; + if( hSystemKeyStore != NULL ) { + pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); + while (pCertContext) + { + // for checking whether the certificate is a personal certificate or not. + if(!(CryptAcquireCertificatePrivateKey(pCertContext, + CRYPT_ACQUIRE_COMPARE_KEY_FLAG, + NULL, + &hCryptProv, + &dwKeySpec, + NULL))) + { + // Not Privatekey found. SKIP this one. + pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); + continue; + } + // then TODO : Check the personal cert is valid or not. + + xcert = MswcryCertContextToXCert( pCertContext ) ; + if( xcert != NULL ) + certsList.push_back( xcert ) ; + pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ); + } + } + + CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + } + + length = certsList.size() ; + if( length != 0 ) { + int i ; + std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ; + Sequence< Reference< XCertificate > > certSeq( length ) ; + + for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); ++xcertIt, ++i ) { + certSeq[i] = *xcertIt ; + } + + return certSeq ; + } + + return Sequence< Reference< XCertificate > >() ; +} + + +Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) { + unsigned int i ; + LPSTR pszName ; + X509Certificate_MSCryptImpl *xcert = NULL ; + PCCERT_CONTEXT pCertContext = NULL ; + HCERTSTORE hCertStore = NULL ; + CRYPT_INTEGER_BLOB cryptSerialNumber ; + CERT_INFO certInfo ; + + // for correct encoding + sal_uInt16 encoding ; + rtl_Locale *pLocale = NULL ; + osl_getProcessLocale( &pLocale ) ; + encoding = osl_getTextEncodingFromLocale( pLocale ) ; + + //Create cert info from issue and serial + rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ; + pszName = ( char* )oissuer.getStr() ; + + if( ! ( CertStrToName( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + pszName , + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, + NULL , + NULL , + &certInfo.Issuer.cbData, NULL ) ) + ) { + return NULL ; + } + + certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData ); + if(!certInfo.Issuer.pbData) + throw RuntimeException() ; + + if( ! ( CertStrToName( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + pszName , + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, + NULL , + ( BYTE* )certInfo.Issuer.pbData , + &certInfo.Issuer.cbData, NULL ) ) + ) { + free( certInfo.Issuer.pbData ) ; + return NULL ; + } + + //Get the SerialNumber + cryptSerialNumber.cbData = serialNumber.getLength() ; + cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData); + if (!cryptSerialNumber.pbData) + { + free( certInfo.Issuer.pbData ) ; + throw RuntimeException() ; + } + for( i = 0; i < cryptSerialNumber.cbData; i ++ ) + cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ; + + certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ; + certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ; + + // Get the Cert from all store. + for( i = 0 ; i < 6 ; i ++ ) + { + switch(i) + { + case 0: + if(m_hKeyStore == NULL) continue ; + hCertStore = m_hKeyStore ; + break; + case 1: + if(m_hCertStore == NULL) continue ; + hCertStore = m_hCertStore ; + break; + case 2: + hCertStore = CertOpenSystemStore( 0, "MY" ) ; + if(hCertStore == NULL || !m_bEnableDefault) continue ; + break; + case 3: + hCertStore = CertOpenSystemStore( 0, "Root" ) ; + if(hCertStore == NULL || !m_bEnableDefault) continue ; + break; + case 4: + hCertStore = CertOpenSystemStore( 0, "Trust" ) ; + if(hCertStore == NULL || !m_bEnableDefault) continue ; + break; + case 5: + hCertStore = CertOpenSystemStore( 0, "CA" ) ; + if(hCertStore == NULL || !m_bEnableDefault) continue ; + break; + default: + i=6; + continue; + } + +/******************************************************************************* + * This code reserved for remind us there are another way to find one cert by + * IssuerName&serialnumber. You can use the code to replaced the function + * CertFindCertificateInStore IF and ONLY IF you must find one special cert in + * certStore but can not be found by CertFindCertificateInStore , then , you + * should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875. + * By Chandler Peng(chandler.peng@sun.com) + *****/ +/******************************************************************************* + pCertContext = NULL ; + found = 0; + do{ + // 1. enum the certs has same string in the issuer string. + pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ; + if( pCertContext != NULL ) + { + // 2. check the cert's issuer name . + char* issuer = NULL ; + DWORD cbIssuer = 0 ; + + cbIssuer = CertNameToStr( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + &( pCertContext->pCertInfo->Issuer ), + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , + NULL, 0 + ) ; + + if( cbIssuer == 0 ) continue ; // discard this cert; + + issuer = (char *)malloc( cbIssuer ) ; + if( issuer == NULL ) // discard this cert; + { + free( cryptSerialNumber.pbData) ; + free( certInfo.Issuer.pbData ) ; + CertFreeCertificateContext( pCertContext ) ; + if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + + cbIssuer = CertNameToStr( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + &( pCertContext->pCertInfo->Issuer ), + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , + issuer, cbIssuer + ) ; + + if( cbIssuer <= 0 ) + { + free( issuer ) ; + continue ;// discard this cert; + } + + if(strncmp(pszName , issuer , cbIssuer) != 0) + { + free( issuer ) ; + continue ;// discard this cert; + } + free( issuer ) ; + + // 3. check the serial number. + if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 ) + { + continue ;// discard this cert; + } + + // 4. confirm and break; + found = 1; + break ; + } + + }while(pCertContext); + + if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + if( found != 0 ) break; // Found the certificate. +********************************************************************************/ + + pCertContext = CertFindCertificateInStore( + hCertStore, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, + CERT_FIND_SUBJECT_CERT, + &certInfo, + NULL + ) ; + + if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + if( pCertContext != NULL ) break ; // Found the certificate. + + } + + if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ; + if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ; + + if( pCertContext != NULL ) { + xcert = MswcryCertContextToXCert( pCertContext ) ; + if( pCertContext ) CertFreeCertificateContext( pCertContext ) ; + } else { + xcert = NULL ; + } + + return xcert ; +} + +Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) { + Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ; + return getCertificate( issuerName, serial ) ; +} + +Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) { + PCCERT_CHAIN_CONTEXT pChainContext ; + PCCERT_CONTEXT pCertContext ; + const X509Certificate_MSCryptImpl* xcert ; + + CERT_ENHKEY_USAGE enhKeyUsage ; + CERT_USAGE_MATCH certUsage ; + CERT_CHAIN_PARA chainPara ; + + enhKeyUsage.cUsageIdentifier = 0 ; + enhKeyUsage.rgpszUsageIdentifier = NULL ; + certUsage.dwType = USAGE_MATCH_TYPE_AND ; + certUsage.Usage = enhKeyUsage ; + chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ; + chainPara.RequestedUsage = certUsage ; + + Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ; + if( !xCertTunnel.is() ) { + throw RuntimeException() ; + } + + xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; + if( xcert == NULL ) { + throw RuntimeException() ; + } + + pCertContext = xcert->getMswcryCert() ; + + pChainContext = NULL ; + + BOOL bChain = FALSE; + if( pCertContext != NULL ) + { + HCERTSTORE hAdditionalStore = NULL; + HCERTSTORE hCollectionStore = NULL; + if (m_hCertStore && m_hKeyStore) + { + //Merge m_hCertStore and m_hKeyStore into one store. + hCollectionStore = CertOpenStore( + CERT_STORE_PROV_COLLECTION , + 0 , + NULL , + 0 , + NULL + ) ; + if (hCollectionStore != NULL) + { + CertAddStoreToCollection ( + hCollectionStore , + m_hCertStore , + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , + 0) ; + CertAddStoreToCollection ( + hCollectionStore , + m_hCertStore , + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , + 0) ; + hAdditionalStore = hCollectionStore; + } + + } + + //if the merge of both stores failed then we add only m_hCertStore + if (hAdditionalStore == NULL && m_hCertStore) + hAdditionalStore = m_hCertStore; + else if (hAdditionalStore == NULL && m_hKeyStore) + hAdditionalStore = m_hKeyStore; + else + hAdditionalStore = NULL; + + //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST + bChain = CertGetCertificateChain( + NULL , + pCertContext , + NULL , //use current system time + hAdditionalStore, + &chainPara , + CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME , + NULL , + &pChainContext); + if (!bChain) + pChainContext = NULL; + + //Close the additional store + CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); + } + + if(bChain && pChainContext != NULL && pChainContext->cChain > 0 ) + { + PCCERT_CONTEXT pCertInChain ; + PCERT_SIMPLE_CHAIN pCertChain ; + X509Certificate_MSCryptImpl* pCert ; + + pCertChain = pChainContext->rgpChain[0] ; + if( pCertChain->cElement ) { + Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ; + + for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) { + if( pCertChain->rgpElement[i] ) + pCertInChain = pCertChain->rgpElement[i]->pCertContext ; + else + pCertInChain = NULL ; + + if( pCertInChain != NULL ) { + pCert = MswcryCertContextToXCert( pCertInChain ) ; + if( pCert != NULL ) + xCertChain[i] = pCert ; + } + } + + CertFreeCertificateChain( pChainContext ) ; + pChainContext = NULL ; + + return xCertChain ; + } + } + if (pChainContext) + CertFreeCertificateChain(pChainContext); + + return Sequence< Reference < XCertificate > >(); +} + +Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) { + X509Certificate_MSCryptImpl* xcert ; + + if( rawCertificate.getLength() > 0 ) { + xcert = new X509Certificate_MSCryptImpl() ; + if( xcert == NULL ) + throw RuntimeException() ; + + xcert->setRawCert( rawCertificate ) ; + } else { + xcert = NULL ; + } + + return xcert ; +} + +Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) { + xmlChar* chCert ; + xmlSecSize certSize ; + + rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ; + + chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ; + + certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ; + + Sequence< sal_Int8 > rawCert( certSize ) ; + for( unsigned int i = 0 ; i < certSize ; i ++ ) + rawCert[i] = *( chCert + i ) ; + + xmlFree( chCert ) ; + + return createCertificateFromRaw( rawCert ) ; +} + + +HCERTSTORE getCertStoreForIntermediatCerts( + const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts) +{ + HCERTSTORE store = NULL; + store = CertOpenStore( + CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL); + if (store == NULL) + return NULL; + + 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()); + //Adding the certificate creates a copy and not just increases the ref count + //Therefore we free later the certificate that we now add + CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, NULL); + CertFreeCertificateContext(cert); + } + 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) + throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) +{ + sal_Int32 validity = 0; + PCCERT_CHAIN_CONTEXT pChainContext = NULL; + PCCERT_CONTEXT pCertContext = NULL; + const X509Certificate_MSCryptImpl* xcert = NULL; + + 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 ; + certUsage.dwType = USAGE_MATCH_TYPE_AND ; + certUsage.Usage = enhKeyUsage ; + chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ; + chainPara.RequestedUsage = certUsage ; + + + HCERTSTORE hCollectionStore = NULL; + HCERTSTORE hIntermediateCertsStore = NULL; + BOOL bChain = FALSE; + if( pCertContext != NULL ) + { + hIntermediateCertsStore = + getCertStoreForIntermediatCerts(seqCerts); + + //Merge m_hCertStore and m_hKeyStore and the store of the intermediate + //certificates into one store. + hCollectionStore = CertOpenStore( + CERT_STORE_PROV_COLLECTION , + 0 , + NULL , + 0 , + NULL + ) ; + if (hCollectionStore != NULL) + { + CertAddStoreToCollection ( + hCollectionStore , + m_hCertStore , + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , + 0) ; + CertAddStoreToCollection ( + hCollectionStore , + m_hCertStore , + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG , + 0) ; + CertAddStoreToCollection ( + hCollectionStore, + hIntermediateCertsStore, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, + 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_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, + NULL , + &pChainContext); + + if (bChain && pChainContext->cChain > 0) + { + 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)) + + { + //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 ; + } + } + else + { + xmlsec_trace("CertGetCertificateChaine failed.\n"); + } + } + + if (pChainContext) + { + CertFreeCertificateChain(pChainContext); + pChainContext = NULL; + } + + //Close the additional store, do not destroy the contained certs + CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG); + //Close the temporary store containing the intermediate certificates and make + //sure all certificates are deleted. + CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG); + + return validity ; +} + +sal_Int32 SecurityEnvironment_MSCryptImpl :: getCertificateCharacters( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) { + sal_Int32 characters ; + PCCERT_CONTEXT pCertContext ; + const X509Certificate_MSCryptImpl* xcert ; + + Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; + if( !xCertTunnel.is() ) { + throw RuntimeException() ; + } + + xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ; + if( xcert == NULL ) { + throw RuntimeException() ; + } + + pCertContext = xcert->getMswcryCert() ; + + characters = 0x00000000 ; + + //Firstly, make sentence whether or not the cert is self-signed. + if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) { + characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; + } else { + characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; + } + + //Secondly, make sentence whether or not the cert has a private key. + { + BOOL fCallerFreeProv ; + DWORD dwKeySpec ; + HCRYPTPROV hProv ; + if( CryptAcquireCertificatePrivateKey( pCertContext , + 0 , + NULL , + &( hProv ) , + &( dwKeySpec ) , + &( fCallerFreeProv ) ) + ) { + characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; + + if( hProv != NULL && fCallerFreeProv ) + CryptReleaseContext( hProv, 0 ) ; + } else { + characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; + } + } + return characters ; +} + +void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) { + m_bEnableDefault = enable ; +} + +sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) { + return m_bEnableDefault ; +} + +X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) +{ + X509Certificate_MSCryptImpl* xcert ; + + if( cert != NULL ) { + xcert = new X509Certificate_MSCryptImpl() ; + if( xcert != NULL ) { + xcert->setMswcryCert( cert ) ; + } + } else { + xcert = NULL ; + } + + return xcert ; +} + +::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException ) +{ + return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Microsoft Crypto API")); +} + +/* Native methods */ +xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) { + + unsigned int i ; + HCRYPTKEY symKey ; + HCRYPTKEY pubKey ; + HCRYPTKEY priKey ; + xmlSecKeysMngrPtr pKeysMngr = NULL ; + + /*- + * The following lines is based on the of xmlsec-mscrypto crypto engine + */ + pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ; + if( pKeysMngr == NULL ) + throw RuntimeException() ; + + /*- + * Adopt symmetric key into keys manager + */ + for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric public key into keys manager + */ + for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric private key into keys manager + */ + for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt system default certificate store. + */ + if( defaultEnabled() ) { + HCERTSTORE hSystemStore ; + + //Add system key store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "MY" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system root store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "Root" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system trusted store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "Trust" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system CA store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "CA" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + } + + return pKeysMngr ; +} +void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) { + if( pKeysMngr != NULL ) { + xmlSecKeysMngrDestroy( pKeysMngr ) ; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.hxx new file mode 100644 index 000000000000..8f0b7c7a9979 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/securityenvironment_mscryptimpl.hxx @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XSECURITYENVIRONMENT_MSCRYPTIMPL_HXX_ +#define _XSECURITYENVIRONMENT_MSCRYPTIMPL_HXX_ + +#ifdef _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <wincrypt.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase4.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> +#include <com/sun/star/security/XCertificate.hpp> +#include <com/sun/star/security/CertificateCharacters.hpp> +#include <com/sun/star/security/CertificateValidity.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> + +#include <list> +#include "xmlsec/xmlsec.h" + +class SecurityEnvironment_MSCryptImpl : public ::cppu::WeakImplHelper4< + ::com::sun::star::xml::crypto::XSecurityEnvironment , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo , + ::com::sun::star::lang::XUnoTunnel > +{ + private : + //cyrpto provider and key container + HCRYPTPROV m_hProv ; + LPCTSTR m_pszContainer ; + + //Key store + HCERTSTORE m_hKeyStore ; + + //Certiticate store + HCERTSTORE m_hCertStore ; + + //Enable default system cryptography setting + sal_Bool m_bEnableDefault ; + + //External keys + std::list< HCRYPTKEY > m_tSymKeyList ; + std::list< HCRYPTKEY > m_tPubKeyList ; + std::list< HCRYPTKEY > m_tPriKeyList ; + + //Service manager + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + SecurityEnvironment_MSCryptImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~SecurityEnvironment_MSCryptImpl() ; + + //Methods from XSecurityEnvironment + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > > SAL_CALL getPersonalCertificates() + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL getCertificate( + const ::rtl::OUString& issuerName, + const ::com::sun::star::uno::Sequence< sal_Int8 >& serialNumber ) + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL getCertificate( + const ::rtl::OUString& issuerName, + const ::rtl::OUString& serialNumber ) + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > > SAL_CALL buildCertificatePath( + const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& beginCert ) + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL createCertificateFromRaw( + const ::com::sun::star::uno::Sequence< sal_Int8 >& rawCertificate ) + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL createCertificateFromAscii( + const ::rtl::OUString& asciiCertificate ) + throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::sal_Int32 SAL_CALL verifyCertificate( + const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& xCert, + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< + ::com::sun::star::security::XCertificate > >& intermediateCertificates) + throw (::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException) ; + + virtual ::sal_Int32 SAL_CALL getCertificateCharacters( + const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& xCert ) + throw (::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException) ; + + virtual ::rtl::OUString SAL_CALL getSecurityEnvironmentInformation( ) + throw (::com::sun::star::uno::RuntimeException); + + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) + throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; + + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (::com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static SecurityEnvironment_MSCryptImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; + + //Native mehtods + virtual HCRYPTPROV getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual LPCTSTR getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual HCERTSTORE getCryptoSlot() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void setCryptoSlot( HCERTSTORE aKeyStore ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual HCERTSTORE getCertDb() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void setCertDb( HCERTSTORE aCertDb ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptSymKey( HCRYPTKEY aSymKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectSymKey( HCRYPTKEY aSymKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual HCRYPTKEY getSymKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptPubKey( HCRYPTKEY aPubKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectPubKey( HCRYPTKEY aPubKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual HCRYPTKEY getPubKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptPriKey( HCRYPTKEY aPriKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectPriKey( HCRYPTKEY aPriKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual HCRYPTKEY getPriKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void enableDefaultCrypt( sal_Bool enable ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual sal_Bool defaultEnabled() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Native mehtods + virtual xmlSecKeysMngrPtr createKeysManager() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; +} ; + +#endif // _XSECURITYENVIRONMENT_MSCRYPTIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.cxx new file mode 100644 index 000000000000..72063a140240 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.cxx @@ -0,0 +1,240 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include "seinitializer_mscryptimpl.hxx" + +#include "securityenvironment_mscryptimpl.hxx" + +#include "xmlsec/strings.h" +#include "xmlsec/mscrypto/app.h" + +namespace cssu = com::sun::star::uno; +namespace cssl = com::sun::star::lang; +namespace cssxc = com::sun::star::xml::crypto; + +#define SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer" +#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.SEInitializer_MSCryptImpl" +#define SECURITY_ENVIRONMENT "com.sun.star.xml.crypto.SecurityEnvironment" +#define SECURITY_CONTEXT "com.sun.star.xml.crypto.XMLSecurityContext" + +SEInitializer_MSCryptImpl::SEInitializer_MSCryptImpl( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF) + :mxMSF( rxMSF ) +{ +} + +SEInitializer_MSCryptImpl::~SEInitializer_MSCryptImpl() +{ +} + +/* XSEInitializer */ +cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL + SEInitializer_MSCryptImpl::createSecurityContext( + const rtl::OUString& sCertDB ) + throw (cssu::RuntimeException) +{ + const char* n_pCertStore ; + HCERTSTORE n_hStoreHandle ; + + //Initialize the crypto engine + if( sCertDB.getLength() > 0 ) + { + rtl::OString sCertDir(sCertDB, sCertDB.getLength(), RTL_TEXTENCODING_ASCII_US); + n_pCertStore = sCertDir.getStr(); + n_hStoreHandle = CertOpenSystemStore( NULL, n_pCertStore ) ; + if( n_hStoreHandle == NULL ) + { + return NULL; + } + } + else + { + n_pCertStore = NULL ; + n_hStoreHandle = NULL ; + } + + xmlSecMSCryptoAppInit( n_pCertStore ) ; + + try { + /* Build Security Environment */ + const rtl::OUString sSecyrutyEnvironment ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_ENVIRONMENT ) ); + cssu::Reference< cssxc::XSecurityEnvironment > xSecEnv( mxMSF->createInstance ( sSecyrutyEnvironment ), cssu::UNO_QUERY ); + if( !xSecEnv.is() ) + { + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + } + + xmlSecMSCryptoAppShutdown() ; + return NULL; + } + + /* Setup key slot and certDb */ + cssu::Reference< cssl::XUnoTunnel > xEnvTunnel( xSecEnv , cssu::UNO_QUERY ) ; + if( !xEnvTunnel.is() ) + { + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + } + + xmlSecMSCryptoAppShutdown() ; + return NULL; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xEnvTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + { + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + } + + xmlSecMSCryptoAppShutdown() ; + return NULL; + } + + if( n_hStoreHandle != NULL ) + { + pSecEnv->setCryptoSlot( n_hStoreHandle ) ; + pSecEnv->setCertDb( n_hStoreHandle ) ; + } + else + { + pSecEnv->enableDefaultCrypt( sal_True ) ; + } + + /* Build XML Security Context */ + const rtl::OUString sSecyrutyContext ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_CONTEXT ) ); + cssu::Reference< cssxc::XXMLSecurityContext > xSecCtx( mxMSF->createInstance ( sSecyrutyContext ), cssu::UNO_QUERY ); + if( !xSecCtx.is() ) + { + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + } + + xmlSecMSCryptoAppShutdown() ; + return NULL; + } + + xSecCtx->setDefaultSecurityEnvironmentIndex(xSecCtx->addSecurityEnvironment( xSecEnv )) ; + return xSecCtx; + } + catch( cssu::Exception& ) + { + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + } + + xmlSecMSCryptoAppShutdown() ; + return NULL; + } +} + +void SAL_CALL SEInitializer_MSCryptImpl::freeSecurityContext( const cssu::Reference< cssxc::XXMLSecurityContext >&) + throw (cssu::RuntimeException) +{ + /* + cssu::Reference< cssxc::XSecurityEnvironment > xSecEnv + = securityContext->getSecurityEnvironment(); + + if( xSecEnv.is() ) + { + cssu::Reference< cssl::XUnoTunnel > xEnvTunnel( xSecEnv , cssu::UNO_QUERY ) ; + if( xEnvTunnel.is() ) + { + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xEnvTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + HCERTSTORE n_hStoreHandle = pSecEnv->getCryptoSlot(); + + if( n_hStoreHandle != NULL ) + { + CertCloseStore( n_hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG ) ; + pSecEnv->setCryptoSlot( NULL ) ; + pSecEnv->setCertDb( NULL ) ; + } + + xmlSecMSCryptoAppShutdown() ; + } + } + */ + + xmlSecMSCryptoAppShutdown() ; +} + +rtl::OUString SEInitializer_MSCryptImpl_getImplementationName () + throw (cssu::RuntimeException) +{ + return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); +} + +sal_Bool SAL_CALL SEInitializer_MSCryptImpl_supportsService( const rtl::OUString& ServiceName ) + throw (cssu::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME )); +} + +cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_MSCryptImpl_getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + cssu::Sequence < rtl::OUString > aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); + return aRet; +} +#undef SERVICE_NAME + +cssu::Reference< cssu::XInterface > SAL_CALL SEInitializer_MSCryptImpl_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr) + throw( cssu::Exception ) +{ + return (cppu::OWeakObject*) new SEInitializer_MSCryptImpl(rSMgr); +} + +/* XServiceInfo */ +rtl::OUString SAL_CALL SEInitializer_MSCryptImpl::getImplementationName( ) + throw (cssu::RuntimeException) +{ + return SEInitializer_MSCryptImpl_getImplementationName(); +} +sal_Bool SAL_CALL SEInitializer_MSCryptImpl::supportsService( const rtl::OUString& rServiceName ) + throw (cssu::RuntimeException) +{ + return SEInitializer_MSCryptImpl_supportsService( rServiceName ); +} +cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_MSCryptImpl::getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + return SEInitializer_MSCryptImpl_getSupportedServiceNames(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.hxx new file mode 100644 index 000000000000..1553155c9e37 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/seinitializer_mscryptimpl.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _SEINITIALIZERIMPL_HXX +#define _SEINITIALIZERIMPL_HXX + +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> +#include <com/sun/star/xml/crypto/XSEInitializer.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <cppuhelper/implbase2.hxx> + +#include <libxml/tree.h> + +class SEInitializer_MSCryptImpl : public cppu::WeakImplHelper2 +< + com::sun::star::xml::crypto::XSEInitializer, + com::sun::star::lang::XServiceInfo +> +/****** SEInitializer_MSCryptImpl.hxx/CLASS SEInitializer_MSCryptImpl *********** + * + * NAME + * SEInitializer_MSCryptImpl -- Class to initialize a Security Context + * instance + * + * FUNCTION + * Use this class to initialize a XmlSec based Security Context + * instance. After this instance is used up, use this class to free this + * instance. + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ +private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > mxMSF; + +public: + SEInitializer_MSCryptImpl(const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF); + virtual ~SEInitializer_MSCryptImpl(); + + /* XSEInitializer */ + virtual com::sun::star::uno::Reference< + com::sun::star::xml::crypto::XXMLSecurityContext > + SAL_CALL createSecurityContext( const rtl::OUString& certDB ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL freeSecurityContext( const com::sun::star::uno::Reference< + com::sun::star::xml::crypto::XXMLSecurityContext >& securityContext ) + throw (com::sun::star::uno::RuntimeException); + + /* XServiceInfo */ + virtual rtl::OUString SAL_CALL getImplementationName( ) + throw (com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) + throw (com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (com::sun::star::uno::RuntimeException); +}; + +rtl::OUString SEInitializer_MSCryptImpl_getImplementationName() + throw ( com::sun::star::uno::RuntimeException ); + +sal_Bool SAL_CALL SEInitializer_MSCryptImpl_supportsService( const rtl::OUString& ServiceName ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL SEInitializer_MSCryptImpl_getSupportedServiceNames( ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Reference< com::sun::star::uno::XInterface > +SAL_CALL SEInitializer_MSCryptImpl_createInstance( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > & rSMgr) + throw ( com::sun::star::uno::Exception ); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx new file mode 100644 index 000000000000..d5ab2898ee5a --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx @@ -0,0 +1,652 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> +#include "x509certificate_mscryptimpl.hxx" +#include "certificateextension_xmlsecimpl.hxx" + +#include "oid.hxx" + +#include <rtl/locale.h> +#include <osl/nlsupport.h> +#include <osl/process.h> +#include <utility> + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::security ; +using ::rtl::OUString ; + +using ::com::sun::star::security::XCertificate ; +using ::com::sun::star::util::DateTime ; + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + +/*Resturns the index withing rRawString where sTypeName starts and where it ends. + The starting index is pair.first. The ending index in pair.second points + one char after the last character of the type. + sTypeName can be + "S" or "CN" (without ""). Do not use spaces at the beginning of the type name. + If the type name is not found then pair.first and pair.second are -1. +*/ +std::pair< sal_Int32, sal_Int32 > +findTypeInDN(const OUString& rRawString, const OUString& sTypeName) +{ + std::pair< sal_Int32, sal_Int32 > retVal; + bool bInEscape = false; + bool bInValue = false; + bool bFound = false; + sal_Int32 nTypeNameStart = 0; + sal_Int32 length = rRawString.getLength(); + + for (sal_Int32 i = 0; i < length; i++) + { + sal_Unicode c = rRawString[i]; + + if (c == '=') + { + if (! bInValue) + { + OUString sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart); + sType = sType.trim(); + if (sType.equalsIgnoreAsciiCase(sTypeName)) + { + bFound = true; + break; + } + } + } + else if (c == '"') + { + if (!bInEscape) + { + //If this is the quote is the first of the couple which enclose the + //whole value, because the value contains special characters + //then we just drop it. That is, this character must be followed by + //a character which is not '"'. + if ( i + 1 < length && rRawString[i+1] == '"') + bInEscape = true; + else + bInValue = !bInValue; //value is enclosed in " " + } + else + { + //This quote is escaped by a preceding quote and therefore is + //part of the value + bInEscape = false; + } + } + else if (c == ',' || c == '+') + { + //The comma separate the attribute value pairs. + //If the comma is not part of a value (the value would then be enclosed in '"'), + //then we have reached the end of the value + if (!bInValue) + { + //The next char is the start of the new type + nTypeNameStart = i + 1; + } + } + } + + //Found the Type Name, but there can still be spaces after the last comma + //and the beginning of the type. + if (bFound) + { + while (true) + { + sal_Unicode c = rRawString[nTypeNameStart]; + if (c != ' ' && c != '\t') + //found + break; + nTypeNameStart ++; + } + // search end (one after last letter) + sal_Int32 nTypeNameEnd = nTypeNameStart; + nTypeNameEnd++; + while (true) + { + sal_Unicode c = rRawString[nTypeNameEnd]; + if (c == ' ' || c == '\t' || c == '=') + break; + nTypeNameEnd++; + } + retVal = std::make_pair(nTypeNameStart, nTypeNameEnd); + } + else + { + retVal = std::make_pair(-1, -1); + } + return retVal; +} + + +/* + MS Crypto uses the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise + it, so the 'S' tag should be changed to 'ST' tag. However I am not sure if this is necessary + anymore, because we provide always the signers certificate when signing. So libmlsec can find + the private key based on the provided certificate (X509Certificate element) and does not need + the issuer name (X509IssuerName element). The issuer name in the xml signature has also no + effect for the signature nor the certificate validation. + In many RFCs, for example 4519, on speaks of 'ST'. However, the certificate does not contain + strings for type names. Instead it uses OIDs. + */ + +OUString replaceTagSWithTagST(OUString oldDN) +{ + std::pair<sal_Int32, sal_Int32 > pairIndex = findTypeInDN(oldDN, OUSTR("S")); + + if (pairIndex.first != -1) + { + OUString newDN = oldDN.copy(0, pairIndex.first); + newDN += OUSTR("ST"); + newDN += oldDN.copy(pairIndex.second); + return newDN; + } + return oldDN; +} +/* end */ + +X509Certificate_MSCryptImpl :: X509Certificate_MSCryptImpl() : + m_pCertContext( NULL ) +{ +} + +X509Certificate_MSCryptImpl :: ~X509Certificate_MSCryptImpl() { + if( m_pCertContext != NULL ) { + CertFreeCertificateContext( m_pCertContext ) ; + } +} + +//Methods from XCertificate +sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + return ( char )m_pCertContext->pCertInfo->dwVersion ; + } else { + return -1 ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + Sequence< sal_Int8 > serial( m_pCertContext->pCertInfo->SerialNumber.cbData ) ; + for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SerialNumber.cbData ; i ++ ) + serial[i] = *( m_pCertContext->pCertInfo->SerialNumber.pbData + m_pCertContext->pCertInfo->SerialNumber.cbData - i - 1 ) ; + + return serial ; + } else { + return Sequence< sal_Int8 >(); + } +} + +::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + char* issuer ; + DWORD cbIssuer ; + + cbIssuer = CertNameToStr( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + &( m_pCertContext->pCertInfo->Issuer ), + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , + NULL, 0 + ) ; + + // Here the cbIssuer count the last 0x00 , take care. + if( cbIssuer != 0 ) { + issuer = new char[ cbIssuer ] ; + if( issuer == NULL ) + throw RuntimeException() ; + + cbIssuer = CertNameToStr( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + &( m_pCertContext->pCertInfo->Issuer ), + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , + issuer, cbIssuer + ) ; + + if( cbIssuer <= 0 ) { + delete [] issuer ; + throw RuntimeException() ; + } + + // for correct encoding + sal_uInt16 encoding ; + rtl_Locale *pLocale = NULL ; + osl_getProcessLocale( &pLocale ) ; + encoding = osl_getTextEncodingFromLocale( pLocale ) ; + + if(issuer[cbIssuer-1] == 0) cbIssuer--; //delimit the last 0x00; + OUString xIssuer(issuer , cbIssuer ,encoding ) ; + delete [] issuer ; + + return replaceTagSWithTagST(xIssuer); + } else { + return OUString() ; + } + } else { + return OUString() ; + } +} + +::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 = 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 wchar_t[ cbSubject ] ; + if( subject == NULL ) + throw RuntimeException() ; + + cbSubject = CertNameToStrW( + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , + &( m_pCertContext->pCertInfo->Subject ), + CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , + subject, cbSubject + ) ; + + if( cbSubject <= 0 ) { + delete [] subject ; + throw RuntimeException() ; + } + + OUString xSubject(reinterpret_cast<const sal_Unicode*>(subject)); + delete [] subject ; + + return replaceTagSWithTagST(xSubject); + } else + { + return OUString() ; + } + } + else + { + return OUString() ; + } +} + +::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException ) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + SYSTEMTIME explTime ; + DateTime dateTime ; + FILETIME localFileTime; + + if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotBefore ), &localFileTime)) + { + if( FileTimeToSystemTime( &localFileTime, &explTime ) ) { + //Convert the time to readable local time + dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ; + dateTime.Seconds = explTime.wSecond ; + dateTime.Minutes = explTime.wMinute ; + dateTime.Hours = explTime.wHour ; + dateTime.Day = explTime.wDay ; + dateTime.Month = explTime.wMonth ; + dateTime.Year = explTime.wYear ; + } + } + + return dateTime ; + } else { + return DateTime() ; + } +} + +::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + SYSTEMTIME explTime ; + DateTime dateTime ; + FILETIME localFileTime; + + if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotAfter ), &localFileTime)) + { + if( FileTimeToSystemTime( &localFileTime, &explTime ) ) { + //Convert the time to readable local time + dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ; + dateTime.Seconds = explTime.wSecond ; + dateTime.Minutes = explTime.wMinute ; + dateTime.Hours = explTime.wHour ; + dateTime.Day = explTime.wDay ; + dateTime.Month = explTime.wMonth ; + dateTime.Year = explTime.wYear ; + } + } + + return dateTime ; + } else { + return DateTime() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + Sequence< sal_Int8 > issuerUid( m_pCertContext->pCertInfo->IssuerUniqueId.cbData ) ; + for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->IssuerUniqueId.cbData; i ++ ) + issuerUid[i] = *( m_pCertContext->pCertInfo->IssuerUniqueId.pbData + i ) ; + + return issuerUid ; + } else { + return Sequence< sal_Int8 >(); + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException ) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { + Sequence< sal_Int8 > subjectUid( m_pCertContext->pCertInfo->SubjectUniqueId.cbData ) ; + for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SubjectUniqueId.cbData; i ++ ) + subjectUid[i] = *( m_pCertContext->pCertInfo->SubjectUniqueId.pbData + i ) ; + + return subjectUid ; + } else { + return Sequence< sal_Int8 >(); + } +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL X509Certificate_MSCryptImpl :: getExtensions() throw ( ::com::sun::star::uno::RuntimeException ) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) { + CertificateExtension_XmlSecImpl* xExtn ; + CERT_EXTENSION* pExtn ; + Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ; + + for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) { + pExtn = &(m_pCertContext->pCertInfo->rgExtension[i]) ; + + xExtn = new CertificateExtension_XmlSecImpl() ; + if( xExtn == NULL ) + throw RuntimeException() ; + + xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ; + + xExtns[i] = xExtn ; + } + + return xExtns ; + } else { + return Sequence< Reference< XCertificateExtension > >(); + } +} + +::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL X509Certificate_MSCryptImpl :: findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& /*oid*/ ) throw (::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) { + CertificateExtension_XmlSecImpl* xExtn ; + CERT_EXTENSION* pExtn ; + Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ; + + xExtn = NULL ; + for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) { + pExtn = &( m_pCertContext->pCertInfo->rgExtension[i] ) ; + + //TODO: Compare the oid + if( 0 ) { + xExtn = new CertificateExtension_XmlSecImpl() ; + if( xExtn == NULL ) + throw RuntimeException() ; + + xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ; + } + } + + return xExtn ; + } else { + return NULL ; + } +} + + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getEncoded() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL && m_pCertContext->cbCertEncoded > 0 ) { + Sequence< sal_Int8 > rawCert( m_pCertContext->cbCertEncoded ) ; + + for( unsigned int i = 0 ; i < m_pCertContext->cbCertEncoded ; i ++ ) + rawCert[i] = *( m_pCertContext->pbCertEncoded + i ) ; + + return rawCert ; + } else { + return Sequence< sal_Int8 >(); + } +} + +//Helper methods +void X509Certificate_MSCryptImpl :: setMswcryCert( const CERT_CONTEXT* cert ) { + if( m_pCertContext != NULL ) { + CertFreeCertificateContext( m_pCertContext ) ; + m_pCertContext = NULL ; + } + + if( cert != NULL ) { + m_pCertContext = CertDuplicateCertificateContext( cert ) ; + } +} + +const CERT_CONTEXT* X509Certificate_MSCryptImpl :: getMswcryCert() const { + if( m_pCertContext != NULL ) { + return m_pCertContext ; + } else { + return NULL ; + } +} + +void X509Certificate_MSCryptImpl :: setRawCert( Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCertContext != NULL ) { + CertFreeCertificateContext( m_pCertContext ) ; + m_pCertContext = NULL ; + } + + if( rawCert.getLength() != 0 ) { + m_pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, ( const sal_uInt8* )&rawCert[0], rawCert.getLength() ) ; + } +} + +/* XUnoTunnel */ +sal_Int64 SAL_CALL X509Certificate_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw( RuntimeException ) { + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { + return ( sal_Int64 )this ; + } + return 0 ; +} + +/* XUnoTunnel extension */ +const Sequence< sal_Int8>& X509Certificate_MSCryptImpl :: getUnoTunnelId() { + static Sequence< sal_Int8 >* pSeq = 0 ; + if( !pSeq ) { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if( !pSeq ) { + static Sequence< sal_Int8> aSeq( 16 ) ; + rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; + pSeq = &aSeq ; + } + } + return *pSeq ; +} + +/* XUnoTunnel extension */ +X509Certificate_MSCryptImpl* X509Certificate_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) { + Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; + if( xUT.is() ) { + return ( X509Certificate_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ; + } else + return NULL ; +} + +::rtl::OUString findOIDDescription(char *oid) +{ + OUString ouOID = OUString::createFromAscii( oid ); + for (int i=0; i<nOID; i++) + { + OUString item = OUString::createFromAscii( OIDs[i].oid ); + if (ouOID == item) + { + return OUString::createFromAscii( OIDs[i].desc ); + } + } + + return OUString() ; +} + +::com::sun::star::uno::Sequence< sal_Int8 > getThumbprint(const CERT_CONTEXT* pCertContext, DWORD dwPropId) +{ + if( pCertContext != NULL ) + { + DWORD cbData = 20; + unsigned char fingerprint[20]; + if (CertGetCertificateContextProperty(pCertContext, dwPropId, (void*)fingerprint, &cbData)) + { + Sequence< sal_Int8 > thumbprint( cbData ) ; + for( unsigned int i = 0 ; i < cbData ; i ++ ) + { + thumbprint[i] = fingerprint[i]; + } + + return thumbprint; + } + else + { + DWORD e = GetLastError(); + cbData = e; + } + } + + return Sequence< sal_Int8 >(); +} + +::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) + { + CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm; + return findOIDDescription( algorithm.pszObjId ) ; + } + else + { + return OUString() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyValue() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) + { + CRYPT_BIT_BLOB publicKey = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey; + + Sequence< sal_Int8 > key( publicKey.cbData ) ; + for( unsigned int i = 0 ; i < publicKey.cbData ; i++ ) + { + key[i] = *(publicKey.pbData + i) ; + } + + return key; + } + else + { + return Sequence< sal_Int8 >(); + } +} + +::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSignatureAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) + { + CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SignatureAlgorithm; + return findOIDDescription( algorithm.pszObjId ) ; + } + else + { + return OUString() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSHA1Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) +{ + return getThumbprint(m_pCertContext, CERT_SHA1_HASH_PROP_ID); +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getMD5Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) +{ + return getThumbprint(m_pCertContext, CERT_MD5_HASH_PROP_ID); +} + +sal_Int32 SAL_CALL X509Certificate_MSCryptImpl::getCertificateUsage( ) + throw ( ::com::sun::star::uno::RuntimeException) +{ + sal_Int32 usage = + CERT_DATA_ENCIPHERMENT_KEY_USAGE | + CERT_DIGITAL_SIGNATURE_KEY_USAGE | + CERT_KEY_AGREEMENT_KEY_USAGE | + CERT_KEY_CERT_SIGN_KEY_USAGE | + CERT_KEY_ENCIPHERMENT_KEY_USAGE | + CERT_NON_REPUDIATION_KEY_USAGE | + CERT_OFFLINE_CRL_SIGN_KEY_USAGE; + + if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) + { + CERT_EXTENSION* pExtn = CertFindExtension( + szOID_KEY_USAGE, + m_pCertContext->pCertInfo->cExtension, + m_pCertContext->pCertInfo->rgExtension); + + if (pExtn != NULL) + { + CERT_KEY_USAGE_RESTRICTION_INFO keyUsage; + DWORD length = sizeof(CERT_KEY_USAGE_RESTRICTION_INFO); + + bool rc = CryptDecodeObject( + X509_ASN_ENCODING, + X509_KEY_USAGE, + pExtn->Value.pbData, + pExtn->Value.cbData, + CRYPT_DECODE_NOCOPY_FLAG, + (void *)&keyUsage, + &length); + + if (rc && keyUsage.RestrictedKeyUsage.cbData!=0) + { + usage = (sal_Int32)keyUsage.RestrictedKeyUsage.pbData; + } + } + } + + return usage; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx new file mode 100644 index 000000000000..4fc3a0260d15 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _X509CERTIFICATE_MSCRYPTIMPL_HXX_ +#define _X509CERTIFICATE_MSCRYPTIMPL_HXX_ + +#ifdef _MSC_VER +#pragma warning(push,1) +#endif +#include "Windows.h" +#include "WinCrypt.h" +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/uno/SecurityException.hpp> +#include <com/sun/star/security/XCertificate.hpp> + +class X509Certificate_MSCryptImpl : public ::cppu::WeakImplHelper2< + ::com::sun::star::security::XCertificate , + ::com::sun::star::lang::XUnoTunnel > +{ + private : + const CERT_CONTEXT* m_pCertContext ; + + public : + X509Certificate_MSCryptImpl() ; + virtual ~X509Certificate_MSCryptImpl() ; + + //Methods from XCertificate + virtual sal_Int16 SAL_CALL getVersion() throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::rtl::OUString SAL_CALL getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::rtl::OUString SAL_CALL getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::util::DateTime SAL_CALL getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::util::DateTime SAL_CALL getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL getExtensions() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& oid ) throw (::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getEncoded() throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::rtl::OUString SAL_CALL getSubjectPublicKeyAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSubjectPublicKeyValue() + throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::rtl::OUString SAL_CALL getSignatureAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual sal_Int32 SAL_CALL getCertificateUsage( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw (com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static X509Certificate_MSCryptImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; + + //Helper methods + void setMswcryCert( const CERT_CONTEXT* cert ) ; + const CERT_CONTEXT* getMswcryCert() const ; + void setRawCert( ::com::sun::star::uno::Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) ; +} ; + +#endif // _X509CERTIFICATE_MSCRYPTIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.cxx new file mode 100644 index 000000000000..7e04922939e2 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.cxx @@ -0,0 +1,386 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <sal/config.h> +#include <rtl/uuid.h> +#include "xmlencryption_mscryptimpl.hxx" + +#include "xmldocumentwrapper_xmlsecimpl.hxx" + +#include "xmlelementwrapper_xmlsecimpl.hxx" + +#include "securityenvironment_mscryptimpl.hxx" +#include "errorcallback.hxx" + +#include "xmlsec/xmlsec.h" +#include "xmlsec/xmltree.h" +#include "xmlsec/xmlenc.h" +#include "xmlsec/crypto.h" + +#ifdef UNX +#define stricmp strcasecmp +#endif + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; +using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLEncryption ; +using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; +using ::com::sun::star::xml::crypto::XMLEncryptionException ; + +XMLEncryption_MSCryptImpl :: XMLEncryption_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { +} + +XMLEncryption_MSCryptImpl :: ~XMLEncryption_MSCryptImpl() { +} + +/* XXMLEncryption */ +Reference< XXMLEncryptionTemplate > +SAL_CALL XMLEncryption_MSCryptImpl :: encrypt( + const Reference< XXMLEncryptionTemplate >& aTemplate , + const Reference< XSecurityEnvironment >& aEnvironment +) throw( com::sun::star::xml::crypto::XMLEncryptionException, + com::sun::star::uno::SecurityException ) +{ + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecEncCtxPtr pEncCtx = NULL ; + xmlNodePtr pEncryptedData = NULL ; + xmlNodePtr pContent = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aEnvironment.is() ) + throw RuntimeException() ; + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + //Get the encryption template + Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; + if( !xTemplate.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; + if( !xTplTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; + if( pTemplate == NULL ) { + throw RuntimeException() ; + } + + pEncryptedData = pTemplate->getNativeElement() ; + + //Find the element to be encrypted. + //This element is wrapped in the CipherValue sub-element. + xmlNodePtr pCipherData = pEncryptedData->children; + while (pCipherData != NULL && stricmp((const char *)(pCipherData->name), "CipherData")) + { + pCipherData = pCipherData->next; + } + + if( pCipherData == NULL ) { + throw XMLEncryptionException() ; + } + + xmlNodePtr pCipherValue = pCipherData->children; + while (pCipherValue != NULL && stricmp((const char *)(pCipherValue->name), "CipherValue")) + { + pCipherValue = pCipherValue->next; + } + + if( pCipherValue == NULL ) { + throw XMLEncryptionException() ; + } + + pContent = pCipherValue->children; + + if( pContent == NULL ) { + throw XMLEncryptionException() ; + } + + xmlUnlinkNode(pContent); + xmlAddNextSibling(pEncryptedData, pContent); + + //remember the position of the element to be signed + sal_Bool isParentRef = sal_True; + xmlNodePtr pParent = pEncryptedData->parent; + xmlNodePtr referenceNode; + + if (pEncryptedData == pParent->children) + { + referenceNode = pParent; + } + else + { + referenceNode = pEncryptedData->prev; + isParentRef = sal_False; + } + + setErrorRecorder( ); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Encryption context + pEncCtx = xmlSecEncCtxCreate( pMngr ) ; + if( pEncCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + + //Encrypt the template + if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) { + aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + clearErrorRecorder(); + return aTemplate; + } + aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //get the new EncryptedData element + if (isParentRef) + { + pTemplate->setNativeElement(referenceNode->children) ; + } + else + { + pTemplate->setNativeElement(referenceNode->next); + } + + clearErrorRecorder(); + return aTemplate ; +} + +/* XXMLEncryption */ +Reference< XXMLEncryptionTemplate > SAL_CALL +XMLEncryption_MSCryptImpl :: decrypt( + const Reference< XXMLEncryptionTemplate >& aTemplate , + const Reference< XXMLSecurityContext >& aSecurityCtx +) throw( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException) { + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecEncCtxPtr pEncCtx = NULL ; + xmlNodePtr pEncryptedData = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aSecurityCtx.is() ) + throw RuntimeException() ; + + //Get Keys Manager + Reference< XSecurityEnvironment > xSecEnv + = aSecurityCtx->getSecurityEnvironmentByIndex( + aSecurityCtx->getDefaultSecurityEnvironmentIndex()); + Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + //Get the encryption template + Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; + if( !xTemplate.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; + if( !xTplTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pTemplate = ( XMLElementWrapper_XmlSecImpl* )xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; + if( pTemplate == NULL ) { + throw RuntimeException() ; + } + + pEncryptedData = pTemplate->getNativeElement() ; + + //remember the position of the element to be signed + sal_Bool isParentRef = sal_True; + xmlNodePtr pParent = pEncryptedData->parent; + xmlNodePtr referenceNode; + + if (pEncryptedData == pParent->children) + { + referenceNode = pParent; + } + else + { + referenceNode = pEncryptedData->prev; + isParentRef = sal_False; + } + + setErrorRecorder( ); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Encryption context + pEncCtx = xmlSecEncCtxCreate( pMngr ) ; + if( pEncCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + + //Decrypt the template + if( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL ) { + aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + aTemplate->setStatus(::com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + /*---------------------------------------- + if( pEncCtx->resultReplaced != 0 ) { + pContent = pEncryptedData ; + + Reference< XUnoTunnel > xTunnel( ret , UNO_QUERY ) ; + if( !xTunnel.is() ) { + xmlSecEncCtxDestroy( pEncCtx ) ; + throw RuntimeException() ; + } + XMLElementWrapper_XmlSecImpl* pNode = ( XMLElementWrapper_XmlSecImpl* )xTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; + if( pNode == NULL ) { + xmlSecEncCtxDestroy( pEncCtx ) ; + throw RuntimeException() ; + } + + pNode->setNativeElement( pContent ) ; + } else { + xmlSecEncCtxDestroy( pEncCtx ) ; + throw RuntimeException() ; + } + ----------------------------------------*/ + + //Destroy the encryption context + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //get the decrypted element + XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef? + (referenceNode->children):(referenceNode->next)); + + //return ret; + aTemplate->setTemplate(ret); + + clearErrorRecorder(); + return aTemplate; +} + +/* XInitialization */ +void SAL_CALL XMLEncryption_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLEncryption_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLEncryption_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLEncryption_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLEncryption_MSCryptImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLEncryption")) ; + return seqServiceNames ; +} + +OUString XMLEncryption_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_MSCryptImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLEncryption_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLEncryption_MSCryptImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLEncryption_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + //Reference< XSingleServiceFactory > xFactory ; + //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; + //return xFactory ; + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.hxx new file mode 100644 index 000000000000..539c9afff55f --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlencryption_mscryptimpl.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLENCRYPTION_MSCRYPTIMPL_HXX_ +#define _XMLENCRYPTION_MSCRYPTIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XXMLEncryption.hpp> +#include <com/sun/star/xml/crypto/XXMLEncryptionTemplate.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + +class XMLEncryption_MSCryptImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLEncryption , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + XMLEncryption_MSCryptImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLEncryption_MSCryptImpl() ; + + //Methods from XXMLEncryption + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate > SAL_CALL encrypt( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aEnvironment) + // ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + throw ( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate > SAL_CALL decrypt( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext >& aContext + ) throw( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException) ; + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; +} ; + +#endif // _XMLENCRYPTION_MSCRYPTIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.cxx new file mode 100644 index 000000000000..c9fed3227f0b --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.cxx @@ -0,0 +1,345 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> +#include "securityenvironment_mscryptimpl.hxx" + +#include "xmlsecuritycontext_mscryptimpl.hxx" +#include "xmlstreamio.hxx" + +#include "xmlsec/xmlsec.h" +#include "xmlsec/keysmngr.h" +#include "xmlsec/crypto.h" +#include "xmlsec/mscrypto/akmngr.h" + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; + +XMLSecurityContext_MSCryptImpl :: XMLSecurityContext_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) + ://m_pKeysMngr( NULL ) , + m_xServiceManager( aFactory ), + m_xSecurityEnvironment( NULL ) +{ + //Init xmlsec library + if( xmlSecInit() < 0 ) { + throw RuntimeException() ; + } + + //Init xmlsec crypto engine library + if( xmlSecCryptoInit() < 0 ) { + xmlSecShutdown() ; + throw RuntimeException() ; + } + + //Enable external stream handlers + if( xmlEnableStreamInputCallbacks() < 0 ) { + xmlSecCryptoShutdown() ; + xmlSecShutdown() ; + throw RuntimeException() ; + } +} + +XMLSecurityContext_MSCryptImpl :: ~XMLSecurityContext_MSCryptImpl() { + xmlDisableStreamInputCallbacks() ; + xmlSecCryptoShutdown() ; + xmlSecShutdown() ; +} + +//i39448 : new methods +sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::addSecurityEnvironment( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment) + throw (::com::sun::star::security::SecurityInfrastructureException, ::com::sun::star::uno::RuntimeException) +{ + if( !aSecurityEnvironment.is() ) + { + throw RuntimeException() ; + } + + m_xSecurityEnvironment = aSecurityEnvironment; + + return 0; +} + + +sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::getSecurityEnvironmentNumber( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return 1; +} + +::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + XMLSecurityContext_MSCryptImpl::getSecurityEnvironmentByIndex( sal_Int32 index ) + throw (::com::sun::star::uno::RuntimeException) +{ + if (index == 0) + { + return m_xSecurityEnvironment; + } + else + throw RuntimeException() ; +} + +::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + XMLSecurityContext_MSCryptImpl::getSecurityEnvironment( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return m_xSecurityEnvironment; +} + +sal_Int32 SAL_CALL XMLSecurityContext_MSCryptImpl::getDefaultSecurityEnvironmentIndex( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return 0; +} + +void SAL_CALL XMLSecurityContext_MSCryptImpl::setDefaultSecurityEnvironmentIndex( sal_Int32 /*nDefaultEnvIndex*/ ) + throw (::com::sun::star::uno::RuntimeException) +{ + //dummy +} + +#if 0 +/* XXMLSecurityContext */ +void SAL_CALL XMLSecurityContext_MSCryptImpl :: setSecurityEnvironment( const Reference< XSecurityEnvironment >& aSecurityEnvironment ) throw( com::sun::star::security::SecurityInfrastructureException ) { + HCERTSTORE hkeyStore ; + HCERTSTORE hCertStore ; + HCRYPTKEY symKey ; + HCRYPTKEY pubKey ; + HCRYPTKEY priKey ; + unsigned int i ; + + if( !aSecurityEnvironment.is() ) + throw RuntimeException() ; + + m_xSecurityEnvironment = aSecurityEnvironment ; + + //Clear key manager + if( m_pKeysMngr != NULL ) { + xmlSecKeysMngrDestroy( m_pKeysMngr ) ; + m_pKeysMngr = NULL ; + } + + //Create key manager + Reference< XUnoTunnel > xEnvTunnel( m_xSecurityEnvironment , UNO_QUERY ) ; + if( !xEnvTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xEnvTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + hkeyStore = pSecEnv->getCryptoSlot() ; + hCertStore = pSecEnv->getCertDb() ; + + /*- + * The following lines is based on the of xmlsec-mscrypto crypto engine + */ + m_pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( hkeyStore , hCertStore ) ; + if( m_pKeysMngr == NULL ) + throw RuntimeException() ; + + /*- + * Adopt symmetric key into keys manager + */ + for( i = 0 ; ( symKey = pSecEnv->getSymKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( m_pKeysMngr, symKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric public key into keys manager + */ + for( i = 0 ; ( pubKey = pSecEnv->getPubKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( m_pKeysMngr, pubKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric private key into keys manager + */ + for( i = 0 ; ( priKey = pSecEnv->getPriKey( i ) ) != NULL ; i ++ ) { + if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( m_pKeysMngr, priKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt system default certificate store. + */ + if( pSecEnv->defaultEnabled() ) { + HCERTSTORE hSystemStore ; + + //Add system key store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "MY" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( m_pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system root store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "Root" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system trusted store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "Trust" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + + //Add system CA store into the keys manager. + hSystemStore = CertOpenSystemStore( 0, "CA" ) ; + if( hSystemStore != NULL ) { + if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( m_pKeysMngr, hSystemStore ) < 0 ) { + CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ; + throw RuntimeException() ; + } + } + } +} + +/* XXMLSecurityContext */ +Reference< XSecurityEnvironment > SAL_CALL XMLSecurityContext_MSCryptImpl :: getSecurityEnvironment() + throw (RuntimeException) +{ + return m_xSecurityEnvironment ; +} +#endif + +/* XInitialization */ +void SAL_CALL XMLSecurityContext_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLSecurityContext_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLSecurityContext_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLSecurityContext_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLSecurityContext_MSCryptImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLSecurityContext")) ; + return seqServiceNames ; +} + +OUString XMLSecurityContext_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_MSCryptImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLSecurityContext_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLSecurityContext_MSCryptImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLSecurityContext_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + //Reference< XSingleServiceFactory > xFactory ; + //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; + //return xFactory ; + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +#if 0 +/* XUnoTunnel */ +sal_Int64 SAL_CALL XMLSecurityContext_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) +throw (RuntimeException) +{ + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { + return ( sal_Int64 )this ; + } + return 0 ; +} + +/* XUnoTunnel extension */ +const Sequence< sal_Int8>& XMLSecurityContext_MSCryptImpl :: getUnoTunnelId() { + static Sequence< sal_Int8 >* pSeq = 0 ; + if( !pSeq ) { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if( !pSeq ) { + static Sequence< sal_Int8> aSeq( 16 ) ; + rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; + pSeq = &aSeq ; + } + } + return *pSeq ; +} + +/* XUnoTunnel extension */ +XMLSecurityContext_MSCryptImpl* XMLSecurityContext_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) { + Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; + if( xUT.is() ) { + return ( XMLSecurityContext_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ; + } else + return NULL ; +} + +/* Native methods */ +xmlSecKeysMngrPtr XMLSecurityContext_MSCryptImpl :: keysManager() throw( Exception, RuntimeException ) { + return m_pKeysMngr ; +} +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.hxx new file mode 100644 index 000000000000..dfc8217aa957 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlsecuritycontext_mscryptimpl.hxx @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLSIGNATURECONTEXT_MSCRYPTIMPL_HXX_ +#define _XMLSIGNATURECONTEXT_MSCRYPTIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + + +class XMLSecurityContext_MSCryptImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLSecurityContext , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + //xmlSecKeysMngrPtr m_pKeysMngr ; + ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > m_xSecurityEnvironment ; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + XMLSecurityContext_MSCryptImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLSecurityContext_MSCryptImpl() ; + + //Methods from XXMLSecurityContext + virtual sal_Int32 SAL_CALL addSecurityEnvironment( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment + ) throw (::com::sun::star::security::SecurityInfrastructureException, ::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getSecurityEnvironmentNumber( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + getSecurityEnvironmentByIndex( ::sal_Int32 index ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + getSecurityEnvironment( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getDefaultSecurityEnvironmentIndex( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setDefaultSecurityEnvironmentIndex( sal_Int32 nDefaultEnvIndex ) + throw (::com::sun::star::uno::RuntimeException); + +#if 0 + virtual void SAL_CALL setSecurityEnvironment( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment + ) throw( com::sun::star::security::SecurityInfrastructureException) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL getSecurityEnvironment() + throw(::com::sun::star::uno::RuntimeException); +#endif + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; + +#if 0 + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static XMLSecurityContext_MSCryptImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; +#endif + + //Native mehtods + //virtual xmlSecKeysMngrPtr keysManager() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; +} ; + +#endif // _XMLSIGNATURECONTEXT_MSCRYPTIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx new file mode 100644 index 000000000000..eb1dd5615065 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.cxx @@ -0,0 +1,312 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> + +#include "com/sun/star/xml/crypto/SecurityOperationStatus.hdl" +#include "xmlsignature_mscryptimpl.hxx" +#include "xmldocumentwrapper_xmlsecimpl.hxx" +#include "xmlelementwrapper_xmlsecimpl.hxx" +#include "securityenvironment_mscryptimpl.hxx" +#include "xmlstreamio.hxx" +#include "errorcallback.hxx" +#include "xmlsec/xmlsec.h" +#include "xmlsec/xmldsig.h" +#include "xmlsec/crypto.h" + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; +using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLSignature ; +using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; +using ::com::sun::star::xml::crypto::XUriBinding ; +using ::com::sun::star::xml::crypto::XMLSignatureException ; + + +XMLSignature_MSCryptImpl :: XMLSignature_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { +} + +XMLSignature_MSCryptImpl :: ~XMLSignature_MSCryptImpl() { +} + +/* XXMLSignature */ +Reference< XXMLSignatureTemplate > +SAL_CALL XMLSignature_MSCryptImpl :: generate( + const Reference< XXMLSignatureTemplate >& aTemplate , + const Reference< XSecurityEnvironment >& aEnvironment +) throw( com::sun::star::xml::crypto::XMLSignatureException, + com::sun::star::uno::SecurityException ) +{ + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecDSigCtxPtr pDsigCtx = NULL ; + xmlNodePtr pNode = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aEnvironment.is() ) + throw RuntimeException() ; + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + //Get the xml node + Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; + if( !xElement.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; + if( !xNodTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; + if( pElement == NULL ) { + throw RuntimeException() ; + } + + pNode = pElement->getNativeElement() ; + + //Get the stream/URI binding + Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; + if( xUriBinding.is() ) { + //Register the stream input callbacks into libxml2 + if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) + throw RuntimeException() ; + } + + setErrorRecorder( ); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Signature context + pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; + if( pDsigCtx == NULL ) + { + //throw XMLSignatureException() ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + clearErrorRecorder(); + return aTemplate; + } + + //Sign the template + if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 ) + { + if (pDsigCtx->status == xmlSecDSigStatusSucceeded) + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + else + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + else + { + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + + + xmlSecDSigCtxDestroy( pDsigCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //Unregistered the stream/URI binding + if( xUriBinding.is() ) + xmlUnregisterStreamInputCallbacks() ; + + clearErrorRecorder(); + return aTemplate ; +} + +/* XXMLSignature */ +Reference< XXMLSignatureTemplate > +SAL_CALL XMLSignature_MSCryptImpl :: validate( + const Reference< XXMLSignatureTemplate >& aTemplate , + const Reference< XXMLSecurityContext >& aSecurityCtx +) throw( com::sun::star::uno::RuntimeException, + com::sun::star::uno::SecurityException, + com::sun::star::xml::crypto::XMLSignatureException ) { + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecDSigCtxPtr pDsigCtx = NULL ; + xmlNodePtr pNode = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aSecurityCtx.is() ) + throw RuntimeException() ; + + //Get Keys Manager + Reference< XSecurityEnvironment > xSecEnv + = aSecurityCtx->getSecurityEnvironmentByIndex( + aSecurityCtx->getDefaultSecurityEnvironmentIndex()); + Reference< XUnoTunnel > xSecTunnel( xSecEnv , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_MSCryptImpl* pSecEnv = ( SecurityEnvironment_MSCryptImpl* )xSecTunnel->getSomething( SecurityEnvironment_MSCryptImpl::getUnoTunnelId() ) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + //Get the xml node + Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; + if( !xElement.is() ) + throw RuntimeException() ; + + Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; + if( !xNodTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ; + if( pElement == NULL ) + throw RuntimeException() ; + + pNode = pElement->getNativeElement() ; + + //Get the stream/URI binding + Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; + if( xUriBinding.is() ) { + //Register the stream input callbacks into libxml2 + if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) + throw RuntimeException() ; + } + + setErrorRecorder( ); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Signature context + pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; + if( pDsigCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + clearErrorRecorder(); + return aTemplate; + } + + //Verify signature + //The documentation says that the signature is only valid if the return value is 0 (that is, not < 0) + //AND pDsigCtx->status == xmlSecDSigStatusSucceeded. That is, we must not make any assumptions, if + //the return value is < 0. Then we must regard the signature as INVALID. We cannot use the + //error recorder feature to get the ONE error that made the verification fail, because there is no + //documentation/specification as to how to interpret the number of recorded errors and what is the initial + //error. + if( xmlSecDSigCtxVerify( pDsigCtx , pNode ) == 0 ) + { + if (pDsigCtx->status == xmlSecDSigStatusSucceeded) + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + else + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + else + { + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + + xmlSecDSigCtxDestroy( pDsigCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //Unregistered the stream/URI binding + if( xUriBinding.is() ) + xmlUnregisterStreamInputCallbacks() ; + + + clearErrorRecorder(); + return aTemplate; +} + +/* XInitialization */ +void SAL_CALL XMLSignature_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLSignature_MSCryptImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLSignature_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLSignature_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLSignature_MSCryptImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLSignature")) ; + return seqServiceNames ; +} + +OUString XMLSignature_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLSignature_MSCryptImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLSignature_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLSignature_MSCryptImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLSignature_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.hxx b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.hxx new file mode 100644 index 000000000000..d31050484548 --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xmlsignature_mscryptimpl.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLSIGNATURE_MSCRYPTIMPL_HXX_ +#define _XMLSIGNATURE_MSCRYPTIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XXMLSignature.hpp> +#include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + +class XMLSignature_MSCryptImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLSignature , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + XMLSignature_MSCryptImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLSignature_MSCryptImpl() ; + + //Methods from XXMLSignature + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate > SAL_CALL generate( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aEnvironment + ) throw( com::sun::star::xml::crypto::XMLSignatureException, + com::sun::star::uno::SecurityException) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate > SAL_CALL validate( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext >& aContext + ) throw( com::sun::star::uno::RuntimeException, + com::sun::star::uno::SecurityException, + com::sun::star::xml::crypto::XMLSignatureException); + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; +} ; + +#endif // _XMLSIGNATURE_MSCRYPTIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/mscrypt/xsec_mscrypt.cxx b/xmlsecurity/source/xmlsec/mscrypt/xsec_mscrypt.cxx new file mode 100644 index 000000000000..4d6dbd52d88d --- /dev/null +++ b/xmlsecurity/source/xmlsec/mscrypt/xsec_mscrypt.cxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <sal/config.h> +#include <stdio.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include "seinitializer_mscryptimpl.hxx" +#include "xmlsignature_mscryptimpl.hxx" +#include "xmlencryption_mscryptimpl.hxx" +#include "xmlsecuritycontext_mscryptimpl.hxx" +#include "securityenvironment_mscryptimpl.hxx" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +extern "C" +{ + +void* SAL_CALL mscrypt_component_getFactory( const sal_Char* pImplName , void* pServiceManager , void* /*pRegistryKey*/ ) +{ + void* pRet = 0; + Reference< XSingleServiceFactory > xFactory ; + + if( pImplName != NULL && pServiceManager != NULL ) { + if( XMLSignature_MSCryptImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLSignature_MSCryptImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( XMLSecurityContext_MSCryptImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLSecurityContext_MSCryptImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( SecurityEnvironment_MSCryptImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = SecurityEnvironment_MSCryptImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( XMLEncryption_MSCryptImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLEncryption_MSCryptImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( SEInitializer_MSCryptImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = Reference< XSingleServiceFactory >( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + SEInitializer_MSCryptImpl_createInstance, SEInitializer_MSCryptImpl_getSupportedServiceNames() ) ); + } + } + + if( xFactory.is() ) { + xFactory->acquire() ; + pRet = xFactory.get() ; + } + + return pRet ; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/certerrors.h b/xmlsecurity/source/xmlsec/nss/certerrors.h new file mode 100644 index 000000000000..d91fff52923d --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/certerrors.h @@ -0,0 +1,394 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * + * 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 occurred during cert validation."}, + +#if ( NSS_VMAJOR > 3 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR > 12 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH > 2 ) +// following 3 errors got first used in NSS 3.12.3 +// they were in the header even in 3.12.2 but there was missing the mapping in pk11err.c +// see also https://bugzilla.mozilla.org/show_bug.cgi?id=453364 + +{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."}, + +#endif + +#if ( NSS_VMAJOR > 3 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR > 12 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH > 3 ) +// following 2 errors got added in NSS 3.12.4 + +{SEC_ERROR_BAD_INFO_ACCESS_METHOD, "Unknown information access method in certificate extension."}, + +{SEC_ERROR_CRL_IMPORT_FAILED, "Error attempting to import a CRL."}, + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/makefile.mk b/xmlsecurity/source/xmlsec/nss/makefile.mk new file mode 100644 index 000000000000..de6a059573a2 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/makefile.mk @@ -0,0 +1,127 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME = xmlsecurity +TARGET = xs_nss + +ENABLE_EXCEPTIONS = TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/target.pmk + +.IF "$(SYSTEM_LIBXML)" == "YES" +CFLAGS+=-DSYSTEM_LIBXML $(LIBXML_CFLAGS) +.ENDIF + +.IF "$(CRYPTO_ENGINE)" != "nss" +LIBTARGET=NO +.ENDIF + +.IF "$(CRYPTO_ENGINE)" == "nss" + +.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 +NSS_INC = $(MOZ_INC)$/nss +NSPR_INC = $(MOZ_INC)$/nspr +.ELSE +# MOZ_INC already defined from environment +NSS_INC = $(MOZ_NSS_CFLAGS) +NSPR_INC = $(MOZ_INC)$/nspr +.ENDIF + +.IF "$(GUI)"=="UNX" +.IF "$(COMNAME)"=="sunpro5" +CFLAGS += -features=tmplife +#This flag is needed to build mozilla 1.7 code +.ENDIF # "$(COMNAME)"=="sunpro5" +.ENDIF + +.IF "$(GUI)" == "WNT" +.IF "$(DBG_LEVEL)" == "0" +INCPRE += \ +-I$(MOZ_INC)$/profile \ +-I$(MOZ_INC)$/string \ +-I$(MOZ_INC)$/embed_base +CFLAGS += -GR- -W3 -Gy -MD -UDEBUG +.ELSE +INCPRE += \ +-I$(MOZ_INC)$/profile \ +-I$(MOZ_INC)$/string \ +-I$(MOZ_INC)$/embed_base +CFLAGS += -Zi -GR- -W3 -Gy -MDd -UNDEBUG +.ENDIF +.ENDIF +.IF "$(GUI)" == "UNX" +INCPOST += \ +$(MOZ_INC)$/profile \ +-I$(MOZ_INC)$/string \ +-I$(MOZ_INC)$/embed_base +.ENDIF + +CDEFS += -DXMLSEC_CRYPTO_NSS -DXMLSEC_NO_XSLT + +# --- Files -------------------------------------------------------- + +SOLARINC += \ + -I$(MOZ_INC) \ +-I$(NSPR_INC) \ +-I$(PRJ)$/source$/xmlsec + +.IF "$(SYSTEM_MOZILLA)" == "YES" +SOLARINC += -DSYSTEM_MOZILLA $(NSS_INC) +.ELSE +SOLARINC += -I$(NSS_INC) +.ENDIF + +SLOFILES = \ + $(SLO)$/securityenvironment_nssimpl.obj \ + $(SLO)$/xmlencryption_nssimpl.obj \ + $(SLO)$/xmlsecuritycontext_nssimpl.obj \ + $(SLO)$/xmlsignature_nssimpl.obj \ + $(SLO)$/x509certificate_nssimpl.obj \ + $(SLO)$/seinitializer_nssimpl.obj \ + $(SLO)$/xsec_nss.obj \ + $(SLO)$/secerror.obj + + + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/xmlsecurity/source/xmlsec/nss/nssrenam.h b/xmlsecurity/source/xmlsec/nss/nssrenam.h new file mode 100644 index 000000000000..bc3249e1bfc4 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/nssrenam.h @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 2001 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#ifndef __nssrenam_h_ +#define __nssrenam_h_ + +#define CERT_NewTempCertificate __CERT_NewTempCertificate +#define PK11_CreateContextByRawKey __PK11_CreateContextByRawKey +#define PK11_GetKeyData __PK11_GetKeyData +#define nss_InitLock __nss_InitLock +#define CERT_ClosePermCertDB __CERT_ClosePermCertDB +#define CERT_DecodeDERCertificate __CERT_DecodeDERCertificate +#define CERT_TraversePermCertsForNickname __CERT_TraversePermCertsForNickname +#define CERT_TraversePermCertsForSubject __CERT_TraversePermCertsForSubject +#define PBE_CreateContext __PBE_CreateContext +#define PBE_DestroyContext __PBE_DestroyContext +#define PBE_GenerateBits __PBE_GenerateBits + +#endif /* __nssrenam_h_ */ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/secerror.cxx b/xmlsecurity/source/xmlsec/nss/secerror.cxx new file mode 100644 index 000000000000..34c9421bf1fb --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/secerror.cxx @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * + * 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 <sal/macros.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 = SAL_N_ELEMENTS(allDesc); + for (int i = 0; i < numDesc; i++) + { + if (allDesc[i].errNum == errNum) + return allDesc[i].errString; + } + + return sEmpty; +} + +void +printChainFailure(CERTVerifyLog *log) +{ + 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:"); + unsigned long errorFlags = 0; + 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); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/secerror.hxx b/xmlsecurity/source/xmlsec/nss/secerror.hxx new file mode 100644 index 000000000000..79878d14daaa --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/secerror.hxx @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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 + * + * 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_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx new file mode 100644 index 000000000000..a6a1af956728 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx @@ -0,0 +1,1112 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +//todo before commit: nssrenam.h is not delivered!!! +#include "nssrenam.h" +#include "cert.h" +#include "secerr.h" +#include "ocsp.h" + +#include <sal/config.h> +#include <sal/macros.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 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include <xmlsec/xmlsec.h> +#include <xmlsec/keysmngr.h> +#include <xmlsec/crypto.h> +#include <xmlsec/base64.h> +#include <xmlsec/strings.h> + +#include <tools/string.hxx> +#include <rtl/ustrbuf.hxx> +#include <comphelper/processfactory.hxx> +#include <cppuhelper/servicefactory.hxx> +#include <comphelper/docpasswordrequest.hxx> +#include <xmlsecurity/biginteger.hxx> +#include <rtl/logfile.h> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <vector> +#include "boost/scoped_array.hpp" + +#include "secerror.hxx" + +// 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 ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::security::XCertificate ; + +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() ); + if ( xMSF.is() ) + { + uno::Reference < task::XInteractionHandler > xInteractionHandler( + xMSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler")) ), uno::UNO_QUERY ); + + if ( xInteractionHandler.is() ) + { + task::PasswordRequestMode eMode = bRetry ? task::PasswordRequestMode_PASSWORD_REENTER : task::PasswordRequestMode_PASSWORD_ENTER; + ::comphelper::DocPasswordRequest* pPasswordRequest = new ::comphelper::DocPasswordRequest( + ::comphelper::DocPasswordRequestType_STANDARD, eMode, ::rtl::OUString::createFromAscii(PK11_GetTokenName(pSlot)) ); + + uno::Reference< task::XInteractionRequest > xRequest( pPasswordRequest ); + xInteractionHandler->handle( xRequest ); + + if ( pPasswordRequest->isPassword() ) + { + ByteString aPassword = ByteString( String( pPasswordRequest->getPassword() ), gsl_getSystemTextEncoding() ); + sal_uInt16 nLen = aPassword.Len(); + char* pPassword = (char*) PORT_Alloc( nLen+1 ) ; + pPassword[nLen] = 0; + memcpy( pPassword, aPassword.GetBuffer(), nLen ); + return pPassword; + } + } + } + return NULL; +} + +SecurityEnvironment_NssImpl :: SecurityEnvironment_NssImpl( const Reference< XMultiServiceFactory >& ) : +m_pHandler( NULL ) , m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList() { + + PK11_SetPasswordFunc( GetPasswordFunction ) ; +} + +SecurityEnvironment_NssImpl :: ~SecurityEnvironment_NssImpl() { + + PK11_SetPasswordFunc( NULL ) ; + + for (CIT_SLOTS i = m_Slots.begin(); i != m_Slots.end(); i++) + { + PK11_FreeSlot(*i); + } + + if( !m_tSymKeyList.empty() ) { + std::list< PK11SymKey* >::iterator symKeyIt ; + + for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; ++symKeyIt ) + PK11_FreeSymKey( *symKeyIt ) ; + } + + if( !m_tPubKeyList.empty() ) { + std::list< SECKEYPublicKey* >::iterator pubKeyIt ; + + for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; ++pubKeyIt ) + SECKEY_DestroyPublicKey( *pubKeyIt ) ; + } + + if( !m_tPriKeyList.empty() ) { + std::list< SECKEYPrivateKey* >::iterator priKeyIt ; + + for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; ++priKeyIt ) + SECKEY_DestroyPrivateKey( *priKeyIt ) ; + } +} + +/* XInitialization */ +void SAL_CALL SecurityEnvironment_NssImpl :: initialize( const Sequence< Any >& ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL SecurityEnvironment_NssImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL SecurityEnvironment_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL SecurityEnvironment_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > SecurityEnvironment_NssImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.SecurityEnvironment")) ; + return seqServiceNames ; +} + +OUString SecurityEnvironment_NssImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL SecurityEnvironment_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new SecurityEnvironment_NssImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > SecurityEnvironment_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* XUnoTunnel */ +sal_Int64 SAL_CALL SecurityEnvironment_NssImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) + throw( RuntimeException ) +{ + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); + } + return 0 ; +} + +/* XUnoTunnel extension */ +const Sequence< sal_Int8>& SecurityEnvironment_NssImpl :: getUnoTunnelId() { + static Sequence< sal_Int8 >* pSeq = 0 ; + if( !pSeq ) { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if( !pSeq ) { + static Sequence< sal_Int8> aSeq( 16 ) ; + rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; + pSeq = &aSeq ; + } + } + return *pSeq ; +} + +/* XUnoTunnel extension */ +SecurityEnvironment_NssImpl* SecurityEnvironment_NssImpl :: getImplementation( const Reference< XInterface > xObj ) { + Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; + if( xUT.is() ) { + return reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( getUnoTunnelId() ))) ; + } else + return NULL ; +} + + +::rtl::OUString SecurityEnvironment_NssImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException ) +{ + rtl::OUString result; + ::rtl::OUStringBuffer buff; + for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++) + { + buff.append(rtl::OUString::createFromAscii(PK11_GetTokenName(*is))); + buff.appendAscii("\n"); + } + return buff.makeStringAndClear(); +} + +void SecurityEnvironment_NssImpl::addCryptoSlot( PK11SlotInfo* aSlot) throw( Exception , RuntimeException ) +{ + PK11_ReferenceSlot(aSlot); + m_Slots.push_back(aSlot); +} + +CERTCertDBHandle* SecurityEnvironment_NssImpl :: getCertDb() throw( Exception , RuntimeException ) { + return m_pHandler ; +} + +//Could we have multiple cert dbs? +void SecurityEnvironment_NssImpl :: setCertDb( CERTCertDBHandle* aCertDb ) throw( Exception , RuntimeException ) { + m_pHandler = aCertDb ; +} + +void SecurityEnvironment_NssImpl :: adoptSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) { + PK11SymKey* symkey ; + std::list< PK11SymKey* >::iterator keyIt ; + + if( aSymKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) { + if( *keyIt == aSymKey ) + return ; + } + + //If we do not find the key in the list, add a new node + symkey = PK11_ReferenceSymKey( aSymKey ) ; + if( symkey == NULL ) + throw RuntimeException() ; + + try { + m_tSymKeyList.push_back( symkey ) ; + } catch ( Exception& ) { + PK11_FreeSymKey( symkey ) ; + } + } +} + +void SecurityEnvironment_NssImpl :: rejectSymKey( PK11SymKey* aSymKey ) throw( Exception , RuntimeException ) { + PK11SymKey* symkey ; + std::list< PK11SymKey* >::iterator keyIt ; + + if( aSymKey != NULL ) { + for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; ++keyIt ) { + if( *keyIt == aSymKey ) { + symkey = *keyIt ; + PK11_FreeSymKey( symkey ) ; + m_tSymKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +PK11SymKey* SecurityEnvironment_NssImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) { + PK11SymKey* symkey ; + std::list< PK11SymKey* >::iterator keyIt ; + unsigned int pos ; + + symkey = NULL ; + for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ; + + if( pos == position && keyIt != m_tSymKeyList.end() ) + symkey = *keyIt ; + + return symkey ; +} + +void SecurityEnvironment_NssImpl :: adoptPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) { + SECKEYPublicKey* pubkey ; + std::list< SECKEYPublicKey* >::iterator keyIt ; + + if( aPubKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) { + if( *keyIt == aPubKey ) + return ; + } + + //If we do not find the key in the list, add a new node + pubkey = SECKEY_CopyPublicKey( aPubKey ) ; + if( pubkey == NULL ) + throw RuntimeException() ; + + try { + m_tPubKeyList.push_back( pubkey ) ; + } catch ( Exception& ) { + SECKEY_DestroyPublicKey( pubkey ) ; + } + } +} + +void SecurityEnvironment_NssImpl :: rejectPubKey( SECKEYPublicKey* aPubKey ) throw( Exception , RuntimeException ) { + SECKEYPublicKey* pubkey ; + std::list< SECKEYPublicKey* >::iterator keyIt ; + + if( aPubKey != NULL ) { + for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; ++keyIt ) { + if( *keyIt == aPubKey ) { + pubkey = *keyIt ; + SECKEY_DestroyPublicKey( pubkey ) ; + m_tPubKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +SECKEYPublicKey* SecurityEnvironment_NssImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) { + SECKEYPublicKey* pubkey ; + std::list< SECKEYPublicKey* >::iterator keyIt ; + unsigned int pos ; + + pubkey = NULL ; + for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ; + + if( pos == position && keyIt != m_tPubKeyList.end() ) + pubkey = *keyIt ; + + return pubkey ; +} + +void SecurityEnvironment_NssImpl :: adoptPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) { + SECKEYPrivateKey* prikey ; + std::list< SECKEYPrivateKey* >::iterator keyIt ; + + if( aPriKey != NULL ) { + //First try to find the key in the list + for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) { + if( *keyIt == aPriKey ) + return ; + } + + //If we do not find the key in the list, add a new node + prikey = SECKEY_CopyPrivateKey( aPriKey ) ; + if( prikey == NULL ) + throw RuntimeException() ; + + try { + m_tPriKeyList.push_back( prikey ) ; + } catch ( Exception& ) { + SECKEY_DestroyPrivateKey( prikey ) ; + } + } +} + +void SecurityEnvironment_NssImpl :: rejectPriKey( SECKEYPrivateKey* aPriKey ) throw( Exception , RuntimeException ) { + SECKEYPrivateKey* prikey ; + std::list< SECKEYPrivateKey* >::iterator keyIt ; + + if( aPriKey != NULL ) { + for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; ++keyIt ) { + if( *keyIt == aPriKey ) { + prikey = *keyIt ; + SECKEY_DestroyPrivateKey( prikey ) ; + m_tPriKeyList.erase( keyIt ) ; + break ; + } + } + } +} + +SECKEYPrivateKey* SecurityEnvironment_NssImpl :: getPriKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) { + SECKEYPrivateKey* prikey ; + std::list< SECKEYPrivateKey* >::iterator keyIt ; + unsigned int pos ; + + prikey = NULL ; + for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ; + + if( pos == position && keyIt != m_tPriKeyList.end() ) + prikey = *keyIt ; + + return prikey ; +} + +void SecurityEnvironment_NssImpl::updateSlots() +{ + //In case new tokens are present then we can obtain the corresponding slot + PK11SlotList * soltList = NULL; + PK11SlotListElement * soltEle = NULL; + PK11SlotInfo * pSlot = NULL; + PK11SymKey * pSymKey = NULL; + + osl::MutexGuard guard(m_mutex); + + m_Slots.clear(); + m_tSymKeyList.clear(); + + soltList = PK11_GetAllTokens( CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL ) ; + if( soltList != NULL ) + { + for( soltEle = soltList->head ; soltEle != NULL; soltEle = soltEle->next ) + { + pSlot = soltEle->slot ; + + if(pSlot != NULL) + { + RTL_LOGFILE_TRACE2( "XMLSEC: Found a slot: SlotName=%s, TokenName=%s", PK11_GetSlotName(pSlot), PK11_GetTokenName(pSlot) ); + +//The following code which is commented out checks if a slot, that is a smart card for example, is +// able to generate a symmetric key of type CKM_DES3_CBC. If this fails then this token +// will not be used. This key is possibly used for the encryption service. However, all +// interfaces and services used for public key signature and encryption are not published +// and the encryption is not used in OOo. Therefore it does not do any harm to remove +// this code, hence allowing smart cards which cannot generate this type of key. +// +// By doing this, the encryption may fail if a smart card is being used which does not +// support this key generation. +// + pSymKey = PK11_KeyGen( pSlot , CKM_DES3_CBC, NULL, 128, NULL ) ; +// if( pSymKey == NULL ) +// { +// PK11_FreeSlot( pSlot ) ; +// RTL_LOGFILE_TRACE( "XMLSEC: Error - pSymKey is NULL" ); +// continue; +// } + addCryptoSlot(pSlot); + PK11_FreeSlot( pSlot ) ; + pSlot = NULL; + + if (pSymKey != NULL) + { + adoptSymKey( pSymKey ) ; + PK11_FreeSymKey( pSymKey ) ; + pSymKey = NULL; + } + + }// end of if(pSlot != NULL) + }// end of for + }// end of if( soltList != NULL ) + +} + + +Sequence< Reference < XCertificate > > +SecurityEnvironment_NssImpl::getPersonalCertificates() throw( SecurityException , RuntimeException ) +{ + sal_Int32 length ; + X509Certificate_NssImpl* xcert ; + std::list< X509Certificate_NssImpl* > certsList ; + + updateSlots(); + //firstly, we try to find private keys in slot + for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++) + { + PK11SlotInfo *slot = *is; + SECKEYPrivateKeyList* priKeyList ; + SECKEYPrivateKeyListNode* curPri ; + + if( PK11_NeedLogin(slot ) ) { + SECStatus nRet = PK11_Authenticate(slot, PR_TRUE, NULL); + //PK11_Authenticate may fail in case the a slot has not been initialized. + //this is the case if the user has a new profile, so that they have never + //added a personal certificate. + if( nRet != SECSuccess && PORT_GetError() != SEC_ERROR_IO) { + throw NoPasswordException(); + } + } + + priKeyList = PK11_ListPrivateKeysInSlot(slot) ; + if( priKeyList != NULL ) { + for( curPri = PRIVKEY_LIST_HEAD( priKeyList ); + !PRIVKEY_LIST_END( curPri, priKeyList ) && curPri != NULL ; + curPri = PRIVKEY_LIST_NEXT( curPri ) ) { + xcert = NssPrivKeyToXCert( curPri->key ) ; + if( xcert != NULL ) + certsList.push_back( xcert ) ; + } + } + + SECKEY_DestroyPrivateKeyList( priKeyList ) ; + } + + //secondly, we try to find certificate from registered private keys. + if( !m_tPriKeyList.empty() ) { + std::list< SECKEYPrivateKey* >::iterator priKeyIt ; + + for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; ++priKeyIt ) { + xcert = NssPrivKeyToXCert( *priKeyIt ) ; + if( xcert != NULL ) + certsList.push_back( xcert ) ; + } + } + + length = certsList.size() ; + if( length != 0 ) { + int i ; + std::list< X509Certificate_NssImpl* >::iterator xcertIt ; + Sequence< Reference< XCertificate > > certSeq( length ) ; + + for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); ++xcertIt, ++i ) { + certSeq[i] = *xcertIt ; + } + + return certSeq ; + } + + return Sequence< Reference < XCertificate > > (); +} + +Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) +{ + X509Certificate_NssImpl* xcert = NULL; + + if( m_pHandler != NULL ) { + CERTIssuerAndSN issuerAndSN ; + CERTCertificate* cert ; + CERTName* nmIssuer ; + char* chIssuer ; + SECItem* derIssuer ; + PRArenaPool* arena ; + + arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ) ; + if( arena == NULL ) + throw RuntimeException() ; + + // Create cert info from issue and serial + rtl::OString ostr = rtl::OUStringToOString( issuerName , RTL_TEXTENCODING_UTF8 ) ; + chIssuer = PL_strndup( ( char* )ostr.getStr(), ( int )ostr.getLength() ) ; + nmIssuer = CERT_AsciiToName( chIssuer ) ; + if( nmIssuer == NULL ) { + PL_strfree( chIssuer ) ; + PORT_FreeArena( arena, PR_FALSE ) ; + return NULL; // no need for exception cf. i40394 + } + + derIssuer = SEC_ASN1EncodeItem( arena, NULL, ( void* )nmIssuer, SEC_ASN1_GET( CERT_NameTemplate ) ) ; + if( derIssuer == NULL ) { + PL_strfree( chIssuer ) ; + CERT_DestroyName( nmIssuer ) ; + PORT_FreeArena( arena, PR_FALSE ) ; + throw RuntimeException() ; + } + + memset( &issuerAndSN, 0, sizeof( issuerAndSN ) ) ; + + issuerAndSN.derIssuer.data = derIssuer->data ; + issuerAndSN.derIssuer.len = derIssuer->len ; + + issuerAndSN.serialNumber.data = ( unsigned char* )&serialNumber[0] ; + issuerAndSN.serialNumber.len = serialNumber.getLength() ; + + cert = CERT_FindCertByIssuerAndSN( m_pHandler, &issuerAndSN ) ; + if( cert != NULL ) { + xcert = NssCertToXCert( cert ) ; + } else { + xcert = NULL ; + } + + PL_strfree( chIssuer ) ; + CERT_DestroyName( nmIssuer ) ; + //SECITEM_FreeItem( derIssuer, PR_FALSE ) ; + CERT_DestroyCertificate( cert ) ; + PORT_FreeArena( arena, PR_FALSE ) ; + } else { + xcert = NULL ; + } + + return xcert ; +} + +Reference< XCertificate > SecurityEnvironment_NssImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) { + Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ; + return getCertificate( issuerName, serial ) ; +} + +Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) { + const X509Certificate_NssImpl* xcert ; + const CERTCertificate* cert ; + CERTCertList* certChain ; + + Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ; + if( !xCertTunnel.is() ) { + throw RuntimeException() ; + } + + xcert = reinterpret_cast<X509Certificate_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ; + if( xcert == NULL ) { + throw RuntimeException() ; + } + + cert = xcert->getNssCert() ; + if( cert != NULL ) { + int64 timeboundary ; + + //Get the system clock time + timeboundary = PR_Now() ; + + certChain = CERT_GetCertChainFromCert( ( CERTCertificate* )cert, timeboundary, certUsageAnyCA ) ; + } else { + certChain = NULL ; + } + + if( certChain != NULL ) { + X509Certificate_NssImpl* pCert ; + CERTCertListNode* node ; + int len ; + + for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) ; + Sequence< Reference< XCertificate > > xCertChain( len ) ; + + for( len = 0, node = CERT_LIST_HEAD( certChain ); !CERT_LIST_END( node, certChain ); node = CERT_LIST_NEXT( node ), len ++ ) { + pCert = new X509Certificate_NssImpl() ; + if( pCert == NULL ) { + CERT_DestroyCertList( certChain ) ; + throw RuntimeException() ; + } + + pCert->setCert( node->cert ) ; + + xCertChain[len] = pCert ; + } + + CERT_DestroyCertList( certChain ) ; + + return xCertChain ; + } + + return Sequence< Reference < XCertificate > >(); +} + +Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) { + X509Certificate_NssImpl* xcert ; + + if( rawCertificate.getLength() > 0 ) { + xcert = new X509Certificate_NssImpl() ; + if( xcert == NULL ) + throw RuntimeException() ; + + xcert->setRawCert( rawCertificate ) ; + } else { + xcert = NULL ; + } + + return xcert ; +} + +Reference< XCertificate > SecurityEnvironment_NssImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) { + xmlChar* chCert ; + xmlSecSize certSize ; + + rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ; + + chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ; + + certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ; + + Sequence< sal_Int8 > rawCert( certSize ) ; + for( unsigned int i = 0 ; i < certSize ; i ++ ) + rawCert[i] = *( chCert + i ) ; + + xmlFree( chCert ) ; + + return createCertificateFromRaw( rawCert ) ; +} + +sal_Int32 SecurityEnvironment_NssImpl :: +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 = csss::CertificateValidity::INVALID; + const X509Certificate_NssImpl* xcert ; + const CERTCertificate* cert ; + ::std::vector<CERTCertificate*> vecTmpNSSCertificates; + Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; + if( !xCertTunnel.is() ) { + throw RuntimeException() ; + } + + xmlsec_trace("Start verification of certificate: \n %s \n", + OUStringToOString( + 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 + for (sal_Int32 i = 0; i < intermediateCerts.getLength(); i++) + { + Sequence<sal_Int8> der = intermediateCerts[i]->getEncoded(); + SECItem item; + item.type = siBuffer; + item.data = (unsigned char*)der.getArray(); + item.len = der.getLength(); + + CERTCertificate* certTmp = CERT_NewTempCertificate(certDb, &item, + NULL /* nickname */, + PR_FALSE /* isPerm */, + PR_TRUE /* copyDER */); + if (!certTmp) + { + xmlsec_trace("Failed to add a temporary certificate: %s", + OUStringToOString(intermediateCerts[i]->getIssuerName(), + osl_getThreadTextEncoding()).getStr()); + + } + else + { + xmlsec_trace("Added temporary certificate: %s", + certTmp->subjectName ? certTmp->subjectName : ""); + vecTmpNSSCertificates.push_back(certTmp); + } + } + + + SECStatus status ; + + CERTVerifyLog log; + log.arena = PORT_NewArena(512); + log.head = log.tail = NULL; + log.count = 0; + + CERT_EnableOCSPChecking(certDb); + CERT_DisableOCSPDefaultResponder(certDb); + CERTValOutParam cvout[5]; + CERTValInParam cvin[3]; + int ncvinCount=0; + +#if ( NSS_VMAJOR > 3 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR > 12 ) || ( NSS_VMAJOR == 3 && NSS_VMINOR == 12 && NSS_VPATCH > 0 ) + cvin[ncvinCount].type = cert_pi_useAIACertFetch; + cvin[ncvinCount].value.scalar.b = PR_TRUE; + ncvinCount++; +#endif + + 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; + + 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; + + + cvin[ncvinCount].type = cert_pi_revocationFlags; + cvin[ncvinCount].value.pointer.revocation = &rev; + ncvinCount++; + // does not work, not implemented yet in 3.12.4 +// cvin[ncvinCount].type = cert_pi_keyusage; +// cvin[ncvinCount].value.scalar.ui = KU_DIGITAL_SIGNATURE; +// ncvinCount++; + cvin[ncvinCount].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; + + // 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[] = + { + {certificateUsageSSLClient, "certificateUsageSSLClient" }, + {certificateUsageSSLServer, "certificateUsageSSLServer" }, + {certificateUsageSSLCA, "certificateUsageSSLCA" }, + {certificateUsageEmailSigner, "certificateUsageEmailSigner"}, //only usable for end certs + {certificateUsageEmailRecipient, "certificateUsageEmailRecipient"} + }; + + int numUsages = SAL_N_ELEMENTS(arUsages); + for (int i = 0; i < numUsages; i++) + { + xmlsec_trace("Testing usage %d of %d: %s (0x%x)", i + 1, + numUsages, arUsages[i].description, (int) arUsages[i].usage); + + 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 + { + 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"); + } + } + + } + else + { + validity = ::com::sun::star::security::CertificateValidity::INVALID ; + } + + //Destroying the temporary certificates + std::vector<CERTCertificate*>::const_iterator cert_i; + for (cert_i = vecTmpNSSCertificates.begin(); cert_i != vecTmpNSSCertificates.end(); ++cert_i) + { + xmlsec_trace("Destroying temporary certificate"); + CERT_DestroyCertificate(*cert_i); + } + return validity ; +} + +sal_Int32 SecurityEnvironment_NssImpl::getCertificateCharacters( + const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) { + sal_Int32 characters ; + const X509Certificate_NssImpl* xcert ; + const CERTCertificate* cert ; + + Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ; + if( !xCertTunnel.is() ) { + throw RuntimeException() ; + } + + xcert = reinterpret_cast<X509Certificate_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>(xCertTunnel->getSomething( X509Certificate_NssImpl::getUnoTunnelId() ))) ; + if( xcert == NULL ) { + throw RuntimeException() ; + } + + cert = xcert->getNssCert() ; + + characters = 0x00000000 ; + + //Firstly, find out whether or not the cert is self-signed. + if( SECITEM_CompareItem( &(cert->derIssuer), &(cert->derSubject) ) == SECEqual ) { + characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; + } else { + characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ; + } + + //Secondly, find out whether or not the cert has a private key. + + /* + * i40394 + * + * mmi : need to check whether the cert's slot is valid first + */ + SECKEYPrivateKey* priKey = NULL; + + if (cert->slot != NULL) + { + priKey = PK11_FindPrivateKeyFromCert( cert->slot, ( CERTCertificate* )cert, NULL ) ; + } + if(priKey == NULL) + { + for (CIT_SLOTS is = m_Slots.begin(); is != m_Slots.end(); is++) + { + priKey = PK11_FindPrivateKeyFromCert(*is, (CERTCertificate*)cert, NULL); + if (priKey) + break; + } + } + if( priKey != NULL ) { + characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; + + SECKEY_DestroyPrivateKey( priKey ) ; + } else { + characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ; + } + + return characters ; +} + +X509Certificate_NssImpl* NssCertToXCert( CERTCertificate* cert ) +{ + X509Certificate_NssImpl* xcert ; + + if( cert != NULL ) { + xcert = new X509Certificate_NssImpl() ; + if( xcert == NULL ) { + xcert = NULL ; + } else { + xcert->setCert( cert ) ; + } + } else { + xcert = NULL ; + } + + return xcert ; +} + +X509Certificate_NssImpl* NssPrivKeyToXCert( SECKEYPrivateKey* priKey ) +{ + CERTCertificate* cert ; + X509Certificate_NssImpl* xcert ; + + if( priKey != NULL ) { + cert = PK11_GetCertFromPrivateKey( priKey ) ; + + if( cert != NULL ) { + xcert = NssCertToXCert( cert ) ; + } else { + xcert = NULL ; + } + + CERT_DestroyCertificate( cert ) ; + } else { + xcert = NULL ; + } + + return xcert ; +} + + +/* Native methods */ +xmlSecKeysMngrPtr SecurityEnvironment_NssImpl::createKeysManager() throw( Exception, RuntimeException ) { + + unsigned int i ; + CERTCertDBHandle* handler = NULL ; + PK11SymKey* symKey = NULL ; + SECKEYPublicKey* pubKey = NULL ; + SECKEYPrivateKey* priKey = NULL ; + xmlSecKeysMngrPtr pKeysMngr = NULL ; + + handler = this->getCertDb() ; + + /*- + * The following lines is based on the private version of xmlSec-NSS + * crypto engine + */ + int cSlots = m_Slots.size(); + boost::scoped_array<PK11SlotInfo*> sarSlots(new PK11SlotInfo*[cSlots]); + PK11SlotInfo** slots = sarSlots.get(); + int count = 0; + for (CIT_SLOTS islots = m_Slots.begin();islots != m_Slots.end(); islots++, count++) + slots[count] = *islots; + + pKeysMngr = xmlSecNssAppliedKeysMngrCreate(slots, cSlots, handler ) ; + if( pKeysMngr == NULL ) + throw RuntimeException() ; + + /*- + * Adopt symmetric key into keys manager + */ + for( i = 0 ; ( symKey = this->getSymKey( i ) ) != NULL ; i ++ ) { + if( xmlSecNssAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric public key into keys manager + */ + for( i = 0 ; ( pubKey = this->getPubKey( i ) ) != NULL ; i ++ ) { + if( xmlSecNssAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) { + throw RuntimeException() ; + } + } + + /*- + * Adopt asymmetric private key into keys manager + */ + for( i = 0 ; ( priKey = this->getPriKey( i ) ) != NULL ; i ++ ) { + if( xmlSecNssAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) { + throw RuntimeException() ; + } + } + return pKeysMngr ; +} +void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) { + if( pKeysMngr != NULL ) { + xmlSecKeysMngrDestroy( pKeysMngr ) ; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx new file mode 100644 index 000000000000..3488692e023e --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx @@ -0,0 +1,171 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XSECURITYENVIRONMENT_NSSIMPL_HXX_ +#define _XSECURITYENVIRONMENT_NSSIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase4.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> +#include <com/sun/star/security/XCertificate.hpp> +#include <com/sun/star/security/CertificateCharacters.hpp> +#include <com/sun/star/security/CertificateValidity.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> + +#include "osl/mutex.hxx" + +#include "pk11func.h" +#include "keyhi.h" +#include "certdb.h" +#include "list" + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include "xmlsec/xmlsec.h" + +class SecurityEnvironment_NssImpl : public ::cppu::WeakImplHelper4< + ::com::sun::star::xml::crypto::XSecurityEnvironment , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo , + ::com::sun::star::lang::XUnoTunnel > +{ +private : + + std::list< PK11SlotInfo* > m_Slots; + typedef std::list< PK11SlotInfo* >::const_iterator CIT_SLOTS; + + osl::Mutex m_mutex; + + CERTCertDBHandle* m_pHandler ; + std::list< PK11SymKey* > m_tSymKeyList ; + std::list< SECKEYPublicKey* > m_tPubKeyList ; + std::list< SECKEYPrivateKey* > m_tPriKeyList ; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + SecurityEnvironment_NssImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~SecurityEnvironment_NssImpl() ; + + //Methods from XSecurityEnvironment + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; + + virtual ::sal_Int32 SAL_CALL verifyCertificate( + const ::com::sun::star::uno::Reference< + ::com::sun::star::security::XCertificate >& xCert, + const ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > > & + intermediateCerts) + throw (::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException) ; + + virtual ::sal_Int32 SAL_CALL getCertificateCharacters( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& xCert ) throw (::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException) ; + + virtual ::rtl::OUString SAL_CALL getSecurityEnvironmentInformation( ) throw (::com::sun::star::uno::RuntimeException); + + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (::com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static SecurityEnvironment_NssImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; + + //Native mehtods + virtual CERTCertDBHandle* getCertDb() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void setCertDb( CERTCertDBHandle* aCertDb ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptSymKey( PK11SymKey* aSymKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectSymKey( PK11SymKey* aSymKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual PK11SymKey* getSymKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptPubKey( SECKEYPublicKey* aPubKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectPubKey( SECKEYPublicKey* aPubKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual SECKEYPublicKey* getPubKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual void adoptPriKey( SECKEYPrivateKey* aPriKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void rejectPriKey( SECKEYPrivateKey* aPriKey ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual SECKEYPrivateKey* getPriKey( unsigned int position ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > > SAL_CALL getPersonalCertificates() throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL getCertificate( const ::rtl::OUString& issuerName, const ::com::sun::star::uno::Sequence< sal_Int8 >& serialNumber ) throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL getCertificate( const ::rtl::OUString& issuerName, const ::rtl::OUString& serialNumber ) throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > > SAL_CALL buildCertificatePath( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& beginCert ) throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL createCertificateFromRaw( const ::com::sun::star::uno::Sequence< sal_Int8 >& rawCertificate ) throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL createCertificateFromAscii( const ::rtl::OUString& asciiCertificate ) throw( ::com::sun::star::uno::SecurityException , ::com::sun::star::uno::RuntimeException ) ; + + + //Native mehtods + virtual xmlSecKeysMngrPtr createKeysManager() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + virtual void destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + +private: + void updateSlots(); + + virtual void addCryptoSlot( PK11SlotInfo* aSlot ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; +} ; + +#endif // _XSECURITYENVIRONMENT_NSSIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx new file mode 100644 index 000000000000..5bb2a9ecb567 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.cxx @@ -0,0 +1,516 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +/* + * Turn off DEBUG Assertions + */ +#ifdef _DEBUG + #define _DEBUG_WAS_DEFINED _DEBUG + #undef _DEBUG +#else + #undef _DEBUG_WAS_DEFINED +#endif + +/* + * and turn off the additional virtual methods which are part of some interfaces when compiled + * with debug + */ +#ifdef DEBUG + #define DEBUG_WAS_DEFINED DEBUG + #undef DEBUG +#else + #undef DEBUG_WAS_DEFINED +#endif + + +#include <sal/types.h> +#include "rtl/instance.hxx" +#include "rtl/bootstrap.hxx" +#include "rtl/string.hxx" +#include "rtl/strbuf.hxx" +#include "osl/file.hxx" +#include "osl/thread.h" +#include <tools/debug.hxx> +#include <rtl/logfile.hxx> + +#include "seinitializer_nssimpl.hxx" +#include "../diagnose.hxx" + +#include "securityenvironment_nssimpl.hxx" +#include <com/sun/star/mozilla/XMozillaBootstrap.hpp> + +#include "nspr.h" +#include "cert.h" +#include "nss.h" +#include "secmod.h" +#include "nssckbi.h" + + +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; + +#define SERVICE_NAME "com.sun.star.xml.crypto.SEInitializer" +#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.SEInitializer_NssImpl" +#define SECURITY_ENVIRONMENT "com.sun.star.xml.crypto.SecurityEnvironment" +#define SECURITY_CONTEXT "com.sun.star.xml.crypto.XMLSecurityContext" + + +#define ROOT_CERTS "Root Certs for OpenOffice.org" + + +extern "C" void nsscrypto_finalize(); + + +namespace +{ + +bool nsscrypto_initialize( const char * sProfile, bool & out_nss_init); + +struct InitNSSInitialize +{ + //path to the database folder + const OString m_sProfile; + InitNSSInitialize(const OString & sProfile): m_sProfile(sProfile) {}; + bool * operator()() + { + static bool bInitialized = false; + bool bNSSInit = false; + bInitialized = nsscrypto_initialize(m_sProfile.getStr(), bNSSInit); + if (bNSSInit) + atexit(nsscrypto_finalize ); + return & bInitialized; + + } +}; + +bool * initNSS(const OString & sProfile) +{ + return rtl_Instance< bool, InitNSSInitialize, + ::osl::MutexGuard, ::osl::GetGlobalMutex >::create( + InitNSSInitialize(sProfile), ::osl::GetGlobalMutex()); +} + +void deleteRootsModule() +{ + SECMODModule *RootsModule = 0; + SECMODModuleList *list = SECMOD_GetDefaultModuleList(); + SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); + SECMOD_GetReadLock(lock); + + while (!RootsModule && list) + { + SECMODModule *module = list->module; + + for (int i=0; i < module->slotCount; i++) + { + PK11SlotInfo *slot = module->slots[i]; + if (PK11_IsPresent(slot)) + { + if (PK11_HasRootCerts(slot)) + { + xmlsec_trace("The root certifificates module \"%s" + "\" is already loaded: \n%s", + module->commonName, module->dllName); + + RootsModule = SECMOD_ReferenceModule(module); + break; + } + } + } + list = list->next; + } + SECMOD_ReleaseReadLock(lock); + + if (RootsModule) + { + PRInt32 modType; + if (SECSuccess == SECMOD_DeleteModule(RootsModule->commonName, &modType)) + { + xmlsec_trace("Deleted module \"%s\".", RootsModule->commonName); + } + else + { + xmlsec_trace("Failed to delete \"%s\" : \n%s", + RootsModule->commonName, RootsModule->dllName); + } + SECMOD_DestroyModule(RootsModule); + RootsModule = 0; + } +} + +//Older versions of Firefox (FF), for example FF2, and Thunderbird (TB) 2 write +//the roots certificate module (libnssckbi.so), which they use, into the +//profile. This module will then already be loaded during NSS_Init (and the +//other init functions). This fails in two cases. First, FF3 was used to create +//the profile, or possibly used that profile before, and second the profile was +//used on a different platform. +// +//Then one needs to add the roots module oneself. This should be done with +//SECMOD_LoadUserModule rather then SECMOD_AddNewModule. The latter would write +//the location of the roots module to the profile, which makes FF2 and TB2 use +//it instead of there own module. +// +//When using SYSTEM_MOZILLA then the libnss3.so lib is typically found in +///usr/lib. This folder may, however, NOT contain the roots certificate +//module. That is, just providing the library name in SECMOD_LoadUserModule or +//SECMOD_AddNewModule will FAIL to load the mozilla unless the LD_LIBRARY_PATH +//contains an FF or TB installation. +//ATTENTION: DO NOT call this function directly instead use initNSS +//return true - whole initialization was successful +//param out_nss_init = true: at least the NSS initialization (NSS_InitReadWrite +//was successful and therefor NSS_Shutdown should be called when terminating. +bool nsscrypto_initialize( const char* token, bool & out_nss_init ) +{ + bool return_value = true; + + xmlsec_trace("Using profile: %s", token); + + PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 1 ) ; + + //token may be an empty string + if (token != NULL && strlen(token) > 0) + { + 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; + +#if defined SYSTEM_MOZILLA + if (!SECMOD_HasRootCerts()) + { +#endif + deleteRootsModule(); + +#if defined SYSTEM_MOZILLA + OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("libnssckbi"SAL_DLLEXTENSION)); +#else + OUString rootModule(RTL_CONSTASCII_USTRINGPARAM("${OOO_BASE_DIR}/program/libnssckbi"SAL_DLLEXTENSION)); +#endif + ::rtl::Bootstrap::expandMacros(rootModule); + + OUString rootModulePath; + if (::osl::File::E_None == ::osl::File::getSystemPathFromFileURL(rootModule, rootModulePath)) + { + ::rtl::OString ospath = ::rtl::OUStringToOString(rootModulePath, osl_getThreadTextEncoding()); + ::rtl::OStringBuffer pkcs11moduleSpec; + pkcs11moduleSpec.append("name=\""); + pkcs11moduleSpec.append(ROOT_CERTS); + pkcs11moduleSpec.append("\" library=\""); + pkcs11moduleSpec.append(ospath.getStr()); + pkcs11moduleSpec.append("\""); + + SECMODModule * RootsModule = + SECMOD_LoadUserModule( + const_cast<char*>(pkcs11moduleSpec.makeStringAndClear().getStr()), + 0, // no parent + PR_FALSE); // do not recurse + + if (RootsModule) + { + + bool found = RootsModule->loaded; + + SECMOD_DestroyModule(RootsModule); + RootsModule = 0; + if (found) + xmlsec_trace("Added new root certificate module " + "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); + else + { + xmlsec_trace("FAILED to load the new root certificate module " + "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); + return_value = false; + } + } + else + { + xmlsec_trace("FAILED to add new root certifice module: " + "\""ROOT_CERTS"\" contained in \n%s", ospath.getStr()); + return_value = false; + + } + } + else + { + xmlsec_trace("Adding new root certificate module failed."); + return_value = false; + } +#if SYSTEM_MOZILLA + } +#endif + + return return_value; +} + + +// must be extern "C" because we pass the function pointer to atexit +extern "C" void nsscrypto_finalize() +{ + SECMODModule *RootsModule = SECMOD_FindModule(ROOT_CERTS); + + if (RootsModule) + { + + if (SECSuccess == SECMOD_UnloadUserModule(RootsModule)) + { + xmlsec_trace("Unloaded module \""ROOT_CERTS"\"."); + } + else + { + xmlsec_trace("Failed unloadeding module \""ROOT_CERTS"\"."); + } + SECMOD_DestroyModule(RootsModule); + } + else + { + xmlsec_trace("Unloading module \""ROOT_CERTS + "\" failed because it was not found."); + } + PK11_LogoutAll(); + NSS_Shutdown(); +} + + +bool getMozillaCurrentProfile( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF, + rtl::OUString& profilePath) +{ + /* + * 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 + { + mozilla::MozillaProductType productTypes[4] = { + mozilla::MozillaProductType_Thunderbird, + mozilla::MozillaProductType_Mozilla, + mozilla::MozillaProductType_Firefox, + mozilla::MozillaProductType_Default }; + + 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" ); + + uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap + = uno::Reference<mozilla::XMozillaBootstrap>(xInstance,uno::UNO_QUERY); + OSL_ENSURE( xMozillaBootstrap.is(), "failed to create instance" ); + + if (xMozillaBootstrap.is()) + { + int nProduct = 4; + for (int i=0; i<nProduct; i++) + { + ::rtl::OUString profile = xMozillaBootstrap->getDefaultProfile(productTypes[i]); + + if (profile != NULL && profile.getLength()>0) + { + profilePath = xMozillaBootstrap->getProfilePath(productTypes[i],profile); + RTL_LOGFILE_PRODUCT_TRACE1( "XMLSEC: Using Mozilla Profile: %s", rtl::OUStringToOString( profilePath, RTL_TEXTENCODING_ASCII_US ).getStr() ); + return true; + } + } + } + + RTL_LOGFILE_PRODUCT_TRACE( "XMLSEC: No Mozilla Profile found!" ); + return false; + } +} + +} // namespace + +SEInitializer_NssImpl::SEInitializer_NssImpl( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF) + :mxMSF( rxMSF ) +{ +} + +SEInitializer_NssImpl::~SEInitializer_NssImpl() +{ +} + +/* XSEInitializer */ +cssu::Reference< cssxc::XXMLSecurityContext > SAL_CALL + SEInitializer_NssImpl::createSecurityContext( + const rtl::OUString& sCertDB ) + throw (cssu::RuntimeException) +{ + CERTCertDBHandle *pCertHandle = NULL ; + + rtl::OString sCertDir; + if( sCertDB.getLength() ) + { + sCertDir = rtl::OUStringToOString(sCertDB, RTL_TEXTENCODING_ASCII_US); + } + else + { + static rtl::OString* pDefaultCertDir = NULL; + if ( !pDefaultCertDir ) + { + pDefaultCertDir = new rtl::OString; + rtl::OUString ouCertDir; + + if ( getMozillaCurrentProfile(mxMSF, ouCertDir) ) + *pDefaultCertDir = rtl::OUStringToOString(ouCertDir, RTL_TEXTENCODING_ASCII_US); + } + sCertDir = *pDefaultCertDir; + + } + + if( ! *initNSS( sCertDir.getStr() ) ) + { + return NULL; + } + + pCertHandle = CERT_GetDefaultCertDB() ; + + try + { + /* Build XML Security Context */ + const rtl::OUString sSecyrutyContext ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_CONTEXT ) ); + cssu::Reference< cssxc::XXMLSecurityContext > xSecCtx( mxMSF->createInstance ( sSecyrutyContext ), cssu::UNO_QUERY ); + if( !xSecCtx.is() ) + return NULL; + + const rtl::OUString sSecyrutyEnvironment ( RTL_CONSTASCII_USTRINGPARAM( SECURITY_ENVIRONMENT ) ); + cssu::Reference< cssxc::XSecurityEnvironment > xSecEnv( mxMSF->createInstance ( sSecyrutyEnvironment ), cssu::UNO_QUERY ); + cssu::Reference< cssl::XUnoTunnel > xEnvTunnel( xSecEnv , cssu::UNO_QUERY ) ; + if( !xEnvTunnel.is() ) + return NULL; + SecurityEnvironment_NssImpl* pSecEnv = reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xEnvTunnel->getSomething(SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ; + pSecEnv->setCertDb(pCertHandle); + + sal_Int32 n = xSecCtx->addSecurityEnvironment(xSecEnv); + //originally the SecurityEnvironment with the internal slot was set as default + xSecCtx->setDefaultSecurityEnvironmentIndex( n ); + return xSecCtx; + } + catch( cssu::Exception& ) + { + //PK11_LogoutAll(); + //NSS_Shutdown(); + return NULL; + } +} + +void SAL_CALL SEInitializer_NssImpl::freeSecurityContext( const cssu::Reference< cssxc::XXMLSecurityContext >& ) + throw (cssu::RuntimeException) +{ + /* + * because the security context will free all its content when it + * is destructed, so here no free process for the security context + * is needed. + */ + //PK11_LogoutAll(); + //NSS_Shutdown(); +} + +rtl::OUString SEInitializer_NssImpl_getImplementationName () + throw (cssu::RuntimeException) +{ + + return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); +} + +sal_Bool SAL_CALL SEInitializer_NssImpl_supportsService( const rtl::OUString& ServiceName ) + throw (cssu::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME )); +} + +cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl_getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + cssu::Sequence < rtl::OUString > aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); + return aRet; +} +#undef SERVICE_NAME + +cssu::Reference< cssu::XInterface > SAL_CALL SEInitializer_NssImpl_createInstance( const cssu::Reference< cssl::XMultiServiceFactory > & rSMgr) + throw( cssu::Exception ) +{ + return (cppu::OWeakObject*) new SEInitializer_NssImpl(rSMgr); +} + +/* XServiceInfo */ +rtl::OUString SAL_CALL SEInitializer_NssImpl::getImplementationName( ) + throw (cssu::RuntimeException) +{ + return SEInitializer_NssImpl_getImplementationName(); +} +sal_Bool SAL_CALL SEInitializer_NssImpl::supportsService( const rtl::OUString& rServiceName ) + throw (cssu::RuntimeException) +{ + return SEInitializer_NssImpl_supportsService( rServiceName ); +} +cssu::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl::getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + return SEInitializer_NssImpl_getSupportedServiceNames(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx new file mode 100644 index 000000000000..6012a0317c5b --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/seinitializer_nssimpl.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _SEINITIALIZERIMPL_HXX +#define _SEINITIALIZERIMPL_HXX + +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> +#include <com/sun/star/xml/crypto/XSEInitializer.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <cppuhelper/implbase2.hxx> + +#include <libxml/tree.h> + +class SEInitializer_NssImpl : public cppu::WeakImplHelper2 +< + com::sun::star::xml::crypto::XSEInitializer, + com::sun::star::lang::XServiceInfo +> +/****** SEInitializer_NssImpl.hxx/CLASS SEInitializer_NssImpl *********** + * + * NAME + * SEInitializer_NssImpl -- Class to initialize a Security Context + * instance + * + * FUNCTION + * Use this class to initialize a XmlSec based Security Context + * instance. After this instance is used up, use this class to free this + * instance. + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ +private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > mxMSF; + +public: + SEInitializer_NssImpl(const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > &rxMSF); + virtual ~SEInitializer_NssImpl(); + + /* XSEInitializer */ + virtual com::sun::star::uno::Reference< + com::sun::star::xml::crypto::XXMLSecurityContext > + SAL_CALL createSecurityContext( const rtl::OUString& certDB ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL freeSecurityContext( const com::sun::star::uno::Reference< + com::sun::star::xml::crypto::XXMLSecurityContext >& securityContext ) + throw (com::sun::star::uno::RuntimeException); + + /* XServiceInfo */ + virtual rtl::OUString SAL_CALL getImplementationName( ) + throw (com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) + throw (com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (com::sun::star::uno::RuntimeException); +}; + +rtl::OUString SEInitializer_NssImpl_getImplementationName() + throw ( com::sun::star::uno::RuntimeException ); + +sal_Bool SAL_CALL SEInitializer_NssImpl_supportsService( const rtl::OUString& ServiceName ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL SEInitializer_NssImpl_getSupportedServiceNames( ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Reference< com::sun::star::uno::XInterface > +SAL_CALL SEInitializer_NssImpl_createInstance( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > & rSMgr) + throw ( com::sun::star::uno::Exception ); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx new file mode 100644 index 000000000000..3fe691f4acda --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx @@ -0,0 +1,456 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + + + +#include "nssrenam.h" +#include "nspr.h" +#include "nss.h" +#include "secder.h" + +#include "hasht.h" +#include "secoid.h" +#include "pk11func.h" + +#include <sal/config.h> +#include <rtl/uuid.h> +#include "x509certificate_nssimpl.hxx" + +#include "certificateextension_xmlsecimpl.hxx" + + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::security ; +using ::rtl::OUString ; + +using ::com::sun::star::security::XCertificate ; +using ::com::sun::star::util::DateTime ; + +X509Certificate_NssImpl :: X509Certificate_NssImpl() : + m_pCert( NULL ) +{ +} + +X509Certificate_NssImpl :: ~X509Certificate_NssImpl() { + if( m_pCert != NULL ) { + CERT_DestroyCertificate( m_pCert ) ; + } +} + +//Methods from XCertificate +sal_Int16 SAL_CALL X509Certificate_NssImpl :: getVersion() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL ) { + if( m_pCert->version.len > 0 ) { + return ( char )*( m_pCert->version.data ) ; + } else + return 0 ; + } else { + return -1 ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->serialNumber.len > 0 ) { + Sequence< sal_Int8 > serial( m_pCert->serialNumber.len ) ; + for( unsigned int i = 0 ; i < m_pCert->serialNumber.len ; i ++ ) + serial[i] = *( m_pCert->serialNumber.data + i ) ; + + return serial ; + } else { + return ::com::sun::star::uno::Sequence< sal_Int8 >(); + } +} + +::rtl::OUString SAL_CALL X509Certificate_NssImpl :: getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL ) { + return OUString(m_pCert->issuerName , PL_strlen(m_pCert->issuerName) , RTL_TEXTENCODING_UTF8) ; + } else { + return OUString() ; + } +} + +::rtl::OUString SAL_CALL X509Certificate_NssImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL ) { + return OUString(m_pCert->subjectName , PL_strlen(m_pCert->subjectName) , RTL_TEXTENCODING_UTF8); + } else { + return OUString() ; + } +} + +::com::sun::star::util::DateTime SAL_CALL X509Certificate_NssImpl :: getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL ) { + SECStatus rv ; + PRTime notBefore ; + PRExplodedTime explTime ; + DateTime dateTime ; + + rv = DER_DecodeTimeChoice( ¬Before, &m_pCert->validity.notBefore ) ; + if( rv ) { + return DateTime() ; + } + + //Convert the time to readable local time + PR_ExplodeTime( notBefore, PR_LocalTimeParameters, &explTime ) ; + + dateTime.HundredthSeconds = explTime.tm_usec / 1000 ; + dateTime.Seconds = explTime.tm_sec ; + dateTime.Minutes = explTime.tm_min ; + dateTime.Hours = explTime.tm_hour ; + dateTime.Day = explTime.tm_mday ; + dateTime.Month = explTime.tm_month+1 ; + dateTime.Year = explTime.tm_year ; + + return dateTime ; + } else { + return DateTime() ; + } +} + +::com::sun::star::util::DateTime SAL_CALL X509Certificate_NssImpl :: getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL ) { + SECStatus rv ; + PRTime notAfter ; + PRExplodedTime explTime ; + DateTime dateTime ; + + rv = DER_DecodeTimeChoice( ¬After, &m_pCert->validity.notAfter ) ; + if( rv ) { + return DateTime() ; + } + + //Convert the time to readable local time + PR_ExplodeTime( notAfter, PR_LocalTimeParameters, &explTime ) ; + + dateTime.HundredthSeconds = explTime.tm_usec / 1000 ; + dateTime.Seconds = explTime.tm_sec ; + dateTime.Minutes = explTime.tm_min ; + dateTime.Hours = explTime.tm_hour ; + dateTime.Day = explTime.tm_mday ; + dateTime.Month = explTime.tm_month+1 ; + dateTime.Year = explTime.tm_year ; + + return dateTime ; + } else { + return DateTime() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->issuerID.len > 0 ) { + Sequence< sal_Int8 > issuerUid( m_pCert->issuerID.len ) ; + for( unsigned int i = 0 ; i < m_pCert->issuerID.len ; i ++ ) + issuerUid[i] = *( m_pCert->issuerID.data + i ) ; + + return issuerUid ; + } else { + return ::com::sun::star::uno::Sequence< sal_Int8 >(); + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->subjectID.len > 0 ) { + Sequence< sal_Int8 > subjectUid( m_pCert->subjectID.len ) ; + for( unsigned int i = 0 ; i < m_pCert->subjectID.len ; i ++ ) + subjectUid[i] = *( m_pCert->subjectID.data + i ) ; + + return subjectUid ; + } else { + return ::com::sun::star::uno::Sequence< sal_Int8 >(); + } +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL X509Certificate_NssImpl :: getExtensions() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->extensions != NULL ) { + CERTCertExtension** extns ; + CertificateExtension_XmlSecImpl* pExtn ; + sal_Bool crit ; + int len ; + + for( len = 0, extns = m_pCert->extensions; *extns != NULL; len ++, extns ++ ) ; + Sequence< Reference< XCertificateExtension > > xExtns( len ) ; + + for( extns = m_pCert->extensions, len = 0; *extns != NULL; extns ++, len ++ ) { + pExtn = new CertificateExtension_XmlSecImpl() ; + if( (*extns)->critical.data == NULL ) + crit = sal_False ; + else + crit = ( (*extns)->critical.data[0] == 0xFF ) ? sal_True : sal_False ; + pExtn->setCertExtn( (*extns)->value.data, (*extns)->value.len, (*extns)->id.data, (*extns)->id.len, crit ) ; + + xExtns[len] = pExtn ; + } + + return xExtns ; + } else { + return ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > (); + } +} + +::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL X509Certificate_NssImpl :: findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& oid ) throw (::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->extensions != NULL ) { + CertificateExtension_XmlSecImpl* pExtn ; + CERTCertExtension** extns ; + SECItem idItem ; + sal_Bool crit ; + + idItem.data = ( unsigned char* )&oid[0] ; + idItem.len = oid.getLength() ; + + pExtn = NULL ; + for( extns = m_pCert->extensions; *extns != NULL; extns ++ ) { + if( SECITEM_CompareItem( &idItem, &(*extns)->id ) == SECEqual ) { + pExtn = new CertificateExtension_XmlSecImpl() ; + if( (*extns)->critical.data == NULL ) + crit = sal_False ; + else + crit = ( (*extns)->critical.data[0] == 0xFF ) ? sal_True : sal_False ; + pExtn->setCertExtn( (*extns)->value.data, (*extns)->value.len, (*extns)->id.data, (*extns)->id.len, crit ) ; + } + } + + return pExtn ; + } else { + return NULL ; + } +} + + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl :: getEncoded() throw ( ::com::sun::star::uno::RuntimeException) { + if( m_pCert != NULL && m_pCert->derCert.len > 0 ) { + Sequence< sal_Int8 > rawCert( m_pCert->derCert.len ) ; + + for( unsigned int i = 0 ; i < m_pCert->derCert.len ; i ++ ) + rawCert[i] = *( m_pCert->derCert.data + i ) ; + + return rawCert ; + } else { + return ::com::sun::star::uno::Sequence< sal_Int8 >(); + } +} + +//Helper methods +void X509Certificate_NssImpl :: setCert( CERTCertificate* cert ) { + if( m_pCert != NULL ) { + CERT_DestroyCertificate( m_pCert ) ; + m_pCert = NULL ; + } + + if( cert != NULL ) { + m_pCert = CERT_DupCertificate( cert ) ; + } +} + +const CERTCertificate* X509Certificate_NssImpl :: getNssCert() const { + if( m_pCert != NULL ) { + return m_pCert ; + } else { + return NULL ; + } +} + +void X509Certificate_NssImpl :: setRawCert( Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) { + CERTCertificate* cert ; + SECItem certItem ; + + certItem.data = ( unsigned char* )&rawCert[0] ; + certItem.len = rawCert.getLength() ; + + cert = CERT_DecodeDERCertificate( &certItem, PR_TRUE, NULL ) ; + if( cert == NULL ) + throw RuntimeException() ; + + if( m_pCert != NULL ) { + CERT_DestroyCertificate( m_pCert ) ; + m_pCert = NULL ; + } + + m_pCert = cert ; +} + +/* XUnoTunnel */ +sal_Int64 SAL_CALL X509Certificate_NssImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw( RuntimeException ) { + if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this)); + } + return 0 ; +} + +/* XUnoTunnel extension */ +const Sequence< sal_Int8>& X509Certificate_NssImpl :: getUnoTunnelId() { + static Sequence< sal_Int8 >* pSeq = 0 ; + if( !pSeq ) { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if( !pSeq ) { + static Sequence< sal_Int8> aSeq( 16 ) ; + rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; + pSeq = &aSeq ; + } + } + return *pSeq ; +} + +/* XUnoTunnel extension */ +X509Certificate_NssImpl* X509Certificate_NssImpl :: getImplementation( const Reference< XInterface > xObj ) { + Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; + if( xUT.is() ) { + return reinterpret_cast<X509Certificate_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( getUnoTunnelId() ))); + } else + return NULL ; +} + +::rtl::OUString getAlgorithmDescription(SECAlgorithmID *aid) +{ + SECOidTag tag; + tag = SECOID_GetAlgorithmTag(aid); + + const char *pDesc = SECOID_FindOIDTagDescription(tag); + + return rtl::OUString::createFromAscii( pDesc ) ; +} + +::com::sun::star::uno::Sequence< sal_Int8 > getThumbprint(CERTCertificate *pCert, SECOidTag id) +{ + if( pCert != NULL ) + { + unsigned char fingerprint[20]; + int length = ((id == SEC_OID_MD5)?MD5_LENGTH:SHA1_LENGTH); + + memset(fingerprint, 0, sizeof fingerprint); + PK11_HashBuf(id, fingerprint, pCert->derCert.data, pCert->derCert.len); + + Sequence< sal_Int8 > thumbprint( length ) ; + for( int i = 0 ; i < length ; i ++ ) + thumbprint[i] = fingerprint[i]; + + return thumbprint; + } + else + { + return ::com::sun::star::uno::Sequence< sal_Int8 >(); + } +} + +::rtl::OUString SAL_CALL X509Certificate_NssImpl::getSubjectPublicKeyAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCert != NULL ) + { + return getAlgorithmDescription(&(m_pCert->subjectPublicKeyInfo.algorithm)); + } + else + { + return OUString() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getSubjectPublicKeyValue() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCert != NULL ) + { + SECItem spk = m_pCert->subjectPublicKeyInfo.subjectPublicKey; + DER_ConvertBitString(&spk); + + if ( spk.len>0) + { + Sequence< sal_Int8 > key( spk.len ) ; + for( unsigned int i = 0 ; i < spk.len ; i ++ ) + { + key[i] = *( spk.data + i ) ; + } + + return key ; + } + } + + return ::com::sun::star::uno::Sequence< sal_Int8 >(); +} + +::rtl::OUString SAL_CALL X509Certificate_NssImpl::getSignatureAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) +{ + if( m_pCert != NULL ) + { + return getAlgorithmDescription(&(m_pCert->signature)); + } + else + { + return OUString() ; + } +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getSHA1Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) +{ + return getThumbprint(m_pCert, SEC_OID_SHA1); +} + +::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_NssImpl::getMD5Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) +{ + return getThumbprint(m_pCert, SEC_OID_MD5); +} + +sal_Int32 SAL_CALL X509Certificate_NssImpl::getCertificateUsage( ) + throw ( ::com::sun::star::uno::RuntimeException) +{ + SECStatus rv; + SECItem tmpitem; + sal_Int32 usage; + + rv = CERT_FindKeyUsageExtension(m_pCert, &tmpitem); + if ( rv == SECSuccess ) + { + usage = tmpitem.data[0]; + PORT_Free(tmpitem.data); + tmpitem.data = NULL; + } + else + { + usage = KU_ALL; + } + + /* + * to make the nss implementation compatible with MSCrypto, + * the following usage is ignored + * + * + if ( CERT_GovtApprovedBitSet(m_pCert) ) + { + usage |= KU_NS_GOVT_APPROVED; + } + */ + + return usage; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx new file mode 100644 index 000000000000..b84e977e7b2a --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _X509CERTIFICATE_NSSIMPL_HXX_ +#define _X509CERTIFICATE_NSSIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase2.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include "com/sun/star/uno/SecurityException.hpp" +#include <com/sun/star/security/XCertificate.hpp> + +#include "cert.h" + +class X509Certificate_NssImpl : public ::cppu::WeakImplHelper2< + ::com::sun::star::security::XCertificate , + ::com::sun::star::lang::XUnoTunnel > +{ + private : + CERTCertificate* m_pCert ; + + public : + X509Certificate_NssImpl() ; + virtual ~X509Certificate_NssImpl() ; + + //Methods from XCertificate + virtual sal_Int16 SAL_CALL getVersion( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSerialNumber( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::rtl::OUString SAL_CALL getIssuerName( ) throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::rtl::OUString SAL_CALL getSubjectName( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::util::DateTime SAL_CALL getNotValidBefore( ) throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::util::DateTime SAL_CALL getNotValidAfter( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getIssuerUniqueID( ) throw ( ::com::sun::star::uno::RuntimeException) ; + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSubjectUniqueID( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL getExtensions( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& oid ) throw (::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getEncoded( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::rtl::OUString SAL_CALL getSubjectPublicKeyAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSubjectPublicKeyValue() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::rtl::OUString SAL_CALL getSignatureAlgorithm() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getSHA1Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getMD5Thumbprint() + throw ( ::com::sun::star::uno::RuntimeException) ; + + virtual sal_Int32 SAL_CALL getCertificateUsage( ) throw ( ::com::sun::star::uno::RuntimeException) ; + + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw (com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static X509Certificate_NssImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; + + //Helper methods + void setCert( CERTCertificate* cert ) ; + const CERTCertificate* getNssCert() const ; + void setRawCert( ::com::sun::star::uno::Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) ; +} ; + +#endif // _X509CERTIFICATE_NSSIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.cxx new file mode 100644 index 000000000000..71c443b437c3 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.cxx @@ -0,0 +1,384 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> +#include "xmlencryption_nssimpl.hxx" + +#include "xmldocumentwrapper_xmlsecimpl.hxx" + +#include "xmlelementwrapper_xmlsecimpl.hxx" + +#include "securityenvironment_nssimpl.hxx" +#include "errorcallback.hxx" + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include "xmlsec/xmlsec.h" +#include "xmlsec/xmltree.h" +#include "xmlsec/xmlenc.h" +#include "xmlsec/crypto.h" + +#ifdef UNX +#define stricmp strcasecmp +#endif + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; +using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLEncryption ; +using ::com::sun::star::xml::crypto::XXMLEncryptionTemplate ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XMLEncryptionException ; + +XMLEncryption_NssImpl :: XMLEncryption_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { +} + +XMLEncryption_NssImpl :: ~XMLEncryption_NssImpl() { +} + +/* XXMLEncryption */ +Reference< XXMLEncryptionTemplate > +SAL_CALL XMLEncryption_NssImpl :: encrypt( + const Reference< XXMLEncryptionTemplate >& aTemplate , + const Reference< XSecurityEnvironment >& aEnvironment +) throw( com::sun::star::xml::crypto::XMLEncryptionException, + com::sun::star::uno::SecurityException ) +{ + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecEncCtxPtr pEncCtx = NULL ; + xmlNodePtr pEncryptedData = NULL ; + xmlNodePtr pContent = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aEnvironment.is() ) + throw RuntimeException() ; + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_NssImpl* pSecEnv = + reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>(xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))) ; + if( pSecEnv == NULL ) + throw RuntimeException() ; + + //Get the encryption template + Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; + if( !xTemplate.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; + if( !xTplTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pTemplate = + reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); + if( pTemplate == NULL ) { + throw RuntimeException() ; + } + + // Get the element to be encrypted + Reference< XXMLElementWrapper > xTarget = aTemplate->getTarget() ; + if( !xTarget.is() ) { + throw XMLEncryptionException() ; + } + + Reference< XUnoTunnel > xTgtTunnel( xTarget , UNO_QUERY ) ; + if( !xTgtTunnel.is() ) { + throw XMLEncryptionException() ; + } + + XMLElementWrapper_XmlSecImpl* pTarget = + reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xTgtTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); + if( pTarget == NULL ) { + throw RuntimeException() ; + } + + pContent = pTarget->getNativeElement() ; + + if( pContent == NULL ) { + throw XMLEncryptionException() ; + } + + //remember the position of the element to be signed + sal_Bool isParentRef = sal_True; + xmlNodePtr pParent = pEncryptedData->parent; + xmlNodePtr referenceNode; + + if (pEncryptedData == pParent->children) + { + referenceNode = pParent; + } + else + { + referenceNode = pEncryptedData->prev; + isParentRef = sal_False; + } + + setErrorRecorder( ); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Encryption context + pEncCtx = xmlSecEncCtxCreate( pMngr ) ; + if( pEncCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + + pEncryptedData = pTemplate->getNativeElement() ; + + //Find the element to be encrypted. + + //Encrypt the template + if( xmlSecEncCtxXmlEncrypt( pEncCtx , pEncryptedData , pContent ) < 0 ) + { + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //get the new EncryptedData element + if (isParentRef) + { + pTemplate->setNativeElement(referenceNode->children) ; + } + else + { + pTemplate->setNativeElement(referenceNode->next); + } + + return aTemplate ; +} + +/* XXMLEncryption */ +Reference< XXMLEncryptionTemplate > +SAL_CALL XMLEncryption_NssImpl :: decrypt( + const Reference< XXMLEncryptionTemplate >& aTemplate , + const Reference< XXMLSecurityContext >& aSecurityCtx +) throw( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException) { + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecEncCtxPtr pEncCtx = NULL ; + xmlNodePtr pEncryptedData = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aSecurityCtx.is() ) + throw RuntimeException() ; + + //Get the encryption template + Reference< XXMLElementWrapper > xTemplate = aTemplate->getTemplate() ; + if( !xTemplate.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xTplTunnel( xTemplate , UNO_QUERY ) ; + if( !xTplTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pTemplate = + reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xTplTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); + if( pTemplate == NULL ) { + throw RuntimeException() ; + } + + pEncryptedData = pTemplate->getNativeElement() ; + + //remember the position of the element to be signed + sal_Bool isParentRef = sal_True; + xmlNodePtr pParent = pEncryptedData->parent; + xmlNodePtr referenceNode; + + if (pEncryptedData == pParent->children) + { + referenceNode = pParent; + } + else + { + referenceNode = pEncryptedData->prev; + isParentRef = sal_False; + } + + setErrorRecorder( ); + + sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber(); + sal_Int32 i; + + for (i=0; i<nSecurityEnvironment; ++i) + { + Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i); + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !aEnvironment.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_NssImpl* pSecEnv = + reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); + if( pSecEnv == NULL ) + throw RuntimeException() ; + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Encryption context + pEncCtx = xmlSecEncCtxCreate( pMngr ) ; + if( pEncCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLEncryptionException() ; + clearErrorRecorder(); + return aTemplate; + } + + //Decrypt the template + if(!( xmlSecEncCtxDecrypt( pEncCtx , pEncryptedData ) < 0 || pEncCtx->result == NULL )) + { + //The decryption succeeds + + //Destroy the encryption context + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //get the decrypted element + XMLElementWrapper_XmlSecImpl * ret = new XMLElementWrapper_XmlSecImpl(isParentRef? + (referenceNode->children):(referenceNode->next)); + + //return ret; + aTemplate->setTemplate(ret); + break; + } + else + { + //The decryption fails, continue with the next security environment + xmlSecEncCtxDestroy( pEncCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + } + } + + clearErrorRecorder(); + return aTemplate; +} + +/* XInitialization */ +void SAL_CALL XMLEncryption_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLEncryption_NssImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLEncryption_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLEncryption_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLEncryption_NssImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLEncryption")) ; + return seqServiceNames ; +} + +OUString XMLEncryption_NssImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLEncryption_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLEncryption_NssImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLEncryption_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + //Reference< XSingleServiceFactory > xFactory ; + //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; + //return xFactory ; + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.hxx new file mode 100644 index 000000000000..1b859734db39 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlencryption_nssimpl.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLENCRYPTION_NSSIMPL_HXX_ +#define _XMLENCRYPTION_NSSIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XXMLEncryption.hpp> +#include <com/sun/star/xml/crypto/XXMLEncryptionTemplate.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + +class XMLEncryption_NssImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLEncryption , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + XMLEncryption_NssImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLEncryption_NssImpl() ; + + //Methods from XXMLEncryption + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate > SAL_CALL encrypt( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aEnvironment) + // ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + throw ( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate > SAL_CALL decrypt( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLEncryptionTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext >& aContext + ) throw( com::sun::star::xml::crypto::XMLEncryptionException , + com::sun::star::uno::SecurityException) ; + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; +} ; + +#endif // _XMLENCRYPTION_NSSIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx new file mode 100644 index 000000000000..f0dd15c75fac --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.cxx @@ -0,0 +1,203 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> +#include "securityenvironment_nssimpl.hxx" + +#include "xmlsecuritycontext_nssimpl.hxx" +#include "xmlstreamio.hxx" + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include "xmlsec/xmlsec.h" +#include "xmlsec/keysmngr.h" +#include "xmlsec/crypto.h" + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; + +XMLSecurityContext_NssImpl :: XMLSecurityContext_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) + ://i39448 : m_pKeysMngr( NULL ) , + m_xServiceManager( aFactory ) , + m_nDefaultEnvIndex(-1) + //m_xSecurityEnvironment( NULL ) +{ + //Init xmlsec library + if( xmlSecInit() < 0 ) { + throw RuntimeException() ; + } + + //Init xmlsec crypto engine library + if( xmlSecCryptoInit() < 0 ) { + xmlSecShutdown() ; + throw RuntimeException() ; + } + + //Enable external stream handlers + if( xmlEnableStreamInputCallbacks() < 0 ) { + xmlSecCryptoShutdown() ; + xmlSecShutdown() ; + throw RuntimeException() ; + } +} + +XMLSecurityContext_NssImpl :: ~XMLSecurityContext_NssImpl() { + //i39448 + + xmlDisableStreamInputCallbacks() ; + xmlSecCryptoShutdown() ; + xmlSecShutdown() ; +} + +//i39448 : new methods +sal_Int32 SAL_CALL XMLSecurityContext_NssImpl::addSecurityEnvironment( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment) + throw (::com::sun::star::security::SecurityInfrastructureException, ::com::sun::star::uno::RuntimeException) +{ + if( !aSecurityEnvironment.is() ) + { + throw RuntimeException() ; + } + + m_vSecurityEnvironments.push_back( aSecurityEnvironment ); + + return m_vSecurityEnvironments.size() - 1 ; +} + + +sal_Int32 SAL_CALL XMLSecurityContext_NssImpl::getSecurityEnvironmentNumber( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return m_vSecurityEnvironments.size(); +} + +::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + XMLSecurityContext_NssImpl::getSecurityEnvironmentByIndex( sal_Int32 index ) + throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > xSecurityEnvironment; + + if (index >= 0 && index < ( sal_Int32 )m_vSecurityEnvironments.size()) + { + xSecurityEnvironment = m_vSecurityEnvironments[index]; + } + else + throw RuntimeException() ; + + return xSecurityEnvironment; +} + +::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + XMLSecurityContext_NssImpl::getSecurityEnvironment( ) + throw (::com::sun::star::uno::RuntimeException) +{ + if (m_nDefaultEnvIndex >= 0 && m_nDefaultEnvIndex < ( sal_Int32 )m_vSecurityEnvironments.size()) + return getSecurityEnvironmentByIndex(m_nDefaultEnvIndex); + else + throw RuntimeException() ; +} + +sal_Int32 SAL_CALL XMLSecurityContext_NssImpl::getDefaultSecurityEnvironmentIndex( ) + throw (::com::sun::star::uno::RuntimeException) +{ + return m_nDefaultEnvIndex ; +} + +void SAL_CALL XMLSecurityContext_NssImpl::setDefaultSecurityEnvironmentIndex( sal_Int32 nDefaultEnvIndex ) + throw (::com::sun::star::uno::RuntimeException) +{ + m_nDefaultEnvIndex = nDefaultEnvIndex; +} + +//i39448 : old methods deleted + + +/* XInitialization */ +void SAL_CALL XMLSecurityContext_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLSecurityContext_NssImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLSecurityContext_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLSecurityContext_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLSecurityContext_NssImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLSecurityContext")) ; + return seqServiceNames ; +} + +OUString XMLSecurityContext_NssImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_NssImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLSecurityContext_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLSecurityContext_NssImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLSecurityContext_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + //Reference< XSingleServiceFactory > xFactory ; + //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; + //return xFactory ; + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.hxx new file mode 100644 index 000000000000..685f83ec304d --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlsecuritycontext_nssimpl.hxx @@ -0,0 +1,137 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLSIGNATURECONTEXT_NSSIMPL_HXX_ +#define _XMLSIGNATURECONTEXT_NSSIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + +#ifndef INCLUDED_VECTOR +#include <vector> +#define INCLUDED_VECTOR +#endif + +class XMLSecurityContext_NssImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLSecurityContext , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + //xmlSecKeysMngrPtr m_pKeysMngr ; + //::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > m_xSecurityEnvironment ; + std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > > m_vSecurityEnvironments; + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + sal_Int32 m_nDefaultEnvIndex; + + public : + XMLSecurityContext_NssImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLSecurityContext_NssImpl() ; + + //Methods from XXMLSecurityContext + virtual sal_Int32 SAL_CALL addSecurityEnvironment( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aSecurityEnvironment + ) throw (::com::sun::star::security::SecurityInfrastructureException, ::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getSecurityEnvironmentNumber( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + getSecurityEnvironmentByIndex( ::sal_Int32 index ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::xml::crypto::XSecurityEnvironment > SAL_CALL + getSecurityEnvironment( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Int32 SAL_CALL getDefaultSecurityEnvironmentIndex( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setDefaultSecurityEnvironmentIndex( sal_Int32 nDefaultEnvIndex ) + throw (::com::sun::star::uno::RuntimeException); + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; + + /* + * Because of the issue of multi-securityenvironment, so the keyManager method is not useful any longer. + * + + //Methods from XUnoTunnel + virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (com::sun::star::uno::RuntimeException); + + static const ::com::sun::star::uno::Sequence< sal_Int8 >& getUnoTunnelId() ; + static XMLSecurityContext_NssImpl* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xObj ) ; + + //Native mehtods + virtual xmlSecKeysMngrPtr keysManager() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + */ +} ; + +#endif // _XMLSIGNATURECONTEXT_NSSIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx new file mode 100644 index 000000000000..47e20b7af03b --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.cxx @@ -0,0 +1,344 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" +#include <sal/config.h> +#include <rtl/uuid.h> +#include "xmlsignature_nssimpl.hxx" + +#include "xmldocumentwrapper_xmlsecimpl.hxx" + +#include "xmlelementwrapper_xmlsecimpl.hxx" + +#include "securityenvironment_nssimpl.hxx" + +#include "xmlsecuritycontext_nssimpl.hxx" +#include "xmlstreamio.hxx" +#include "errorcallback.hxx" + +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include "xmlsec/xmlsec.h" +#include "xmlsec/xmldsig.h" +#include "xmlsec/crypto.h" + +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using ::com::sun::star::lang::XMultiServiceFactory ; +using ::com::sun::star::lang::XSingleServiceFactory ; +using ::rtl::OUString ; + +using ::com::sun::star::xml::wrapper::XXMLElementWrapper ; +using ::com::sun::star::xml::wrapper::XXMLDocumentWrapper ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLSignature ; +using ::com::sun::star::xml::crypto::XXMLSignatureTemplate ; +using ::com::sun::star::xml::crypto::XSecurityEnvironment ; +using ::com::sun::star::xml::crypto::XXMLSecurityContext ; +using ::com::sun::star::xml::crypto::XUriBinding ; +using ::com::sun::star::xml::crypto::XMLSignatureException ; + +XMLSignature_NssImpl :: XMLSignature_NssImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_xServiceManager( aFactory ) { +} + +XMLSignature_NssImpl :: ~XMLSignature_NssImpl() { +} + +/* XXMLSignature */ +Reference< XXMLSignatureTemplate > +SAL_CALL XMLSignature_NssImpl :: generate( + const Reference< XXMLSignatureTemplate >& aTemplate , + const Reference< XSecurityEnvironment >& aEnvironment +) throw( com::sun::star::xml::crypto::XMLSignatureException, + com::sun::star::uno::SecurityException ) +{ + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecDSigCtxPtr pDsigCtx = NULL ; + xmlNodePtr pNode = NULL ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aEnvironment.is() ) + throw RuntimeException() ; + + //Get the xml node + Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; + if( !xElement.is() ) { + throw RuntimeException() ; + } + + Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; + if( !xNodTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pElement = + reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); + if( pElement == NULL ) { + throw RuntimeException() ; + } + + pNode = pElement->getNativeElement() ; + + //Get the stream/URI binding + Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; + if( xUriBinding.is() ) { + //Register the stream input callbacks into libxml2 + if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) + throw RuntimeException() ; + } + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + //i39448 : the key manager should be retrieved from SecurityEnvironment, instead of SecurityContext + + SecurityEnvironment_NssImpl* pSecEnv = + reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); + if( pSecEnv == NULL ) + throw RuntimeException() ; + + setErrorRecorder(); + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Signature context + pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; + if( pDsigCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLSignatureException() ; + clearErrorRecorder(); + return aTemplate; + } + + //Sign the template + if( xmlSecDSigCtxSign( pDsigCtx , pNode ) == 0 ) + { + if (pDsigCtx->status == xmlSecDSigStatusSucceeded) + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + else + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + else + { + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + + + xmlSecDSigCtxDestroy( pDsigCtx ) ; + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + + //Unregistered the stream/URI binding + if( xUriBinding.is() ) + xmlUnregisterStreamInputCallbacks() ; + + clearErrorRecorder(); + return aTemplate ; +} + +/* XXMLSignature */ +Reference< XXMLSignatureTemplate > +SAL_CALL XMLSignature_NssImpl :: validate( + const Reference< XXMLSignatureTemplate >& aTemplate , + const Reference< XXMLSecurityContext >& aSecurityCtx +) throw( com::sun::star::uno::RuntimeException, + com::sun::star::uno::SecurityException, + com::sun::star::xml::crypto::XMLSignatureException ) { + xmlSecKeysMngrPtr pMngr = NULL ; + xmlSecDSigCtxPtr pDsigCtx = NULL ; + xmlNodePtr pNode = NULL ; + //sal_Bool valid ; + + if( !aTemplate.is() ) + throw RuntimeException() ; + + if( !aSecurityCtx.is() ) + throw RuntimeException() ; + + //Get the xml node + Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ; + if( !xElement.is() ) + throw RuntimeException() ; + + Reference< XUnoTunnel > xNodTunnel( xElement , UNO_QUERY ) ; + if( !xNodTunnel.is() ) { + throw RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pElement = + reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xNodTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))); + if( pElement == NULL ) + throw RuntimeException() ; + + pNode = pElement->getNativeElement() ; + + //Get the stream/URI binding + Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ; + if( xUriBinding.is() ) { + //Register the stream input callbacks into libxml2 + if( xmlRegisterStreamInputCallbacks( xUriBinding ) < 0 ) + throw RuntimeException() ; + } + + setErrorRecorder(); + + sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber(); + sal_Int32 i; + + for (i=0; i<nSecurityEnvironment; ++i) + { + Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(i); + + //Get Keys Manager + Reference< XUnoTunnel > xSecTunnel( aEnvironment , UNO_QUERY ) ; + if( !xSecTunnel.is() ) { + throw RuntimeException() ; + } + + SecurityEnvironment_NssImpl* pSecEnv = + reinterpret_cast<SecurityEnvironment_NssImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xSecTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ))); + if( pSecEnv == NULL ) + throw RuntimeException() ; + + pMngr = pSecEnv->createKeysManager() ; //i39448 + if( !pMngr ) { + throw RuntimeException() ; + } + + //Create Signature context + pDsigCtx = xmlSecDSigCtxCreate( pMngr ) ; + if( pDsigCtx == NULL ) + { + pSecEnv->destroyKeysManager( pMngr ) ; //i39448 + //throw XMLSignatureException() ; + clearErrorRecorder(); + return aTemplate; + } + + //Verify signature + int rs = xmlSecDSigCtxVerify( pDsigCtx , pNode ); + + + if (rs == 0 && + pDsigCtx->status == xmlSecDSigStatusSucceeded) + { + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED); + xmlSecDSigCtxDestroy( pDsigCtx ) ; + pSecEnv->destroyKeysManager( pMngr ); + break; + } + else + { + aTemplate->setStatus(com::sun::star::xml::crypto::SecurityOperationStatus_UNKNOWN); + } + xmlSecDSigCtxDestroy( pDsigCtx ) ; + pSecEnv->destroyKeysManager( pMngr ); + } + + + + //Unregistered the stream/URI binding + if( xUriBinding.is() ) + xmlUnregisterStreamInputCallbacks() ; + + //return valid ; + clearErrorRecorder(); + return aTemplate; +} + +/* XInitialization */ +void SAL_CALL XMLSignature_NssImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) { + // TBD +} ; + +/* XServiceInfo */ +OUString SAL_CALL XMLSignature_NssImpl :: getImplementationName() throw( RuntimeException ) { + return impl_getImplementationName() ; +} + +/* XServiceInfo */ +sal_Bool SAL_CALL XMLSignature_NssImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) { + Sequence< OUString > seqServiceNames = getSupportedServiceNames() ; + const OUString* pArray = seqServiceNames.getConstArray() ; + for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) { + if( *( pArray + i ) == serviceName ) + return sal_True ; + } + return sal_False ; +} + +/* XServiceInfo */ +Sequence< OUString > SAL_CALL XMLSignature_NssImpl :: getSupportedServiceNames() throw( RuntimeException ) { + return impl_getSupportedServiceNames() ; +} + +//Helper for XServiceInfo +Sequence< OUString > XMLSignature_NssImpl :: impl_getSupportedServiceNames() { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; + Sequence< OUString > seqServiceNames( 1 ) ; + seqServiceNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.crypto.XMLSignature")) ; + return seqServiceNames ; +} + +OUString XMLSignature_NssImpl :: impl_getImplementationName() throw( RuntimeException ) { + return OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl")) ; +} + +//Helper for registry +Reference< XInterface > SAL_CALL XMLSignature_NssImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) { + return Reference< XInterface >( *new XMLSignature_NssImpl( aServiceManager ) ) ; +} + +Reference< XSingleServiceFactory > XMLSignature_NssImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) { + //Reference< XSingleServiceFactory > xFactory ; + //xFactory = ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName , impl_createInstance , impl_getSupportedServiceNames ) ; + //return xFactory ; + return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.hxx new file mode 100644 index 000000000000..3a8cfecd4eb0 --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xmlsignature_nssimpl.hxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLSIGNATURE_NSSIMPL_HXX_ +#define _XMLSIGNATURE_NSSIMPL_HXX_ + +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/uno/Exception.hpp> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/xml/crypto/XXMLSignature.hpp> +#include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp> +#include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp> + +class XMLSignature_NssImpl : public ::cppu::WeakImplHelper3< + ::com::sun::star::xml::crypto::XXMLSignature , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XServiceInfo > +{ + private : + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager ; + + public : + XMLSignature_NssImpl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aFactory ) ; + virtual ~XMLSignature_NssImpl() ; + + //Methods from XXMLSignature + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate > SAL_CALL generate( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >& aEnvironment + ) throw( com::sun::star::xml::crypto::XMLSignatureException, + com::sun::star::uno::SecurityException) ; + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate > SAL_CALL validate( + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSignatureTemplate >& aTemplate , + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XXMLSecurityContext >& aContext + ) throw( com::sun::star::uno::RuntimeException, + com::sun::star::uno::SecurityException, + com::sun::star::xml::crypto::XMLSignatureException); + + //Methods from XInitialization + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments + ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) ; + + //Methods from XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual sal_Bool SAL_CALL supportsService( + const ::rtl::OUString& ServiceName + ) throw( ::com::sun::star::uno::RuntimeException ) ; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for XServiceInfo + static ::com::sun::star::uno::Sequence< ::rtl::OUString > impl_getSupportedServiceNames() ; + + static ::rtl::OUString impl_getImplementationName() throw( ::com::sun::star::uno::RuntimeException ) ; + + //Helper for registry + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) throw( ::com::sun::star::uno::RuntimeException ) ; + + static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ) ; +} ; + +#endif // _XMLSIGNATURE_NSSIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx b/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx new file mode 100644 index 000000000000..466652ab25bb --- /dev/null +++ b/xmlsecurity/source/xmlsec/nss/xsec_nss.cxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <sal/config.h> +#include <stdio.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <cppuhelper/factory.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> + +#include "seinitializer_nssimpl.hxx" +#include "xmlsignature_nssimpl.hxx" +#include "xmlencryption_nssimpl.hxx" +#include "xmlsecuritycontext_nssimpl.hxx" +#include "securityenvironment_nssimpl.hxx" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +extern "C" +{ + +void* SAL_CALL nss_component_getFactory( const sal_Char* pImplName , void* pServiceManager , void* /*pRegistryKey*/ ) +{ + void* pRet = 0; + Reference< XSingleServiceFactory > xFactory ; + + if( pImplName != NULL && pServiceManager != NULL ) { + if( XMLSignature_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLSignature_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( XMLSecurityContext_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLSecurityContext_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( SecurityEnvironment_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = SecurityEnvironment_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( XMLEncryption_NssImpl::impl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = XMLEncryption_NssImpl::impl_createFactory( reinterpret_cast< XMultiServiceFactory* >( pServiceManager ) ) ; + } else if( SEInitializer_NssImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) { + xFactory = Reference< XSingleServiceFactory >( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + SEInitializer_NssImpl_createInstance, SEInitializer_NssImpl_getSupportedServiceNames() ) ); + } + } + + if( xFactory.is() ) { + xFactory->acquire() ; + pRet = xFactory.get() ; + } + + return pRet ; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/saxhelper.cxx b/xmlsecurity/source/xmlsec/saxhelper.cxx new file mode 100644 index 000000000000..6b09fea26718 --- /dev/null +++ b/xmlsecurity/source/xmlsec/saxhelper.cxx @@ -0,0 +1,437 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <rtl/ustring.hxx> + +#include "saxhelper.hxx" +#include "libxml/parserInternals.h" + +#ifndef XMLSEC_NO_XSLT +#include "libxslt/xslt.h" +#endif + +namespace cssu = com::sun::star::uno; +namespace cssxs = com::sun::star::xml::sax; +namespace cssxcsax = com::sun::star::xml::csax; + +/** + * The return value is NULL terminated. The application has the responsibilty to + * deallocte the return value. + */ +xmlChar* ous_to_xmlstr( const rtl::OUString& oustr ) +{ + rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ; + return xmlStrndup( ( xmlChar* )ostr.getStr(), ( int )ostr.getLength() ) ; +} + +/** + * The return value is NULL terminated. The application has the responsibilty to + * deallocte the return value. + */ +xmlChar* ous_to_nxmlstr( const rtl::OUString& oustr, int& length ) +{ + rtl::OString ostr = rtl::OUStringToOString( oustr , RTL_TEXTENCODING_UTF8 ) ; + length = ostr.getLength(); + + return xmlStrndup( ( xmlChar* )ostr.getStr(), length ) ; +} + +/** + * The input parameter isn't necessaryly NULL terminated. + */ +rtl::OUString xmlchar_to_ous( const xmlChar* pChar, int length ) +{ + if( pChar != NULL ) + { + return rtl::OUString( ( sal_Char* )pChar , length , RTL_TEXTENCODING_UTF8 ) ; + } + else + { + return rtl::OUString() ; + } +} + +/** + * The input parameter is NULL terminated + */ +rtl::OUString xmlstr_to_ous( const xmlChar* pStr ) +{ + if( pStr != NULL ) + { + return xmlchar_to_ous( pStr , xmlStrlen( pStr ) ) ; + } + else + { + return rtl::OUString() ; + } +} + +/** + * The return value and the referenced value must be NULL terminated. + * The application has the responsibilty to deallocte the return value. + */ +const xmlChar** attrlist_to_nxmlstr( const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes ) +{ + xmlChar* attname = NULL ; + xmlChar* attvalue = NULL ; + const xmlChar** attrs = NULL ; + rtl::OUString oustr ; + + sal_Int32 nLength = aAttributes.getLength();; + + if( nLength != 0 ) + { + attrs = ( const xmlChar** )xmlMalloc( ( nLength * 2 + 2 ) * sizeof( xmlChar* ) ) ; + } + else + { + return NULL ; + } + + for( int i = 0 , j = 0 ; j < nLength ; ++j ) + { + attname = ous_to_xmlstr( aAttributes[j].sName ) ; + attvalue = ous_to_xmlstr( aAttributes[j].sValue ) ; + + if( attname != NULL && attvalue != NULL ) + { + attrs[i++] = attname ; + attrs[i++] = attvalue ; + attrs[i] = NULL ; + attrs[i+1] = NULL ; + } + else + { + if( attname != NULL ) + xmlFree( attname ) ; + if( attvalue != NULL ) + xmlFree( attvalue ) ; + } + } + + return attrs ; +} + +/** + * Constructor + * + * In this constructor, a libxml sax parser context is initialized. a libxml + * default sax handler is initialized with the context. + */ +SAXHelper::SAXHelper( ) + : m_pParserCtxt( NULL ), + m_pSaxHandler( NULL ) +{ + xmlInitParser() ; + LIBXML_TEST_VERSION ; + + /* + * compile error: + * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS ; + */ + xmlSubstituteEntitiesDefault( 1 ) ; + +#ifndef XMLSEC_NO_XSLT + xmlIndentTreeOutput = 1 ; +#endif /* XMLSEC_NO_XSLT */ + + m_pParserCtxt = xmlNewParserCtxt() ; + + /* + * i41748 + * + * mmi : re-initialize the SAX handler to version 1 + */ + + xmlSAXVersion(m_pParserCtxt->sax, 1); + + /* end */ + + if( m_pParserCtxt->inputTab[0] != NULL ) + { + m_pParserCtxt->inputTab[0] = NULL ; + } + + if( m_pParserCtxt == NULL ) + { +#ifndef XMLSEC_NO_XSLT + xsltCleanupGlobals() ; +#endif +// see issue i74334, we cannot call xmlCleanupParser when libxml is still used +// in other parts of the office. +// xmlCleanupParser() ; + throw cssu::RuntimeException() ; + } + else if( m_pParserCtxt->sax == NULL ) + { + xmlFreeParserCtxt( m_pParserCtxt ) ; + +#ifndef XMLSEC_NO_XSLT + xsltCleanupGlobals() ; +#endif +// see issue i74334, we cannot call xmlCleanupParser when libxml is still used +// in other parts of the office. +// xmlCleanupParser() ; + m_pParserCtxt = NULL ; + throw cssu::RuntimeException() ; + } + else + { + m_pSaxHandler = m_pParserCtxt->sax ; + + //Adjust the context + m_pParserCtxt->recovery = 1 ; + } +} + +/** + * Destructor + * + * In this destructor, a libxml sax parser context is desturcted. The XML tree + * in the context is not deallocated because the tree is bind with a document + * model by the setTargetDocument method, which delegate the target document to + * destruct the xml tree. + */ +SAXHelper::~SAXHelper() { + if( m_pParserCtxt != NULL ) + { + /* + * In the situation that no object refer the Document, this destructor + * must deallocate the Document memory + */ + if( m_pSaxHandler == m_pParserCtxt->sax ) + { + m_pSaxHandler = NULL ; + } + + xmlFreeParserCtxt( m_pParserCtxt ) ; + m_pParserCtxt = NULL ; + } + + if( m_pSaxHandler != NULL ) + { + xmlFree( m_pSaxHandler ) ; + m_pSaxHandler = NULL ; + } +// see issue i74334, we cannot call xmlCleanupParser when libxml is still used +// in other parts of the office. +// xmlCleanupParser() ; +} + +xmlNodePtr SAXHelper::getCurrentNode() +{ + return m_pParserCtxt->node; +} + +void SAXHelper::setCurrentNode(const xmlNodePtr pNode) +{ + /* + * This is really a black trick. + * When the current node is replaced, the nodeTab + * stack's top has to been replaced with the same + * node, in order to make compatibility. + */ + m_pParserCtxt->nodeTab[m_pParserCtxt->nodeNr - 1] + = m_pParserCtxt->node + = pNode; +} + +xmlDocPtr SAXHelper::getDocument() +{ + return m_pParserCtxt->myDoc; +} + +/** + * XDocumentHandler -- start an xml document + */ +void SAXHelper::startDocument( void ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + /* + * Adjust inputTab + */ + xmlParserInputPtr pInput = xmlNewInputStream( m_pParserCtxt ) ; + + if( m_pParserCtxt->inputTab != NULL && m_pParserCtxt->inputMax != 0 ) + { + m_pParserCtxt->inputTab[0] = pInput ; + m_pParserCtxt->input = pInput ; + } + + m_pSaxHandler->startDocument( m_pParserCtxt ) ; + + if( m_pParserCtxt == NULL || m_pParserCtxt->myDoc == NULL ) + { + throw cssu::RuntimeException() ; + } +} + +/** + * XDocumentHandler -- end an xml document + */ +void SAXHelper::endDocument( void ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + m_pSaxHandler->endDocument( m_pParserCtxt ) ; +} + +/** + * XDocumentHandler -- start an xml element + */ +void SAXHelper::startElement( + const rtl::OUString& aName, + const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + const xmlChar* fullName = NULL ; + const xmlChar** attrs = NULL ; + + fullName = ous_to_xmlstr( aName ) ; + attrs = attrlist_to_nxmlstr( aAttributes ) ; + + if( fullName != NULL || attrs != NULL ) + { + m_pSaxHandler->startElement( m_pParserCtxt , fullName , attrs ) ; + } + + if( fullName != NULL ) + { + xmlFree( ( xmlChar* )fullName ) ; + fullName = NULL ; + } + + if( attrs != NULL ) + { + for( int i = 0 ; attrs[i] != NULL ; ++i ) + { + xmlFree( ( xmlChar* )attrs[i] ) ; + attrs[i] = NULL ; + } + + xmlFree( ( void* ) attrs ) ; + attrs = NULL ; + } +} + +/** + * XDocumentHandler -- end an xml element + */ +void SAXHelper::endElement( const rtl::OUString& aName ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + xmlChar* fullname = NULL ; + + fullname = ous_to_xmlstr( aName ) ; + m_pSaxHandler->endElement( m_pParserCtxt , fullname ) ; + + if( fullname != NULL ) + { + xmlFree( ( xmlChar* )fullname ) ; + fullname = NULL ; + } +} + +/** + * XDocumentHandler -- an xml element or cdata characters + */ +void SAXHelper::characters( const rtl::OUString& aChars ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + const xmlChar* chars = NULL ; + int length = 0 ; + + chars = ous_to_nxmlstr( aChars, length ) ; + m_pSaxHandler->characters( m_pParserCtxt , chars , length ) ; + + if( chars != NULL ) + { + xmlFree( ( xmlChar* )chars ) ; + } +} + +/** + * XDocumentHandler -- ignorable xml white space + */ +void SAXHelper::ignorableWhitespace( const rtl::OUString& aWhitespaces ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + const xmlChar* chars = NULL ; + int length = 0 ; + + chars = ous_to_nxmlstr( aWhitespaces, length ) ; + m_pSaxHandler->ignorableWhitespace( m_pParserCtxt , chars , length ) ; + + if( chars != NULL ) + { + xmlFree( ( xmlChar* )chars ) ; + } +} + +/** + * XDocumentHandler -- preaorocessing instruction + */ +void SAXHelper::processingInstruction( + const rtl::OUString& aTarget, + const rtl::OUString& aData ) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ + xmlChar* target = NULL ; + xmlChar* data = NULL ; + + target = ous_to_xmlstr( aTarget ) ; + data = ous_to_xmlstr( aData ) ; + + m_pSaxHandler->processingInstruction( m_pParserCtxt , target , data ) ; + + if( target != NULL ) + { + xmlFree( ( xmlChar* )target ) ; + target = NULL ; + } + + if( data != NULL ) + { + xmlFree( ( xmlChar* )data ) ; + data = NULL ; + } +} + +/** + * XDocumentHandler -- set document locator + * In this case, locator is useless. + */ +void SAXHelper::setDocumentLocator( + const cssu::Reference< cssxs::XLocator > &) + throw( cssxs::SAXException , cssu::RuntimeException ) +{ +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/saxhelper.hxx b/xmlsecurity/source/xmlsec/saxhelper.hxx new file mode 100644 index 000000000000..a18943d5043e --- /dev/null +++ b/xmlsecurity/source/xmlsec/saxhelper.hxx @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _SAXHELPER_HXX +#define _SAXHELPER_HXX + +#include "libxml/tree.h" + +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <com/sun/star/xml/sax/XLocator.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/xml/csax/XMLAttribute.hpp> + +/** This class represents a SAX handler which simply forwards to + the corresponding libxml API and translates parameter if necessary. +*/ +class SAXHelper +{ + private : + xmlParserCtxtPtr m_pParserCtxt ; + xmlSAXHandlerPtr m_pSaxHandler ; + + public: + SAXHelper( ) ; + virtual ~SAXHelper() ; + + xmlNodePtr getCurrentNode(); + void setCurrentNode(const xmlNodePtr pNode); + xmlDocPtr getDocument(); + + void startDocument( void ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void endDocument( void ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void startElement( + const ::rtl::OUString& aName , + const com::sun::star::uno::Sequence< + com::sun::star::xml::csax::XMLAttribute >& aAttributes ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void endElement( const ::rtl::OUString& aName ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void characters( const ::rtl::OUString& aChars ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void processingInstruction( + const ::rtl::OUString& aTarget , + const ::rtl::OUString& aData ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; + + void setDocumentLocator( const ::com::sun::star::uno::Reference< + ::com::sun::star::xml::sax::XLocator > & xLocator ) + throw( ::com::sun::star::xml::sax::SAXException , ::com::sun::star::uno::RuntimeException ) ; +} ; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx new file mode 100644 index 000000000000..987a76dff9fb --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx @@ -0,0 +1,1116 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include "xmldocumentwrapper_xmlsecimpl.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <xmloff/attrlist.hxx> +#include "xmlelementwrapper_xmlsecimpl.hxx" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifndef INCLUDED_VECTOR +#include <vector> +#define INCLUDED_VECTOR +#endif + +#ifdef UNX +#define stricmp strcasecmp +#endif + +namespace cssu = com::sun::star::uno; +namespace cssl = com::sun::star::lang; +namespace cssxc = com::sun::star::xml::crypto; +namespace cssxcsax = com::sun::star::xml::csax; +namespace cssxs = com::sun::star::xml::sax; +namespace cssxw = com::sun::star::xml::wrapper; + +#define SERVICE_NAME "com.sun.star.xml.wrapper.XMLDocumentWrapper" +#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl" + +#define STRXMLNS "xmlns" + +#define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US +#define RTL_UTF8_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8 + +/* used by the recursiveDelete method */ +#define NODE_REMOVED 0 +#define NODE_NOTREMOVED 1 +#define NODE_STOPED 2 + +XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl( ) +{ + saxHelper.startDocument(); + m_pDocument = saxHelper.getDocument(); + + /* + * creates the virtual root element + */ + saxHelper.startElement(rtl::OUString(RTL_UTF8_USTRINGPARAM( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>()); + + m_pRootElement = saxHelper.getCurrentNode(); + m_pCurrentElement = m_pRootElement; +} + +XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl() +{ + saxHelper.endDocument(); + xmlFreeDoc(m_pDocument); +} + +void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent() +/****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent ************************* + * + * NAME + * getNextSAXEvent -- Prepares the next SAX event to be manipulate + * + * SYNOPSIS + * getNextSAXEvent(); + * + * FUNCTION + * When converting the document into SAX events, this method is used to + * decide the next SAX event to be generated. + * Two member variables are checked to make the decision, the + * m_pCurrentElement and the m_nCurrentPosition. + * The m_pCurrentElement represents the node which have been covered, and + * the m_nCurrentPosition represents the event which have been sent. + * For example, suppose that the m_pCurrentElement + * points to element A, and the m_nCurrentPosition equals to + * NODEPOSITION_STARTELEMENT, then the next SAX event should be the + * endElement for element A if A has no child, or startElement for the + * first child element of element A otherwise. + * The m_nCurrentPosition can be one of following values: + * NODEPOSITION_STARTELEMENT for startElement; + * NODEPOSITION_ENDELEMENT for endElement; + * NODEPOSITION_NORMAL for other SAX events; + * + * INPUTS + * empty + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + OSL_ASSERT( m_pCurrentElement != NULL ); + + /* + * Get the next event through tree order. + * + * if the current event is a startElement, then the next + * event depends on whether or not the current node has + * children. + */ + if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT) + { + /* + * If the current node has children, then its first child + * should be next current node, and the next event will be + * startElement or charaters(PI) based on that child's node + * type. Otherwise, the endElement of current node is the + * next event. + */ + if (m_pCurrentElement->children != NULL) + { + m_pCurrentElement = m_pCurrentElement->children; + m_nCurrentPosition + = (m_pCurrentElement->type == XML_ELEMENT_NODE)? + NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL; + } + else + { + m_nCurrentPosition = NODEPOSITION_ENDELEMENT; + } + } + /* + * if the current event is a not startElement, then the next + * event depends on whether or not the current node has + * following sibling. + */ + else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL) + { + xmlNodePtr pNextSibling = m_pCurrentElement->next; + + /* + * If the current node has following sibling, that sibling + * should be next current node, and the next event will be + * startElement or charaters(PI) based on that sibling's node + * type. Otherwise, the endElement of current node's parent + * becomes the next event. + */ + if (pNextSibling != NULL) + { + m_pCurrentElement = pNextSibling; + m_nCurrentPosition + = (m_pCurrentElement->type == XML_ELEMENT_NODE)? + NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL; + } + else + { + m_pCurrentElement = m_pCurrentElement->parent; + m_nCurrentPosition = NODEPOSITION_ENDELEMENT; + } + } +} + +void XMLDocumentWrapper_XmlSecImpl::sendStartElement( + const cssu::Reference< cssxs::XDocumentHandler >& xHandler, + const cssu::Reference< cssxs::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (cssxs::SAXException) +/****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************ + * + * NAME + * sendStartElement -- Constructs a startElement SAX event + * + * SYNOPSIS + * sendStartElement(xHandler, xHandler2, pNode); + * + * FUNCTION + * Used when converting the document into SAX event stream. + * This method constructs a startElement SAX event for a particular + * element, then calls the startElement methods of the XDocumentHandlers. + * + * INPUTS + * xHandler - the first XDocumentHandler interface to receive the + * startElement SAX event. It can be NULL. + * xHandler2 - the second XDocumentHandler interface to receive the + * startElement SAX event. It can't be NULL. + * pNode - the node on which the startElement should be generated. + * This node must be a element type. + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + SvXMLAttributeList* pAttributeList = new SvXMLAttributeList(); + cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList); + + xmlNsPtr pNsDef = pNode->nsDef; + + while (pNsDef != NULL) + { + const xmlChar* pNsPrefix = pNsDef->prefix; + const xmlChar* pNsHref = pNsDef->href; + + if (pNsDef->prefix == NULL) + { + pAttributeList->AddAttribute( + rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS )), + rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref ))); + } + else + { + pAttributeList->AddAttribute( + rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS )) + +rtl::OUString(RTL_UTF8_USTRINGPARAM( ":" )) + +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsPrefix )), + rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref ))); + } + + pNsDef = pNsDef->next; + } + + xmlAttrPtr pAttr = pNode->properties; + + while (pAttr != NULL) + { + const xmlChar* pAttrName = pAttr->name; + xmlNsPtr pAttrNs = pAttr->ns; + + rtl::OUString ouAttrName; + if (pAttrNs == NULL) + { + ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName )); + } + else + { + ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrNs->prefix)) + +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)":" )) + +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName )); + } + + pAttributeList->AddAttribute( + ouAttrName, + rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)(pAttr->children->content)))); + pAttr = pAttr->next; + } + + rtl::OString sNodeName = getNodeQName(pNode); + + if (xHandler.is()) + { + xHandler->startElement( + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )), + xAttrList); + } + + xHandler2->startElement( + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )), + xAttrList); +} + +void XMLDocumentWrapper_XmlSecImpl::sendEndElement( + const cssu::Reference< cssxs::XDocumentHandler >& xHandler, + const cssu::Reference< cssxs::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (cssxs::SAXException) +/****** XMLDocumentWrapper_XmlSecImpl/sendEndElement ************************** + * + * NAME + * sendEndElement -- Constructs a endElement SAX event + * + * SYNOPSIS + * sendEndElement(xHandler, xHandler2, pNode); + * + * FUNCTION + * Used when converting the document into SAX event stream. + * This method constructs a endElement SAX event for a particular + * element, then calls the endElement methods of the XDocumentHandlers. + * + * INPUTS + * xHandler - the first XDocumentHandler interface to receive the + * endElement SAX event. It can be NULL. + * xHandler2 - the second XDocumentHandler interface to receive the + * endElement SAX event. It can't be NULL. + * pNode - the node on which the endElement should be generated. + * This node must be a element type. + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + rtl::OString sNodeName = getNodeQName(pNode); + + if (xHandler.is()) + { + xHandler->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) ))); + } + + xHandler2->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) ))); +} + +void XMLDocumentWrapper_XmlSecImpl::sendNode( + const cssu::Reference< cssxs::XDocumentHandler >& xHandler, + const cssu::Reference< cssxs::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (cssxs::SAXException) +/****** XMLDocumentWrapper_XmlSecImpl/sendNode ******************************** + * + * NAME + * sendNode -- Constructs a characters SAX event or a + * processingInstruction SAX event + * + * SYNOPSIS + * sendNode(xHandler, xHandler2, pNode); + * + * FUNCTION + * Used when converting the document into SAX event stream. + * This method constructs a characters SAX event or a + * processingInstructionfor SAX event based on the type of a particular + * element, then calls the corresponding methods of the XDocumentHandlers. + * + * INPUTS + * xHandler - the first XDocumentHandler interface to receive the + * SAX event. It can be NULL. + * xHandler2 - the second XDocumentHandler interface to receive the + * SAX event. It can't be NULL. + * pNode - the node on which the endElement should be generated. + * If it is a text node, then a characters SAX event is + * generated; if it is a PI node, then a + * processingInstructionfor SAX event is generated. + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + xmlElementType type = pNode->type; + + if (type == XML_TEXT_NODE) + { + if (xHandler.is()) + { + xHandler->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) ))); + } + + xHandler2->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) ))); + } + else if (type == XML_PI_NODE) + { + if (xHandler.is()) + { + xHandler->processingInstruction( + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )), + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) ))); + } + + xHandler2->processingInstruction( + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )), + rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) ))); + } +} + +rtl::OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) const +/****** XMLDocumentWrapper_XmlSecImpl/getNodeQName **************************** + * + * NAME + * getNodeQName -- Retrives the qualified name of a node + * + * SYNOPSIS + * name = getNodeQName(pNode); + * + * FUNCTION + * see NAME + * + * INPUTS + * pNode - the node whose name will be retrived + * + * RESULT + * name - the node's qualified name + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + rtl::OString sNodeName((const sal_Char*)pNode->name); + if (pNode->ns != NULL) + { + xmlNsPtr pNs = pNode->ns; + + if (pNs->prefix != NULL) + { + rtl::OString sPrefix((const sal_Char*)pNs->prefix); + sNodeName = sPrefix+rtl::OString(":")+sNodeName; + } + } + + return sNodeName; +} + +xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement) const +/****** XMLDocumentWrapper_XmlSecImpl/checkElement **************************** + * + * NAME + * checkElement -- Retrives the node wrapped by an XXMLElementWrapper + * interface + * + * SYNOPSIS + * node = checkElement(xXMLElement); + * + * FUNCTION + * see NAME + * + * INPUTS + * xXMLElement - the XXMLElementWrapper interface wraping a node + * + * RESULT + * node - the node wrapped in the XXMLElementWrapper interface + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + xmlNodePtr rc = NULL; + + if (xXMLElement.is()) + { + cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ; + if( !xNodTunnel.is() ) + { + throw cssu::RuntimeException() ; + } + + XMLElementWrapper_XmlSecImpl* pElement + = reinterpret_cast<XMLElementWrapper_XmlSecImpl*>( + sal::static_int_cast<sal_uIntPtr>( + xNodTunnel->getSomething( + XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ; + + if( pElement == NULL ) { + throw cssu::RuntimeException() ; + } + + rc = pElement->getNativeElement(); + } + + return rc; +} + +sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete( + const xmlNodePtr pNode) +/****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete ************************* + * + * NAME + * recursiveDelete -- Deletes a paticular node with its branch. + * + * SYNOPSIS + * result = recursiveDelete(pNode); + * + * FUNCTION + * Deletes a paticular node with its branch, while reserving the nodes + * (and their brance) listed in the m_aReservedNodes. + * The deletion process is preformed in the tree order, that is, a node + * is deleted after its previous sibling node is deleted, a parent node + * is deleted after its branch is deleted. + * During the deletion process when the m_pStopAtNode is reached, the + * progress is interrupted at once. + * + * INPUTS + * pNode - the node to be deleted + * + * RESULT + * result - the result of the deletion process, can be one of following + * values: + * NODE_STOPED - the process is interrupted by meeting the + * m_pStopAtNode + * NODE_NOTREMOVED - the pNode is not completely removed + * because there is its descendant in the + * m_aReservedNodes list + * NODE_REMOVED - the pNode and its branch are completely + * removed + * + * NOTES + * The node in the m_aReservedNodes list must be in the tree order, otherwise + * the result is unpredictable. + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + if (pNode == m_pStopAtNode) + { + return NODE_STOPED; + } + + if (pNode != m_pCurrentReservedNode) + { + xmlNodePtr pChild = pNode->children; + + xmlNodePtr pNextSibling; + bool bIsRemoved = true; + sal_Int32 nResult; + + while( pChild != NULL ) + { + pNextSibling = pChild->next; + nResult = recursiveDelete(pChild); + + switch (nResult) + { + case NODE_STOPED: + return NODE_STOPED; + case NODE_NOTREMOVED: + bIsRemoved = false; + break; + case NODE_REMOVED: + removeNode(pChild); + break; + default: + throw cssu::RuntimeException(); + } + + pChild = pNextSibling; + } + + if (pNode == m_pCurrentElement) + { + bIsRemoved = false; + } + + return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED; + } + else + { + getNextReservedNode(); + return NODE_NOTREMOVED; + } +} + +void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode() +/****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode ********************* + * + * NAME + * getNextReservedNode -- Highlights the next reserved node in the + * reserved node list + * + * SYNOPSIS + * getNextReservedNode(); + * + * FUNCTION + * The m_aReservedNodes array holds a node list, while the + * m_pCurrentReservedNode points to the one currently highlighted. + * This method is used to highlight the next node in the node list. + * This method is called at the time when the current highlighted node + * has been already processed, and the next node should be ready. + * + * INPUTS + * empty + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + if (m_nReservedNodeIndex < m_aReservedNodes.getLength()) + { + m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] ); + m_nReservedNodeIndex ++; + } + else + { + m_pCurrentReservedNode = NULL; + } +} + +void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const +/****** XMLDocumentWrapper_XmlSecImpl/removeNode ****************************** + * + * NAME + * removeNode -- Deletes a node with its branch unconditionaly + * + * SYNOPSIS + * removeNode( pNode ); + * + * FUNCTION + * Delete the node along with its branch from the document. + * + * INPUTS + * pNode - the node to be deleted + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + /* you can't remove the current node */ + OSL_ASSERT( m_pCurrentElement != pNode ); + + xmlAttrPtr pAttr = pNode->properties; + + while (pAttr != NULL) + { + if (!stricmp((sal_Char*)pAttr->name,"id")) + { + xmlRemoveID(m_pDocument, pAttr); + } + + pAttr = pAttr->next; + } + + xmlUnlinkNode(pNode); + xmlFreeNode(pNode); +} + +void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const +/****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr ***************************** + * + * NAME + * buildIDAttr -- build the ID attribute of a node + * + * SYNOPSIS + * buildIDAttr( pNode ); + * + * FUNCTION + * see NAME + * + * INPUTS + * pNode - the node whose id attribute will be built + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + xmlAttrPtr idAttr = xmlHasProp( pNode, (const unsigned char *)"id" ); + if (idAttr == NULL) + { + idAttr = xmlHasProp( pNode, (const unsigned char *)"Id" ); + } + + if (idAttr != NULL) + { + xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ; + xmlAddID( NULL, m_pDocument, idValue, idAttr ); + } +} + +void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const +/****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink *************************** + * + * NAME + * rebuildIDLink -- rebuild the ID link for the branch + * + * SYNOPSIS + * rebuildIDLink( pNode ); + * + * FUNCTION + * see NAME + * + * INPUTS + * pNode - the node, from which the branch will be rebuilt + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + if (pNode != NULL && pNode->type == XML_ELEMENT_NODE) + { + buildIDAttr( pNode ); + + xmlNodePtr child = pNode->children; + while (child != NULL) + { + rebuildIDLink(child); + child = child->next; + } + } +} + +/* XXMLDocumentWrapper */ +cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( ) + throw (cssu::RuntimeException) +{ + XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement); + return (cssu::Reference< cssxw::XXMLElementWrapper >)pElement; +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element ) + throw (cssu::RuntimeException) +{ + m_pCurrentElement = checkElement( element ); + saxHelper.setCurrentNode( m_pCurrentElement ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( ) + throw (cssu::RuntimeException) +{ + OSL_ASSERT( m_pCurrentElement != NULL ); + + xmlNodePtr pOldCurrentElement = m_pCurrentElement; + + /* + * pop the top node in the parser context's + * nodeTab stack, then the parent of that node will + * automatically become the new stack top, and + * the current node as well. + */ + saxHelper.endElement( + rtl::OUString( + RTL_UTF8_USTRINGPARAM ( + (sal_Char*)(pOldCurrentElement->name) + ))); + m_pCurrentElement = saxHelper.getCurrentNode(); + + /* + * remove the node + */ + removeNode(pOldCurrentElement); +} + +sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node ) + throw (cssu::RuntimeException) +{ + xmlNodePtr pNode = checkElement(node); + return (pNode == m_pCurrentElement); +} + +sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( ) + throw (cssu::RuntimeException) +{ + sal_Bool rc = sal_False; + + if (m_pCurrentElement->children == NULL) + { + rc = sal_True; + } + + return rc; +} + +rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node ) + throw (cssu::RuntimeException) +{ + xmlNodePtr pNode = checkElement(node); + return rtl::OUString(RTL_UTF8_USTRINGPARAM ( (sal_Char*)pNode->name )); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData( + const cssu::Reference< cssxw::XXMLElementWrapper >& node, + const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants, + const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode ) + throw (cssu::RuntimeException) +{ + xmlNodePtr pTargetNode = checkElement(node); + + m_pStopAtNode = checkElement(stopAtNode); + m_aReservedNodes = reservedDescendants; + m_nReservedNodeIndex = 0; + + getNextReservedNode(); + + recursiveDelete(pTargetNode); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node ) + throw (cssu::RuntimeException) +{ + xmlNodePtr pTargetNode = checkElement(node); + xmlNodePtr pParent; + + while (pTargetNode != NULL) + { + if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement) + { + break; + } + + pParent = pTargetNode->parent; + removeNode(pTargetNode); + pTargetNode = pParent; + } +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + if (m_pRootElement != NULL) + { + xmlNodePtr pTempCurrentElement = m_pCurrentElement; + sal_Int32 nTempCurrentPosition = m_nCurrentPosition; + + m_pCurrentElement = m_pRootElement; + + m_nCurrentPosition = NODEPOSITION_STARTELEMENT; + cssu::Reference< cssxs::XDocumentHandler > xHandler = handler; + + while(true) + { + switch (m_nCurrentPosition) + { + case NODEPOSITION_STARTELEMENT: + sendStartElement(NULL, xHandler, m_pCurrentElement); + break; + case NODEPOSITION_ENDELEMENT: + sendEndElement(NULL, xHandler, m_pCurrentElement); + break; + case NODEPOSITION_NORMAL: + sendNode(NULL, xHandler, m_pCurrentElement); + break; + } + + if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT )) + { + break; + } + + getNextSAXEvent(); + } + + m_pCurrentElement = pTempCurrentElement; + m_nCurrentPosition = nTempCurrentPosition; + } +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents( + const cssu::Reference< cssxs::XDocumentHandler >& handler, + const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler, + const cssu::Reference< cssxw::XXMLElementWrapper >& startNode, + const cssu::Reference< cssxw::XXMLElementWrapper >& endNode ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + /* + * The first SAX event is the startElement of the startNode + * element. + */ + bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL); + + xmlNodePtr pTempCurrentElement = m_pCurrentElement; + + m_pCurrentElement = checkElement(startNode); + + if (m_pCurrentElement->type == XML_ELEMENT_NODE) + { + m_nCurrentPosition = NODEPOSITION_STARTELEMENT; + } + else + { + m_nCurrentPosition = NODEPOSITION_NORMAL; + } + + xmlNodePtr pEndNode = checkElement(endNode); + + cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY ); + + cssu::Reference< cssxs::XDocumentHandler > xHandler = handler; + + while(true) + { + switch (m_nCurrentPosition) + { + case NODEPOSITION_STARTELEMENT: + sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement); + break; + case NODEPOSITION_ENDELEMENT: + sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement); + break; + case NODEPOSITION_NORMAL: + sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement); + break; + default: + throw cssu::RuntimeException(); + } + + if (xSAXEventKeeper->isBlocking()) + { + xHandler = NULL; + } + + if (pEndNode == NULL && + ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) || + (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT))) + { + break; + } + + getNextSAXEvent(); + + /* + * If there is an end point specified, then check whether + * the current node equals to the end point. If so, stop + * generating. + */ + if (pEndNode != NULL && m_pCurrentElement == pEndNode) + { + break; + } + } + + m_pCurrentElement = pTempCurrentElement; +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink( + const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node ) + throw (com::sun::star::uno::RuntimeException) +{ + xmlNodePtr pNode = checkElement( node ); + rebuildIDLink(pNode); +} + + +/* cssxs::XDocumentHandler */ +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const rtl::OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + sal_Int32 nLength = xAttribs->getLength(); + cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength); + + for (int i = 0; i < nLength; ++i) + { + aAttributes[i].sName = xAttribs->getNameByIndex((short)i); + aAttributes[i].sValue =xAttribs->getValueByIndex((short)i); + } + + _startElement(aName, aAttributes); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const rtl::OUString& aName ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.endElement(aName); + m_pCurrentElement = saxHelper.getCurrentNode(); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const rtl::OUString& aChars ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.characters(aChars); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.ignorableWhitespace(aWhitespaces); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.processingInstruction(aTarget, aData); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.setDocumentLocator(xLocator); +} + +/* XCompressedDocumentHandler */ +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startDocument( ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endDocument( ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startElement( const rtl::OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + saxHelper.startElement(aName, aAttributes); + m_pCurrentElement = saxHelper.getCurrentNode(); + + buildIDAttr( m_pCurrentElement ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endElement( const rtl::OUString& aName ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + endElement( aName ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_characters( const rtl::OUString& aChars ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + characters( aChars ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_ignorableWhitespace( const rtl::OUString& aWhitespaces ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + ignorableWhitespace( aWhitespaces ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ + processingInstruction( aTarget, aData ); +} + +void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_setDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const rtl::OUString& /*publicId*/, const rtl::OUString& /*systemId*/ ) + throw (cssxs::SAXException, cssu::RuntimeException) +{ +} + +rtl::OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName () + throw (cssu::RuntimeException) +{ + return rtl::OUString ( RTL_ASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); +} + +sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName ) + throw (cssu::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME )); +} + +cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + cssu::Sequence < rtl::OUString > aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString ( RTL_ASCII_USTRINGPARAM ( SERVICE_NAME ) ); + return aRet; +} +#undef SERVICE_NAME + +cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance( + const cssu::Reference< cssl::XMultiServiceFactory > &) + throw( cssu::Exception ) +{ + return (cppu::OWeakObject*) new XMLDocumentWrapper_XmlSecImpl( ); +} + +/* XServiceInfo */ +rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( ) + throw (cssu::RuntimeException) +{ + return XMLDocumentWrapper_XmlSecImpl_getImplementationName(); +} +sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const rtl::OUString& rServiceName ) + throw (cssu::RuntimeException) +{ + return XMLDocumentWrapper_XmlSecImpl_supportsService( rServiceName ); +} +cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.hxx b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.hxx new file mode 100644 index 000000000000..de4f5cb25769 --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.hxx @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX +#define _XMLDOCUMENTWRAPPER_XMLSECIMPL_HXX + +#include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp> +#include <com/sun/star/xml/csax/XCompressedDocumentHandler.hpp> +#include <com/sun/star/xml/crypto/sax/XSAXEventKeeper.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase4.hxx> + +#include "saxhelper.hxx" + +#define NODEPOSITION_NORMAL 1 +#define NODEPOSITION_STARTELEMENT 2 +#define NODEPOSITION_ENDELEMENT 3 + +#include <libxml/tree.h> + +class XMLDocumentWrapper_XmlSecImpl : public cppu::WeakImplHelper4 +< + com::sun::star::xml::wrapper::XXMLDocumentWrapper, + com::sun::star::xml::sax::XDocumentHandler, + com::sun::star::xml::csax::XCompressedDocumentHandler, + com::sun::star::lang::XServiceInfo +> +/****** XMLDocumentWrapper_XmlSecImpl.hxx/CLASS XMLDocumentWrapper_XmlSecImpl * + * + * NAME + * XMLDocumentWrapper_XmlSecImpl -- Class to manipulate a libxml2 + * document + * + * FUNCTION + * Converts SAX events into a libxml2 document, converts the document back + * into SAX event stream, and manipulate nodes in the document. + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ +private: + /* the sax helper */ + SAXHelper saxHelper; + + /* the document used to convert SAX events to */ + xmlDocPtr m_pDocument; + + /* the root element */ + xmlNodePtr m_pRootElement; + + /* + * the current active element. The next incoming SAX event will be + * appended to this element + */ + xmlNodePtr m_pCurrentElement; + + /* + * This variable is used when converting the document or part of it into + * SAX events. See getNextSAXEvent method. + */ + sal_Int32 m_nCurrentPosition; + + /* + * used for recursive deletion. See recursiveDelete method + */ + xmlNodePtr m_pStopAtNode; + xmlNodePtr m_pCurrentReservedNode; + com::sun::star::uno::Sequence< com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper > > m_aReservedNodes; + sal_Int32 m_nReservedNodeIndex; + +private: + void getNextSAXEvent(); + + void sendStartElement( + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (com::sun::star::xml::sax::SAXException); + + void sendEndElement( + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (com::sun::star::xml::sax::SAXException); + + void sendNode( + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xHandler2, + const xmlNodePtr pNode) const + throw (com::sun::star::xml::sax::SAXException); + + rtl::OString getNodeQName(const xmlNodePtr pNode) const; + + sal_Int32 recursiveDelete( const xmlNodePtr pNode); + + void getNextReservedNode(); + + void removeNode( const xmlNodePtr pNode) const; + + xmlNodePtr checkElement( + const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& xXMLElement) const; + + void buildIDAttr( xmlNodePtr pNode ) const; + void rebuildIDLink( xmlNodePtr pNode ) const; + +public: + XMLDocumentWrapper_XmlSecImpl(); + virtual ~XMLDocumentWrapper_XmlSecImpl(); + + /* com::sun::star::xml::wrapper::XXMLDocumentWrapper */ + virtual com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper > SAL_CALL getCurrentElement( ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setCurrentElement( const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& element ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeCurrentElement( ) + throw (com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isCurrent( const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& node ) + throw (com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isCurrentElementEmpty( ) + throw (com::sun::star::uno::RuntimeException); + + virtual rtl::OUString SAL_CALL getNodeName( const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& node ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL clearUselessData( + const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& node, + const com::sun::star::uno::Sequence< com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper > >& reservedDescendants, + const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& stopAtNode ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL collapse( const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& node ) + throw (com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL generateSAXEvents( + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& handler, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& xEventKeeperHandler, + const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& startNode, + const com::sun::star::uno::Reference< + com::sun::star::xml::wrapper::XXMLElementWrapper >& endNode ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL getTree( + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler >& handler ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL rebuildIDLink( + const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node ) + throw (com::sun::star::uno::RuntimeException); + + /* com::sun::star::xml::sax::XDocumentHandler */ + virtual void SAL_CALL startDocument( ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL endDocument( ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL startElement( + const rtl::OUString& aName, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL endElement( const rtl::OUString& aName ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL characters( const rtl::OUString& aChars ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL ignorableWhitespace( const rtl::OUString& aWhitespaces ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setDocumentLocator( const com::sun::star::uno::Reference< com::sun::star::xml::sax::XLocator >& xLocator ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + /* com::sun::star::xml::csax::XCompressedDocumentHandler */ + virtual void SAL_CALL _startDocument( ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _endDocument( ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _startElement( + const rtl::OUString& aName, + const com::sun::star::uno::Sequence< + com::sun::star::xml::csax::XMLAttribute >& aAttributes ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _endElement( const rtl::OUString& aName ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _characters( const rtl::OUString& aChars ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _ignorableWhitespace( const rtl::OUString& aWhitespaces ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL _setDocumentLocator( + sal_Int32 columnNumber, + sal_Int32 lineNumber, + const rtl::OUString& publicId, + const rtl::OUString& systemId ) + throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException); + + /* com::sun::star::lang::XServiceInfo */ + virtual rtl::OUString SAL_CALL getImplementationName( ) + throw (com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) + throw (com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (com::sun::star::uno::RuntimeException); +}; + +rtl::OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName() + throw ( com::sun::star::uno::RuntimeException ); + +sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Reference< com::sun::star::uno::XInterface > +SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > & rSMgr) + throw ( com::sun::star::uno::Exception ); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.cxx b/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.cxx new file mode 100644 index 000000000000..cc00a33f1bdb --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.cxx @@ -0,0 +1,183 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include "xmlelementwrapper_xmlsecimpl.hxx" +#include <cppuhelper/typeprovider.hxx> + +namespace cssu = com::sun::star::uno; +namespace cssl = com::sun::star::lang; + +#define SERVICE_NAME "com.sun.star.xml.wrapper.XMLElementWrapper" +#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLElementWrapper_XmlSecImpl" + +XMLElementWrapper_XmlSecImpl::XMLElementWrapper_XmlSecImpl(const xmlNodePtr pNode) + : m_pElement( pNode ) +{ +} + +/* XXMLElementWrapper */ + + +/* XUnoTunnel */ +cssu::Sequence< sal_Int8 > XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId( void ) + throw (cssu::RuntimeException) +{ + static ::cppu::OImplementationId* pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +sal_Int64 SAL_CALL XMLElementWrapper_XmlSecImpl::getSomething( const cssu::Sequence< sal_Int8 >& aIdentifier ) + throw (cssu::RuntimeException) +{ + if (aIdentifier.getLength() == 16 && + 0 == rtl_compareMemory( + getUnoTunnelImplementationId().getConstArray(), + aIdentifier.getConstArray(), + 16 )) + { + return reinterpret_cast < sal_Int64 > ( this ); + } + else + { + return 0; + } +} + + +rtl::OUString XMLElementWrapper_XmlSecImpl_getImplementationName () + throw (cssu::RuntimeException) +{ + return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); +} + +sal_Bool SAL_CALL XMLElementWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName ) + throw (cssu::RuntimeException) +{ + return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME )); +} + +cssu::Sequence< rtl::OUString > SAL_CALL XMLElementWrapper_XmlSecImpl_getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + cssu::Sequence < rtl::OUString > aRet(1); + rtl::OUString* pArray = aRet.getArray(); + pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); + return aRet; +} +#undef SERVICE_NAME + +cssu::Reference< cssu::XInterface > SAL_CALL + XMLElementWrapper_XmlSecImpl_createInstance( + const cssu::Reference< cssl::XMultiServiceFactory > &) + throw( cssu::Exception ) +{ + return (cppu::OWeakObject*) new XMLElementWrapper_XmlSecImpl(NULL); +} + +/* XServiceInfo */ +rtl::OUString SAL_CALL XMLElementWrapper_XmlSecImpl::getImplementationName( ) + throw (cssu::RuntimeException) +{ + return XMLElementWrapper_XmlSecImpl_getImplementationName(); +} +sal_Bool SAL_CALL XMLElementWrapper_XmlSecImpl::supportsService( const rtl::OUString& rServiceName ) + throw (cssu::RuntimeException) +{ + return XMLElementWrapper_XmlSecImpl_supportsService( rServiceName ); +} +cssu::Sequence< rtl::OUString > SAL_CALL XMLElementWrapper_XmlSecImpl::getSupportedServiceNames( ) + throw (cssu::RuntimeException) +{ + return XMLElementWrapper_XmlSecImpl_getSupportedServiceNames(); +} + +xmlNodePtr XMLElementWrapper_XmlSecImpl::getNativeElement( ) const +/****** XMLElementWrapper_XmlSecImpl/getNativeElement ************************* + * + * NAME + * getNativeElement -- Retrieves the libxml2 node wrapped by this object + * + * SYNOPSIS + * pNode = getNativeElement(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * pNode - the libxml2 node wrapped by this object + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + return m_pElement; +} + +void XMLElementWrapper_XmlSecImpl::setNativeElement(const xmlNodePtr pNode) +/****** XMLElementWrapper_XmlSecImpl/setNativeElement ************************* + * + * NAME + * setNativeElement -- Configures the libxml2 node wrapped by this object + * + * SYNOPSIS + * setNativeElement( pNode ); + * + * FUNCTION + * see NAME + * + * INPUTS + * pNode - the new libxml2 node to be wrapped by this object + * + * RESULT + * empty + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + m_pElement = pNode; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.hxx b/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.hxx new file mode 100644 index 000000000000..02a97be563d9 --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmlelementwrapper_xmlsecimpl.hxx @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLELEMENTWRAPPER_XMLSECIMPL_HXX +#define _XMLELEMENTWRAPPER_XMLSECIMPL_HXX + +#include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <cppuhelper/implbase3.hxx> + +#include <libxml/tree.h> + +class XMLElementWrapper_XmlSecImpl : public cppu::WeakImplHelper3 +< + com::sun::star::xml::wrapper::XXMLElementWrapper, + com::sun::star::lang::XUnoTunnel, + com::sun::star::lang::XServiceInfo +> +/****** XMLElementWrapper_XmlSecImpl.hxx/CLASS XMLElementWrapper_XmlSecImpl *** + * + * NAME + * XMLElementWrapper_XmlSecImpl -- Class to wrap a libxml2 node + * + * FUNCTION + * Used as a wrapper class to transfer a libxml2 node structure + * between different UNO components. + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ +private: + /* the libxml2 node wrapped by this object */ + xmlNodePtr m_pElement; + +public: + explicit XMLElementWrapper_XmlSecImpl(const xmlNodePtr pNode); + virtual ~XMLElementWrapper_XmlSecImpl() {}; + + /* XXMLElementWrapper */ + + /* com::sun::star::lang::XUnoTunnel */ + virtual sal_Int64 SAL_CALL getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) + throw (com::sun::star::uno::RuntimeException); + static com::sun::star::uno::Sequence < sal_Int8 > getUnoTunnelImplementationId( void ) + throw(com::sun::star::uno::RuntimeException); + + /* com::sun::star::lang::XServiceInfo */ + virtual rtl::OUString SAL_CALL getImplementationName( ) + throw (com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const rtl::OUString& ServiceName ) + throw (com::sun::star::uno::RuntimeException); + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw (com::sun::star::uno::RuntimeException); + +public: + xmlNodePtr getNativeElement( ) const; + void setNativeElement(const xmlNodePtr pNode); +}; + +rtl::OUString XMLElementWrapper_XmlSecImpl_getImplementationName() + throw ( com::sun::star::uno::RuntimeException ); + +sal_Bool SAL_CALL XMLElementWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL XMLElementWrapper_XmlSecImpl_getSupportedServiceNames( ) + throw ( com::sun::star::uno::RuntimeException ); + +com::sun::star::uno::Reference< com::sun::star::uno::XInterface > +SAL_CALL XMLElementWrapper_XmlSecImpl_createInstance( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory > & rSMgr) + throw ( com::sun::star::uno::Exception ); + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmlstreamio.cxx b/xmlsecurity/source/xmlsec/xmlstreamio.cxx new file mode 100644 index 000000000000..b75083e5e022 --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmlstreamio.cxx @@ -0,0 +1,235 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +/* + * Implementation of the I/O interfaces based on stream and URI binding + */ +#include "xmlstreamio.hxx" +#include <rtl/ustring.hxx> +#include "rtl/uri.hxx" + +#include <libxml/uri.h> +#include <sal/types.h> +//For reasons that escape me, this is what xmlsec does when size_t is not 4 +#if SAL_TYPES_SIZEOFPOINTER != 4 +# define XMLSEC_NO_SIZE_T +#endif +#include <xmlsec/io.h> + +#define XMLSTREAMIO_INITIALIZED 0x01 +#define XMLSTREAMIO_REGISTERED 0x02 + +/* Global variables */ +/*- + * Enable stream I/O or not. + */ +static char enableXmlStreamIO = 0x00 ; + +::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding > m_xUriBinding ; + +extern "C" +int xmlStreamMatch( const char* uri ) +{ + ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; + + if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && + ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + if( uri == NULL || !m_xUriBinding.is() ) + return 0 ; + //XMLSec first unescapes the uri and calls this function. For example, we pass the Uri + //ObjectReplacements/Object%201 then XMLSec passes ObjectReplacements/Object 1 + //first. If this failed it would try this + //again with the original escaped string. However, it does not get this far, because there + //is another callback registered by libxml which claims to be able to handle this uri. + ::rtl::OUString sUri = + ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), + rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); + xInputStream = m_xUriBinding->getUriBinding( sUri ) ; + if (!xInputStream.is()) + { + //Try the the passed in uri directly. + //For old documents prior OOo 3.0. We did not use URIs then. + xInputStream = m_xUriBinding->getUriBinding( + ::rtl::OUString::createFromAscii(uri)); + } + } + if (xInputStream.is()) + return 1; + else + return 0 ; +} + +extern "C" +void* xmlStreamOpen( const char* uri ) +{ + ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; + ::com::sun::star::io::XInputStream* pInputStream ; + + if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && + ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + if( uri == NULL || !m_xUriBinding.is() ) + return NULL ; + + //see xmlStreamMatch + ::rtl::OUString sUri = + ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), + rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); + xInputStream = m_xUriBinding->getUriBinding( sUri ) ; + if (!xInputStream.is()) + { + //For old documents. + //try the the passed in uri directly. + xInputStream = m_xUriBinding->getUriBinding( + ::rtl::OUString::createFromAscii(uri)); + } + + if( xInputStream.is() ) { + pInputStream = xInputStream.get() ; + pInputStream->acquire() ; + return ( void* )pInputStream ; + } + } + + return NULL ; +} + +extern "C" +int xmlStreamRead( void* context, char* buffer, int len ) +{ + int numbers ; + ::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ; + ::com::sun::star::uno::Sequence< sal_Int8 > outSeqs( len ) ; + + numbers = 0 ; + if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && + ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + if( context != NULL ) { + xInputStream = ( com::sun::star::io::XInputStream* )context ; + if( !xInputStream.is() ) + return 0 ; + + numbers = xInputStream->readBytes( outSeqs, len ) ; + const sal_Int8* readBytes = ( const sal_Int8* )outSeqs.getArray() ; + for( int i = 0 ; i < numbers ; i ++ ) + *( buffer + i ) = *( readBytes + i ) ; + } + } + + return numbers ; +} + +extern "C" +int xmlStreamClose( void * context ) +{ + ::com::sun::star::io::XInputStream* pInputStream ; + + if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) && + ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + if( context != NULL ) { + pInputStream = ( ::com::sun::star::io::XInputStream* )context ; + pInputStream->release() ; + } + } + + return 0 ; +} + +int xmlEnableStreamInputCallbacks() +{ + + if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) { + //Register the callbacks into xmlSec + //In order to make the xmlsec io finding the callbacks firstly, + //I put the callbacks at the very begining. + + //Cleanup the older callbacks. + //Notes: all none default callbacks will lose. + xmlSecIOCleanupCallbacks() ; + + //Register my classbacks. + int cbs = xmlSecIORegisterCallbacks( + xmlStreamMatch, + xmlStreamOpen, + xmlStreamRead, + xmlStreamClose ) ; + if( cbs < 0 ) { + return -1 ; + } + + //Register the default callbacks. + //Notes: the error will cause xmlsec working problems. + cbs = xmlSecIORegisterDefaultCallbacks() ; + if( cbs < 0 ) { + return -1 ; + } + + enableXmlStreamIO |= XMLSTREAMIO_INITIALIZED ; + } + + return 0 ; +} + +int xmlRegisterStreamInputCallbacks( + ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding >& aUriBinding +) { + if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) { + if( xmlEnableStreamInputCallbacks() < 0 ) + return -1 ; + } + + if( !( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + enableXmlStreamIO |= XMLSTREAMIO_REGISTERED ; + } + + m_xUriBinding = aUriBinding ; + + return 0 ; +} + +int xmlUnregisterStreamInputCallbacks( void ) +{ + if( ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) { + //Clear the uir-stream binding + m_xUriBinding.clear() ; + + //disable the registered flag + enableXmlStreamIO &= ~XMLSTREAMIO_REGISTERED ; + } + + return 0 ; +} + +void xmlDisableStreamInputCallbacks() { + xmlUnregisterStreamInputCallbacks() ; + enableXmlStreamIO &= ~XMLSTREAMIO_INITIALIZED ; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xmlstreamio.hxx b/xmlsecurity/source/xmlsec/xmlstreamio.hxx new file mode 100644 index 000000000000..eb61e9897606 --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmlstreamio.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 _XMLSTREAMIO_XMLSECIMPL_HXX_ +#define _XMLSTREAMIO_XMLSECIMPL_HXX_ + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/xml/crypto/XUriBinding.hpp> + +int xmlEnableStreamInputCallbacks( void ) ; +void xmlDisableStreamInputCallbacks( void ) ; + +int xmlRegisterStreamInputCallbacks( + ::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding >& aUriBinding +) ; + +int xmlUnregisterStreamInputCallbacks( void ) ; + +#endif //_XMLSTREAMIO_XMLSECIMPL_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx new file mode 100644 index 000000000000..54a55cfc1c0c --- /dev/null +++ b/xmlsecurity/source/xmlsec/xsec_xmlsec.cxx @@ -0,0 +1,162 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include <sal/config.h> +#include <stdio.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> +#include <cppuhelper/factory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/security/XSerialNumberAdapter.hpp> + +#include "xmlelementwrapper_xmlsecimpl.hxx" +#include "xmldocumentwrapper_xmlsecimpl.hxx" +#include "xmlsecurity/biginteger.hxx" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; + +namespace +{ +class SerialNumberAdapterImpl : public WeakImplHelper1< + ::com::sun::star::security::XSerialNumberAdapter > +{ + virtual OUString SAL_CALL toString( const Sequence< sal_Int8 >& rSerialNumber ) + throw (RuntimeException) + { + return bigIntegerToNumericString(rSerialNumber); + } + virtual Sequence< sal_Int8 > SAL_CALL toSequence( const OUString& rSerialNumber ) + throw (RuntimeException) + { + return numericStringToBigInteger(rSerialNumber); + } +}; + +OUString SerialNumberAdapterImpl_getImplementationName() + throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.security.SerialNumberAdapter")); +} + +Sequence< OUString > SerialNumberAdapterImpl_getSupportedServiceNames() + throw (RuntimeException) +{ + Sequence < OUString > aRet(1); + OUString* pArray = aRet.getArray(); + pArray[0] = OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.security.SerialNumberAdapter" ) ); + return aRet; +} + +Reference< XInterface > SerialNumberAdapterImpl_createInstance( + const Reference< XComponentContext > &) throw( Exception ) +{ + return Reference< XInterface >( *new SerialNumberAdapterImpl() ); +} + +} + +extern "C" +{ + +#if defined( XMLSEC_CRYPTO_NSS ) +extern void* nss_component_getFactory( const sal_Char*, void*, void* ); +#endif + +#if defined( XMLSEC_CRYPTO_MSCRYPTO ) +extern void* mscrypt_component_getFactory( const sal_Char*, void*, void* ); +#endif + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment **) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +void* SAL_CALL component_getFactory( const sal_Char* pImplName , void* pServiceManager , void* pRegistryKey ) +{ + void* pRet = 0; + Reference< XInterface > xFactory ; + + if( pImplName != NULL && pServiceManager != NULL ) { + if( XMLElementWrapper_XmlSecImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) + { + xFactory = Reference< XSingleServiceFactory >( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + XMLElementWrapper_XmlSecImpl_createInstance, XMLElementWrapper_XmlSecImpl_getSupportedServiceNames() ) ); + } + else if( XMLDocumentWrapper_XmlSecImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) + { + xFactory = Reference< XSingleServiceFactory >( createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + XMLDocumentWrapper_XmlSecImpl_createInstance, XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames() ) ); + } + else if( SerialNumberAdapterImpl_getImplementationName().equals( OUString::createFromAscii( pImplName ) ) ) + { + xFactory = ::cppu::createSingleComponentFactory( + SerialNumberAdapterImpl_createInstance, + OUString::createFromAscii( pImplName ), + SerialNumberAdapterImpl_getSupportedServiceNames() ); + } + } + + if( xFactory.is() ) { + xFactory->acquire() ; + pRet = xFactory.get() ; + } else { +#if defined( XMLSEC_CRYPTO_NSS ) + pRet = nss_component_getFactory( pImplName, pServiceManager, pRegistryKey ) ; + if( pRet != NULL ) + return pRet ; +#endif + +#if defined( XMLSEC_CRYPTO_MSCRYPTO ) + pRet = mscrypt_component_getFactory( pImplName, pServiceManager, pRegistryKey ) ; + if( pRet != NULL ) + return pRet ; +#endif + } + + return pRet ; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |