summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGökçen Eraslan <gokcen.eraslan@gmail.com>2012-07-09 10:16:17 +0300
committerGökçen Eraslan <gokcen.eraslan@gmail.com>2012-07-09 10:16:17 +0300
commit9c8dc01d3a40ec905c9d816c733ceb5d621e0426 (patch)
treeed4182827ad2645a621fcde32887f6d0c5248740
parentf8f2296a510612381fc86273d0380133d5929bf0 (diff)
parent9ba7fda79cd36a20732fee663f52bdb4946cb2cf (diff)
Merge branch 'feature/pdf-signing'
-rw-r--r--filter/inc/filter.hrc1
-rw-r--r--filter/source/pdf/impdialog.cxx155
-rw-r--r--filter/source/pdf/impdialog.hrc13
-rw-r--r--filter/source/pdf/impdialog.hxx39
-rw-r--r--filter/source/pdf/impdialog.src90
-rw-r--r--filter/source/pdf/pdfexport.cxx20
-rw-r--r--filter/source/pdf/pdfexport.hxx8
-rw-r--r--offapi/com/sun/star/security/XDocumentDigitalSignatures.idl4
-rw-r--r--vcl/inc/vcl/pdfwriter.hxx37
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx231
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx9
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.cxx23
-rw-r--r--xmlsecurity/source/component/documentdigitalsignatures.hxx1
13 files changed, 612 insertions, 19 deletions
diff --git a/filter/inc/filter.hrc b/filter/inc/filter.hrc
index dc1c348bcc05..0aac90775665 100644
--- a/filter/inc/filter.hrc
+++ b/filter/inc/filter.hrc
@@ -37,6 +37,7 @@
#define HID_FILTER_PDF_USER_INTERFACE "HID_FILTER_PDF_USER_INTERFACE"
#define HID_FILTER_PDF_SECURITY "HID_FILTER_PDF_SECURITY"
#define HID_FILTER_PDF_LINKS "HID_FILTER_PDF_LINKS"
+#define HID_FILTER_PDF_SIGNING "HID_FILTER_PDF_SIGNING"
#endif
diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 03de7492d46a..f6f9b158864f 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -32,6 +32,8 @@
#include "vcl/svapp.hxx"
#include "vcl/msgbox.hxx"
#include "sfx2/passwd.hxx"
+#include "svtools/miscopt.hxx"
+//#include "xmlsecurity/certificatechooser.hxx"
#include "comphelper/storagehelper.hxx"
@@ -40,6 +42,7 @@
#include "com/sun/star/container/XIndexAccess.hpp"
#include "com/sun/star/frame/XController.hpp"
#include "com/sun/star/view/XSelectionSupplier.hpp"
+#include "com/sun/star/security/XDocumentDigitalSignatures.hpp"
#include <boost/shared_ptr.hpp>
@@ -124,7 +127,10 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
mbExportRelativeFsysLinks( sal_False ),
mnViewPDFMode( 0 ),
mbConvertOOoTargets( sal_False ),
- mbExportBmkToPDFDestination( sal_False )
+ mbExportBmkToPDFDestination( sal_False ),
+
+ mbSignPDF( sal_False )
+
{
FreeResource();
// check for selection
@@ -241,12 +247,21 @@ ImpPDFTabDialog::ImpPDFTabDialog( Window* pParent,
mbConvertOOoTargets = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ), sal_False );
mbExportBmkToPDFDestination = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ), sal_False );
+//prepare values for digital signatures
+ mbSignPDF = maConfigItem.ReadBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignPDF" ) ), sal_False );
+
//queue the tab pages for later creation (created when first shown)
+ AddTabPage( RID_PDF_TAB_SIGNING, ImpPDFTabSigningPage::Create, 0 );
AddTabPage( RID_PDF_TAB_SECURITY, ImpPDFTabSecurityPage::Create, 0 );
AddTabPage( RID_PDF_TAB_LINKS, ImpPDFTabLinksPage::Create, 0 );
AddTabPage( RID_PDF_TAB_VPREFER, ImpPDFTabViewerPage::Create, 0 );
AddTabPage( RID_PDF_TAB_OPNFTR, ImpPDFTabOpnFtrPage::Create, 0 );
+//remove tabpage if experimentalmode is not set
+ SvtMiscOptions aMiscOptions;
+ if (!aMiscOptions.IsExperimentalMode())
+ RemoveTabPage( RID_PDF_TAB_SIGNING );
+
//last queued is the first to be displayed (or so it seems..)
AddTabPage( RID_PDF_TAB_GENER, ImpPDFTabGeneralPage::Create, 0 );
@@ -281,6 +296,11 @@ ImpPDFTabDialog::~ImpPDFTabDialog()
RemoveTabPage( RID_PDF_TAB_OPNFTR );
RemoveTabPage( RID_PDF_TAB_LINKS );
RemoveTabPage( RID_PDF_TAB_SECURITY );
+
+//remove tabpage if experimentalmode is set
+ SvtMiscOptions aMiscOptions;
+ if (aMiscOptions.IsExperimentalMode())
+ RemoveTabPage( RID_PDF_TAB_SIGNING );
}
// -----------------------------------------------------------------------------
@@ -304,6 +324,9 @@ void ImpPDFTabDialog::PageCreated( sal_uInt16 _nId,
case RID_PDF_TAB_SECURITY:
( ( ImpPDFTabSecurityPage* )&_rPage )->SetFilterConfigItem( this );
break;
+ case RID_PDF_TAB_SIGNING:
+ ( ( ImpPDFTabSigningPage* )&_rPage )->SetFilterConfigItem( this );
+ break;
}
}
@@ -329,6 +352,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
( ( ImpPDFTabLinksPage* )GetTabPage( RID_PDF_TAB_LINKS ) )->GetFilterConfigItem( this );
if( GetTabPage( RID_PDF_TAB_SECURITY ) )
( ( ImpPDFTabSecurityPage* )GetTabPage( RID_PDF_TAB_SECURITY ) )->GetFilterConfigItem( this );
+ if( GetTabPage( RID_PDF_TAB_SIGNING ) )
+ ( ( ImpPDFTabSigningPage* )GetTabPage( RID_PDF_TAB_SIGNING ) )->GetFilterConfigItem( this );
//prepare the items to be returned
maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "UseLosslessCompression" ) ), mbUseLosslessCompression );
@@ -379,6 +404,8 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ConvertOOoTargetToPDFTarget" ) ), mbConvertOOoTargets );
maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "ExportBookmarksToPDFDestination" ) ), mbExportBmkToPDFDestination );
+ maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "SignPDF" ) ), mbSignPDF );
+
maConfigItem.WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Printing" ) ), mnPrint );
maConfigItem.WriteInt32( OUString( RTL_CONSTASCII_USTRINGPARAM( "Changes" ) ), mnChangesAllowed );
maConfigItem.WriteBool( OUString( RTL_CONSTASCII_USTRINGPARAM( "EnableCopyingOfContent" ) ), mbCanCopyOrExtract );
@@ -386,7 +413,7 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
Sequence< PropertyValue > aRet( maConfigItem.GetFilterData() );
- int nElementAdded = 6;
+ int nElementAdded = 11;
aRet.realloc( aRet.getLength() + nElementAdded );
@@ -421,13 +448,35 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData()
{
aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) );
aRet[ nLength - nElementAdded ].Value <<= OUString( msPageRange );
+ nElementAdded--;
}
else if( mbSelectionIsChecked )
{
aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "Selection" ) );
aRet[ nLength - nElementAdded ].Value <<= maSelection;
+ nElementAdded--;
}
+ aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureLocation" ) );
+ aRet[ nLength - nElementAdded ].Value <<= msSignLocation;
+ nElementAdded--;
+
+ aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureReason" ) );
+ aRet[ nLength - nElementAdded ].Value <<= msSignReason;
+ nElementAdded--;
+
+ aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureContactInfo" ) );
+ aRet[ nLength - nElementAdded ].Value <<= msSignContact;
+ nElementAdded--;
+
+ aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignaturePassword" ) );
+ aRet[ nLength - nElementAdded ].Value <<= msSignPassword;
+ nElementAdded--;
+
+ aRet[ nLength - nElementAdded ].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "SignatureCertificate" ) );
+ aRet[ nLength - nElementAdded ].Value <<= maSignCertificate;
+ nElementAdded--;
+
return aRet;
}
@@ -1626,4 +1675,106 @@ IMPL_LINK_NOARG(ImplErrorDialog, SelectHdl)
return 0;
}
+////////////////////////////////////////////////////////
+// The digital signatures tab page
+// -----------------------------------------------------------------------------
+ImpPDFTabSigningPage::ImpPDFTabSigningPage( Window* pParent,
+ const SfxItemSet& rCoreSet ) :
+ SfxTabPage( pParent, PDFFilterResId( RID_PDF_TAB_SIGNING ), rCoreSet ),
+
+ maCbSignPDF( this, PDFFilterResId( CB_SIGN_PDF ) ),
+ maFtSignPassword( this, PDFFilterResId( FT_SIGN_PASSWORD ) ),
+ maEdSignPassword( this, PDFFilterResId( ED_SIGN_PASSWORD ) ),
+ maFtSignLocation( this, PDFFilterResId( FT_SIGN_LOCATION ) ),
+ maEdSignLocation( this, PDFFilterResId( ED_SIGN_LOCATION ) ),
+ maFtSignContactInfo( this, PDFFilterResId( FT_SIGN_CONTACT ) ),
+ maEdSignContactInfo( this, PDFFilterResId( ED_SIGN_CONTACT ) ),
+ maFtSignReason( this, PDFFilterResId( FT_SIGN_REASON ) ),
+ maEdSignReason( this, PDFFilterResId( ED_SIGN_REASON ) ),
+ maPbSignSelectCert( this, PDFFilterResId( BTN_SIGN_SELECT_CERT ) ),
+ maSignCertificate()
+{
+ FreeResource();
+
+ maPbSignSelectCert.SetClickHdl( LINK( this, ImpPDFTabSigningPage, ClickmaPbSignSelectCert ) );
+}
+
+// -----------------------------------------------------------------------------
+ImpPDFTabSigningPage::~ImpPDFTabSigningPage()
+{
+}
+
+IMPL_LINK_NOARG( ImpPDFTabSigningPage, ClickmaPbSignSelectCert )
+{
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[0] <<= rtl::OUString("1.2");
+ aArgs[1] <<= sal_False;
+
+ Reference< security::XDocumentDigitalSignatures > xSigner(
+ comphelper::getProcessServiceFactory()->createInstanceWithArguments(
+ rtl::OUString( "com.sun.star.security.DocumentDigitalSignatures" ), aArgs ),
+ uno::UNO_QUERY );
+
+ if ( !xSigner.is() )
+ return 0;
+
+ maSignCertificate = xSigner->chooseCertificate();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+SfxTabPage* ImpPDFTabSigningPage::Create( Window* pParent,
+ const SfxItemSet& rAttrSet)
+{
+ return ( new ImpPDFTabSigningPage( pParent, rAttrSet ) );
+}
+
+// -----------------------------------------------------------------------------
+void ImpPDFTabSigningPage::GetFilterConfigItem( ImpPDFTabDialog* paParent )
+{
+ paParent->mbSignPDF = maCbSignPDF.IsChecked();
+ paParent->msSignLocation = maEdSignLocation.GetText();
+ paParent->msSignPassword = maEdSignPassword.GetText();
+ paParent->msSignContact = maEdSignContactInfo.GetText();
+ paParent->msSignReason = maEdSignReason.GetText();
+ paParent->maSignCertificate = maSignCertificate;
+
+}
+
+// -----------------------------------------------------------------------------
+void ImpPDFTabSigningPage::SetFilterConfigItem( const ImpPDFTabDialog* paParent )
+{
+
+ maCbSignPDF.SetToggleHdl( LINK( this, ImpPDFTabSigningPage, ToggleSignPDFHdl ) );
+ maEdSignLocation.Enable( false );
+ maEdSignPassword.Enable( false );
+ maEdSignContactInfo.Enable( false );
+ maEdSignReason.Enable( false );
+ maPbSignSelectCert.Enable( false );
+
+ if (paParent->mbSignPDF)
+ {
+ maCbSignPDF.Check();
+ maEdSignPassword.SetText(paParent->msSignPassword);
+ maEdSignLocation.SetText(paParent->msSignLocation);
+ maEdSignContactInfo.SetText(paParent->msSignContact);
+ maEdSignReason.SetText(paParent->msSignReason);
+ maSignCertificate = paParent->maSignCertificate;
+ }
+}
+
+// -----------------------------------------------------------------------------
+IMPL_LINK_NOARG(ImpPDFTabSigningPage, ToggleSignPDFHdl)
+{
+ maEdSignPassword.Enable( maCbSignPDF.IsChecked() );
+ maEdSignLocation.Enable( maCbSignPDF.IsChecked() );
+ maEdSignContactInfo.Enable( maCbSignPDF.IsChecked() );
+ maEdSignReason.Enable( maCbSignPDF.IsChecked() );
+ maPbSignSelectCert.Enable( maCbSignPDF.IsChecked() );
+
+ return 0;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc
index 7a4630ed833f..110bae0e94bd 100644
--- a/filter/source/pdf/impdialog.hrc
+++ b/filter/source/pdf/impdialog.hrc
@@ -24,6 +24,7 @@
#define RID_PDF_TAB_OPNFTR (RID_PDF_DIALOG_START + 3)
#define RID_PDF_TAB_SECURITY (RID_PDF_DIALOG_START + 4)
#define RID_PDF_TAB_LINKS (RID_PDF_DIALOG_START + 12)
+#define RID_PDF_TAB_SIGNING (RID_PDF_DIALOG_START + 13)
#define RID_PDF_WARNPDFAPASSWORD (RID_PDF_DIALOG_START + 6)
//strings
@@ -177,3 +178,15 @@
#define FL_INITVIEW_VERTICAL 158
#define FL_VPREFER_VERTICAL 158
#define FL_SECURITY_VERTICAL 160
+
+//controls for digital signatures tab page
+#define CB_SIGN_PDF 170
+#define FT_SIGN_PASSWORD 171
+#define ED_SIGN_PASSWORD 172
+#define FT_SIGN_LOCATION 173
+#define ED_SIGN_LOCATION 174
+#define FT_SIGN_CONTACT 175
+#define ED_SIGN_CONTACT 176
+#define FT_SIGN_REASON 177
+#define ED_SIGN_REASON 178
+#define BTN_SIGN_SELECT_CERT 179
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index acbedaffcc42..45747fd5c6d0 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -148,6 +148,14 @@ protected:
sal_Int32 mnViewPDFMode;
sal_Bool mbConvertOOoTargets;
sal_Bool mbExportBmkToPDFDestination;
+
+ sal_Bool mbSignPDF;
+ ::rtl::OUString msSignPassword;
+ ::rtl::OUString msSignLocation;
+ ::rtl::OUString msSignContact;
+ ::rtl::OUString msSignReason;
+ com::sun::star::uno::Reference< com::sun::star::security::XCertificate > maSignCertificate;
+
::rtl::OUString maWatermarkText;
public:
@@ -157,6 +165,7 @@ public:
friend class ImpPDFTabOpnFtrPage;
friend class ImpPDFTabSecurityPage;
friend class ImpPDFTabLinksPage;
+ friend class ImpPDFTabSigningPage;
ImpPDFTabDialog( Window* pParent,
Sequence< PropertyValue >& rFilterData,
@@ -429,6 +438,36 @@ public:
void ImplPDFALinkControl( sal_Bool bEnableLaunch );
};
+//class to implement the digital signing
+class ImpPDFTabSigningPage : public SfxTabPage
+{
+ CheckBox maCbSignPDF;
+ FixedText maFtSignPassword;
+ Edit maEdSignPassword;
+ FixedText maFtSignLocation;
+ Edit maEdSignLocation;
+ FixedText maFtSignContactInfo;
+ Edit maEdSignContactInfo;
+ FixedText maFtSignReason;
+ Edit maEdSignReason;
+ PushButton maPbSignSelectCert;
+ com::sun::star::uno::Reference< com::sun::star::security::XCertificate > maSignCertificate;
+
+ DECL_LINK( ToggleSignPDFHdl, void* );
+ DECL_LINK( ClickmaPbSignSelectCert, void* );
+
+public:
+ ImpPDFTabSigningPage( Window* pParent,
+ const SfxItemSet& rSet );
+
+ ~ImpPDFTabSigningPage();
+ static SfxTabPage* Create( Window* pParent,
+ const SfxItemSet& rAttrSet );
+
+ void GetFilterConfigItem( ImpPDFTabDialog* paParent);
+ void SetFilterConfigItem( const ImpPDFTabDialog* paParent );
+};
+
#endif // IMPDIALOG_HXX
diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src
index 8c73d20690d9..afae67e7eab1 100644
--- a/filter/source/pdf/impdialog.src
+++ b/filter/source/pdf/impdialog.src
@@ -817,6 +817,91 @@ TabPage RID_PDF_TAB_SECURITY
};
//----------------------------------------------------------
+//tab page for PDF Export, digital signatures
+TabPage RID_PDF_TAB_SIGNING
+{
+ HelpId = HID_FILTER_PDF_SIGNING ;
+ Text [ en-US ] = "Digital Signatures";
+ TAB_PDF_SIZE;
+ Hide = TRUE;
+
+ CheckBox CB_SIGN_PDF
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 164 , 16 ) ;
+ TabStop = TRUE ;
+ WordBreak = TRUE ;
+ Text[ en-US ] = "Sign PDF file" ;
+ };
+
+ PushButton BTN_SIGN_SELECT_CERT
+ {
+ TabStop = TRUE ;
+ Disable = TRUE ;
+ Pos = MAP_APPFONT ( 12, 17 ) ;
+ Size = MAP_APPFONT ( 120 , 13 ) ;
+ Text[ en-US ] = "Select c~ertificate...";
+ };
+
+ FixedText FT_SIGN_PASSWORD
+ {
+ Pos = MAP_APPFONT( 12, 35 );
+ Size = MAP_APPFONT( 109, 10 );
+ Text[ en-US ] = "Certificate Password";
+ };
+
+ Edit ED_SIGN_PASSWORD
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 102, 35 ) ;
+ Size = MAP_APPFONT ( 68 , 12 ) ;
+ };
+
+ FixedText FT_SIGN_LOCATION
+ {
+ Pos = MAP_APPFONT( 12, 48 );
+ Size = MAP_APPFONT( 109, 10 );
+ Text[ en-US ] = "Location";
+ };
+
+ Edit ED_SIGN_LOCATION
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 102, 48 ) ;
+ Size = MAP_APPFONT ( 68 , 12 ) ;
+ };
+
+ FixedText FT_SIGN_CONTACT
+ {
+ Pos = MAP_APPFONT( 12, 61 );
+ Size = MAP_APPFONT( 109, 10 );
+ Text[ en-US ] = "Contact Information";
+ };
+
+ Edit ED_SIGN_CONTACT
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 102, 61 ) ;
+ Size = MAP_APPFONT ( 68 , 12 ) ;
+ };
+
+ FixedText FT_SIGN_REASON
+ {
+ Pos = MAP_APPFONT( 12, 74 );
+ Size = MAP_APPFONT( 109, 10 );
+ Text[ en-US ] = "Reason";
+ };
+
+ Edit ED_SIGN_REASON
+ {
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 102, 74 ) ;
+ Size = MAP_APPFONT ( 68 , 12 ) ;
+ };
+
+};
+
+//----------------------------------------------------------
//tab page for PDF Export, links management
TabPage RID_PDF_TAB_LINKS
{
@@ -930,6 +1015,11 @@ TabDialog RID_PDF_EXPORT_DLG
Identifier = RID_PDF_TAB_SECURITY;
Text [ en-US ] = "Security";
};
+ PageItem
+ {
+ Identifier = RID_PDF_TAB_SIGNING;
+ Text [ en-US ] = "Digital Signatures";
+ };
};
};
};
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index db93010d1ee1..30727c6773f1 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -554,6 +554,18 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
rFilterData[ nData ].Value >>= mbExportHiddenSlides;
else if ( rFilterData[ nData ].Name == "OpenBookmarkLevels" )
rFilterData[ nData ].Value >>= mnOpenBookmarkLevels;
+ else if ( rFilterData[ nData ].Name == "SignPDF" )
+ rFilterData[ nData ].Value >>= mbSignPDF;
+ else if ( rFilterData[ nData ].Name == "SignatureLocation" )
+ rFilterData[ nData ].Value >>= msSignLocation;
+ else if ( rFilterData[ nData ].Name == "SignatureReason" )
+ rFilterData[ nData ].Value >>= msSignReason;
+ else if ( rFilterData[ nData ].Name == "SignatureContactInfo" )
+ rFilterData[ nData ].Value >>= msSignContact;
+ else if ( rFilterData[ nData ].Name == "SignaturePassword" )
+ rFilterData[ nData ].Value >>= msSignPassword;
+ else if ( rFilterData[ nData ].Name == "SignatureCertificate" )
+ rFilterData[ nData ].Value >>= maSignCertificate;
}
aContext.URL = aURL.GetMainURL(INetURLObject::DECODE_TO_IURI);
@@ -781,6 +793,14 @@ sal_Bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue
aContext.ForcePDFAction = sal_False;
}
}
+
+ aContext.SignPDF = mbSignPDF;
+ aContext.SignLocation = msSignLocation;
+ aContext.SignContact = msSignContact;
+ aContext.SignReason = msSignReason;
+ aContext.SignPassword = msSignPassword;
+ aContext.SignCertificate = maSignCertificate;
+
// all context data set, time to create the printing device
PDFWriter* pPDFWriter = new PDFWriter( aContext, xEnc );
OutputDevice* pOut = pPDFWriter->GetReferenceDevice();
diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx
index a571cd44dbe6..4c884ee5d568 100644
--- a/filter/source/pdf/pdfexport.hxx
+++ b/filter/source/pdf/pdfexport.hxx
@@ -111,6 +111,14 @@ private:
sal_Bool mbExportBmkToDest;
sal_Bool ImplExportPage( ::vcl::PDFWriter& rWriter, ::vcl::PDFExtOutDevData& rPDFExtOutDevData,
const GDIMetaFile& rMtf );
+
+ sal_Bool mbSignPDF;
+ OUString msSignLocation;
+ OUString msSignContact;
+ OUString msSignReason;
+ OUString msSignPassword;
+ Reference< security::XCertificate > maSignCertificate;
+
void ImplWriteWatermark( ::vcl::PDFWriter& rWriter, const Size& rPageSize );
public:
diff --git a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
index be75dc1dee3d..8e9089e75495 100644
--- a/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
+++ b/offapi/com/sun/star/security/XDocumentDigitalSignatures.idl
@@ -143,7 +143,9 @@ interface XDocumentDigitalSignatures : com::sun::star::uno::XInterface
void addAuthorToTrustedSources( [in] com::sun::star::security::XCertificate Author );
void addLocationToTrustedSources( [in] string Location );
-
+ /** This method shows CertificateChooser dialog, used by document and PDF signing
+ */
+ com::sun::star::security::XCertificate chooseCertificate();
} ;
diff --git a/vcl/inc/vcl/pdfwriter.hxx b/vcl/inc/vcl/pdfwriter.hxx
index cb6d271dfe73..0e93cdd9c6a1 100644
--- a/vcl/inc/vcl/pdfwriter.hxx
+++ b/vcl/inc/vcl/pdfwriter.hxx
@@ -41,6 +41,7 @@
#include "com/sun/star/io/XOutputStream.hpp"
#include "com/sun/star/beans/XMaterialHolder.hpp"
+#include "com/sun/star/security/XCertificate.hpp"
#include "com/sun/star/lang/Locale.hpp"
#include <boost/scoped_ptr.hpp>
@@ -197,7 +198,8 @@ public:
enum WidgetType
{
- PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox, Hierarchy
+ PushButton, RadioButton, CheckBox, Edit, ListBox, ComboBox, Hierarchy,
+ Signature
};
enum WidgetState
@@ -449,6 +451,28 @@ public:
}
};
+ struct SignatureWidget: public AnyWidget
+ {
+ // Use Sig prefix for members to avoid conflict with
+ // the Location member of the AnyWidget which spcifies the coordinates
+ // of the signature
+
+ rtl::OUString SigLocation;
+ rtl::OUString SigReason;
+ rtl::OUString SigContactInfo;
+ bool SigHidden;
+
+ SignatureWidget()
+ : AnyWidget( vcl::PDFWriter::Signature ),
+ SigHidden( true )
+ {}
+
+ virtual AnyWidget* Clone() const
+ {
+ return new SignatureWidget( *this );
+ }
+ };
+
enum ExportDataFormat { HTML, XML, FDF, PDF };
// see 3.6.1 of PDF 1.4 ref for details, used for 8.1 PDF v 1.4 ref also
// These emuns are treated as integer while reading/writing to configuration
@@ -606,6 +630,13 @@ The following structure describes the permissions used in PDF security
PDFWriter::PDFEncryptionProperties Encryption;
PDFWriter::PDFDocInfo DocumentInfo;
+ bool SignPDF;
+ rtl::OUString SignLocation;
+ rtl::OUString SignPassword;
+ rtl::OUString SignReason;
+ rtl::OUString SignContact;
+ com::sun::star::uno::Reference< com::sun::star::security::XCertificate> SignCertificate;
+
com::sun::star::lang::Locale DocumentLocale; // defines the document default language
sal_uInt32 DPIx, DPIy; // how to handle MapMode( MAP_PIXEL )
// 0 here specifies a default handling
@@ -637,9 +668,11 @@ The following structure describes the permissions used in PDF security
InitialPage( 1 ),
OpenBookmarkLevels( -1 ),
Encryption(),
+ SignPDF( false ),
DPIx( 0 ),
DPIy( 0 ),
- ColorMode( PDFWriter::DrawColor )
+ ColorMode( PDFWriter::DrawColor ),
+ SignCertificate( 0 )
{}
};
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 5eb5ad7e41ab..f89bbebe2b38 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -74,6 +74,7 @@
#include <lcms2.h>
#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/util/URLTransformer.hpp>
@@ -97,6 +98,8 @@ using ::rtl::OUStringBuffer;
#define DEBUG_DISABLE_PDFCOMPRESSION // also do not compress streams
#endif
+#define MAX_SIGNATURE_CONTENT_LENGTH 0x4000
+
#ifdef DO_TEST_PDF
class PDFTestOutputStream : public PDFOutputStream
{
@@ -135,6 +138,11 @@ void doTestCode()
aContext.DocumentInfo.Title = OUString( "PDF export test document" );
aContext.DocumentInfo.Producer = OUString( "VCL" );
+ aContext.SignPDF = true;
+ aContext.SignLocation = OUString( "Burdur" );
+ aContext.SignReason = OUString( "Some valid reason to sign" );
+ aContext.SignContact = OUString( "signer@example.com" );
+
com::sun::star::uno::Reference< com::sun::star::beans::XMaterialHolder > xEnc;
PDFWriter aWriter( aContext, xEnc );
aWriter.NewPage( 595, 842 );
@@ -520,6 +528,7 @@ void doTestCode()
aWriter.CreateOutlineItem( nPage2OL, OUString( "Dest 1" ), nFirstDest );
aWriter.EndStructureElement(); // close document
+
aWriter.Emit();
}
#endif
@@ -1755,6 +1764,9 @@ void PDFWriterImpl::PDFPage::appendWaveLine( sal_Int32 nWidth, sal_Int32 nY, sal
m_eInheritedOrientation( PDFWriter::Portrait ),
m_nCurrentPage( -1 ),
m_nResourceDict( -1 ),
+ m_nSignatureObject( -1 ),
+ m_nSignatureContentOffset( 0 ),
+ m_nSignatureLastByteRangeNoOffset( 0 ),
m_nFontDictObject( -1 ),
m_pCodec( NULL ),
m_aDocDigest( rtl_digest_createMD5() ),
@@ -5452,15 +5464,29 @@ bool PDFWriterImpl::emitWidgetAnnotations()
// emit widget annotation only for terminal fields
if( rWidget.m_aKids.empty() )
{
- aLine.append( "/Type/Annot/Subtype/Widget/F 4\n"
- "/Rect[" );
- appendFixedInt( rWidget.m_aRect.Left()-1, aLine );
+ int iRectMargin;
+
+ aLine.append( "/Type/Annot/Subtype/Widget/F " );
+
+ if (rWidget.m_eType == PDFWriter::Signature)
+ {
+ aLine.append( "132\n" ); // Print & Locked
+ iRectMargin = 0;
+ }
+ else
+ {
+ aLine.append( "4\n" );
+ iRectMargin = 1;
+ }
+
+ aLine.append("/Rect[" );
+ appendFixedInt( rWidget.m_aRect.Left()-iRectMargin, aLine );
aLine.append( ' ' );
- appendFixedInt( rWidget.m_aRect.Top()+1, aLine );
+ appendFixedInt( rWidget.m_aRect.Top()+iRectMargin, aLine );
aLine.append( ' ' );
- appendFixedInt( rWidget.m_aRect.Right()+1, aLine );
+ appendFixedInt( rWidget.m_aRect.Right()+iRectMargin, aLine );
aLine.append( ' ' );
- appendFixedInt( rWidget.m_aRect.Bottom()-1, aLine );
+ appendFixedInt( rWidget.m_aRect.Bottom()-iRectMargin, aLine );
aLine.append( "]\n" );
}
aLine.append( "/FT/" );
@@ -5515,6 +5541,10 @@ bool PDFWriterImpl::emitWidgetAnnotations()
aLine.append( "Tx" );
appendUnicodeTextStringEncrypt( rWidget.m_aValue, rWidget.m_nObject, aValue );
break;
+ case PDFWriter::Signature:
+ aLine.append( "Sig" );
+ aValue.append(OUStringToOString(rWidget.m_aValue, RTL_TEXTENCODING_ASCII_US));
+ break;
case PDFWriter::Hierarchy: // make the compiler happy
break;
}
@@ -5877,6 +5907,14 @@ bool PDFWriterImpl::emitCatalog()
}
else
aInitPageRef.append( "0" );
+
+ if (m_nSignatureObject != -1) // Document will be signed
+ {
+ aLine.append("/Perms<</DocMDP ");
+ aLine.append(m_nSignatureObject);
+ aLine.append(" 0 R>>");
+ }
+
switch( m_aContext.PDFDocumentAction )
{
case PDFWriter::ActionDefault : //do nothing, this is the Acrobat default
@@ -6001,10 +6039,16 @@ bool PDFWriterImpl::emitCatalog()
aLine.append( (nOut++ % 5)==4 ? " 0 R\n" : " 0 R " );
}
}
- aLine.append( "\n]/DR " );
+ aLine.append( "\n]" );
+
+ if (m_nSignatureObject != -1)
+ aLine.append( "/SigFlags 3");
+
+ aLine.append( "/DR " );
aLine.append( getResourceDictObj() );
aLine.append( " 0 R" );
- if( m_bIsPDF_A1 )
+ // /NeedAppearances must not be used if PDF is signed
+ if( m_bIsPDF_A1 || ( m_nSignatureObject != -1 ) )
aLine.append( ">>\n" );
else
aLine.append( "/NeedAppearances true>>\n" );
@@ -6031,6 +6075,129 @@ bool PDFWriterImpl::emitCatalog()
return true;
}
+bool PDFWriterImpl::emitSignature()
+{
+ if( !updateObject( m_nSignatureObject ) )
+ return false;
+
+ OStringBuffer aLine( 0x5000 );
+ aLine.append( m_nSignatureObject );
+ aLine.append( " 0 obj\n" );
+ aLine.append("<</Reference[<</Data ");
+ aLine.append( m_nCatalogObject );
+ aLine.append(" 0 R/Type/SigRef/TransformParams<</Type/TransformParams"
+ "/V/1.2/P 1>>/DigestMethod/MD5/DigestLocation[0 0]"
+ "/DigestValue(aa)/TransformMethod/DocMDP>>]/Contents <" );
+
+ sal_uInt64 nOffset = ~0U;
+ CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nOffset ) ) );
+ DBG_ASSERT( aError == osl_File_E_None, "could not get file position" );
+
+ m_nSignatureContentOffset = nOffset + aLine.getLength();
+
+ // reserve some space for the PKCS#7 object
+ OStringBuffer aContentFiller( MAX_SIGNATURE_CONTENT_LENGTH );
+ comphelper::string::padToLength(aContentFiller, MAX_SIGNATURE_CONTENT_LENGTH, '0');
+ aLine.append( aContentFiller.makeStringAndClear() );
+ aLine.append( ">\n/Type/Sig/SubFilter/adbe.pkcs7.sha1");
+
+ if( m_aContext.DocumentInfo.Author.Len() )
+ {
+ aLine.append( "/Name" );
+ appendUnicodeTextStringEncrypt( m_aContext.DocumentInfo.Author, m_nSignatureObject, aLine );
+ }
+
+ aLine.append( " /M ");
+ appendLiteralStringEncrypt( m_aCreationDateString, m_nSignatureObject, aLine );
+
+ aLine.append( " /ByteRange [ 0 ");
+ aLine.append( m_nSignatureContentOffset - 1, 10 );
+ aLine.append( " " );
+ aLine.append( m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1, 10 );
+ aLine.append( " " );
+
+ m_nSignatureLastByteRangeNoOffset = nOffset + aLine.getLength();
+
+ // mark the last ByteRange no and add some space. Now, we don't know
+ // how many bytes we need for this ByteRange value
+ // The real value will be overwritten in the finalizeSignature method
+ OStringBuffer aByteRangeFiller( 100 );
+ comphelper::string::padToLength(aByteRangeFiller, 100, ' ');
+ aLine.append( aByteRangeFiller.makeStringAndClear() );
+ aLine.append(" /Filter/Adobe.PPKMS");
+
+ //emit reason, location and contactinfo
+ if ( !m_aContext.SignReason.isEmpty() )
+ {
+ aLine.append("/Reason");
+ appendUnicodeTextStringEncrypt( m_aContext.SignReason, m_nSignatureObject, aLine );
+ }
+
+ if ( !m_aContext.SignLocation.isEmpty() )
+ {
+ aLine.append("/Location");
+ appendUnicodeTextStringEncrypt( m_aContext.SignLocation, m_nSignatureObject, aLine );
+ }
+
+ if ( !m_aContext.SignContact.isEmpty() )
+ {
+ aLine.append("/ContactInfo");
+ appendUnicodeTextStringEncrypt( m_aContext.SignContact, m_nSignatureObject, aLine );
+ }
+
+ aLine.append(" >>\nendobj\n\n" );
+
+ if (!writeBuffer( aLine.getStr(), aLine.getLength() ))
+ return false;
+
+ return true;
+}
+
+bool PDFWriterImpl::finalizeSignature()
+{
+
+ if (!m_aContext.SignCertificate.is())
+ return false;
+
+ // 1- calculate last ByteRange value
+ sal_uInt64 nOffset = ~0U;
+ CHECK_RETURN( (osl_File_E_None == osl_getFilePos( m_aFile, &nOffset ) ) );
+
+ sal_Int64 nLastByteRangeNo = nOffset - (m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH) - 1;
+
+ // 2- overwrite the value to the m_nSignatureLastByteRangeNoOffset position
+ sal_uInt64 nWritten = 0;
+ CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureLastByteRangeNoOffset ) ) );
+ OStringBuffer aByteRangeNo( 256 );
+ aByteRangeNo.append( nLastByteRangeNo, 10);
+ aByteRangeNo.append( " ]" );
+
+ if( osl_writeFile( m_aFile, aByteRangeNo.getStr(), aByteRangeNo.getLength(), &nWritten ) != osl_File_E_None )
+ {
+ CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset ) ) );
+ return false;
+ }
+
+ // 3- create the PKCS#7 object using NSS
+ // use m_aContext.SignCertificate and m_aContext.SignPassword as certificate and private key password
+ // SignCertificate->getEncoded is DER encoded certificate
+ com::sun::star::uno::Sequence< sal_Int8 > derEncoded = m_aContext.SignCertificate->getEncoded();
+
+ if (!derEncoded.hasElements())
+ return false;
+
+ sal_Int8* n_derArray = derEncoded.getArray();
+ sal_Int32 n_derLength = derEncoded.getLength();
+
+ // 4- overwrite the PKCS7 content to the m_nSignatureContentOffset
+ CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset ) ) );
+ // osl_writeFile()
+
+ // revert the file position back
+ CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset ) ) );
+ return true;
+}
+
sal_Int32 PDFWriterImpl::emitInfoDict( )
{
sal_Int32 nObject = createObject();
@@ -6812,15 +6979,29 @@ bool PDFWriterImpl::emit()
// needed for widget tab order
sortWidgets();
+ if( m_aContext.SignPDF )
+ {
+ // sign the document
+ PDFWriter::SignatureWidget aSignature;
+ aSignature.Name = OUString("Signature1");
+ createControl( aSignature, 0 );
+ }
+
// emit additional streams
CHECK_RETURN( emitAdditionalStreams() );
// emit catalog
CHECK_RETURN( emitCatalog() );
+ if (m_nSignatureObject != -1) // if document is signed, emit sigdict
+ CHECK_RETURN( emitSignature() );
+
// emit trailer
CHECK_RETURN( emitTrailer() );
+ if (m_nSignatureObject != -1) // finalize the signature
+ CHECK_RETURN( finalizeSignature() );
+
osl_closeFile( m_aFile );
m_bOpen = false;
@@ -11552,13 +11733,14 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
if( nPageNr < 0 || nPageNr >= (sal_Int32)m_aPages.size() )
return -1;
+ bool sigHidden;
sal_Int32 nNewWidget = m_aWidgets.size();
m_aWidgets.push_back( PDFWidget() );
m_aWidgets.back().m_nObject = createObject();
- m_aWidgets.back().m_aRect = rControl.Location;
- m_aWidgets.back().m_nPage = nPageNr;
- m_aWidgets.back().m_eType = rControl.getType();
+ m_aWidgets.back().m_aRect = rControl.Location;
+ m_aWidgets.back().m_nPage = nPageNr;
+ m_aWidgets.back().m_eType = rControl.getType();
sal_Int32 nRadioGroupWidget = -1;
// for unknown reasons the radio buttons of a radio group must not have a
@@ -11716,10 +11898,31 @@ sal_Int32 PDFWriterImpl::createControl( const PDFWriter::AnyWidget& rControl, sa
createDefaultEditAppearance( rNewWidget, rEdit );
}
+ else if( rControl.getType() == PDFWriter::Signature)
+ {
+ const PDFWriter::SignatureWidget& rSig = static_cast<const PDFWriter::SignatureWidget&>(rControl);
+ sigHidden = rSig.SigHidden;
- // convert to default user space now, since the mapmode may change
- // note: create default appearances before m_aRect gets transformed
- m_aPages[ nPageNr ].convertRect( rNewWidget.m_aRect );
+ if ( sigHidden )
+ rNewWidget.m_aRect = Rectangle(0, 0, 0, 0);
+
+ m_nSignatureObject = createObject();
+ rNewWidget.m_aValue = OUString::valueOf( m_nSignatureObject );
+ rNewWidget.m_aValue += OUString(" 0 R");
+ //createDefaultSignatureAppearance( rNewWidget, rSig );
+ // let's add a fake appearance
+ rNewWidget.m_aAppearances[ "N" ][ "Standard" ] = new SvMemoryStream();
+ }
+
+
+ // if control is a hidden signature, do not convert coordinates since we
+ // need /Rect [ 0 0 0 0 ]
+ if ( ! ( ( rControl.getType() == PDFWriter::Signature ) && ( sigHidden ) ) )
+ {
+ // convert to default user space now, since the mapmode may change
+ // note: create default appearances before m_aRect gets transformed
+ m_aPages[ nPageNr ].convertRect( rNewWidget.m_aRect );
+ }
// insert widget to page's annotation list
m_aPages[ nPageNr ].m_aAnnotations.push_back( rNewWidget.m_nObject );
diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx
index 36429a004c6d..2f3a6b3bbbaf 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -678,6 +678,10 @@ private:
sal_Int32 m_nCurrentPage;
sal_Int32 m_nCatalogObject;
+ // object number of the main signature dictionary
+ sal_Int32 m_nSignatureObject;
+ sal_Int64 m_nSignatureContentOffset;
+ sal_Int64 m_nSignatureLastByteRangeNoOffset;
sal_Int32 m_nResourceDict;
ResourceDict m_aGlobalResourceDict;
sal_Int32 m_nFontDictObject;
@@ -950,6 +954,11 @@ i12626
sal_Int32 emitStructParentTree( sal_Int32 nTreeObject );
// writes page tree and catalog
bool emitCatalog();
+ // writes signature dictionary object
+ bool emitSignature();
+ // creates a PKCS7 object using the ByteRange and overwrite /Contents
+ // of the signature dictionary
+ bool finalizeSignature();
// writes xref and trailer
bool emitTrailer();
// emit additional streams collected; also create there object numbers
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.cxx b/xmlsecurity/source/component/documentdigitalsignatures.cxx
index 3282dfede4d3..f52c1a4411d0 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.cxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.cxx
@@ -28,6 +28,7 @@
#include <documentdigitalsignatures.hxx>
#include <xmlsecurity/digitalsignaturesdialog.hxx>
+#include <xmlsecurity/certificatechooser.hxx>
#include <xmlsecurity/certificateviewer.hxx>
#include <xmlsecurity/macrosecurity.hxx>
#include <xmlsecurity/biginteger.hxx>
@@ -424,6 +425,28 @@ void DocumentDigitalSignatures::showCertificate(
return bFound;
}
+Reference< css::security::XCertificate > DocumentDigitalSignatures::chooseCertificate() throw (RuntimeException)
+{
+ Reference< dcss::xml::crypto::XSecurityEnvironment > xSecEnv;
+
+ XMLSignatureHelper aSignatureHelper( mxCtx );
+ if ( aSignatureHelper.Init() )
+ xSecEnv = aSignatureHelper.GetSecurityEnvironment();
+
+ CertificateChooser aChooser( NULL, mxCtx, xSecEnv, aSignatureHelper.GetSignatureInformations());
+
+ if (aChooser.Execute() != RET_OK)
+ return Reference< css::security::XCertificate >(0);
+
+ Reference< css::security::XCertificate > xCert = aChooser.GetSelectedCertificate();
+
+ if ( !xCert.is() )
+ return Reference< css::security::XCertificate >(0);
+
+ return xCert;
+}
+
+
::sal_Bool DocumentDigitalSignatures::isLocationTrusted( const ::rtl::OUString& Location ) throw (RuntimeException)
{
sal_Bool bFound = sal_False;
diff --git a/xmlsecurity/source/component/documentdigitalsignatures.hxx b/xmlsecurity/source/component/documentdigitalsignatures.hxx
index 03bf1b926d75..141bc911ca1d 100644
--- a/xmlsecurity/source/component/documentdigitalsignatures.hxx
+++ b/xmlsecurity/source/component/documentdigitalsignatures.hxx
@@ -85,6 +85,7 @@ public:
void SAL_CALL addAuthorToTrustedSources( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& Author ) throw (::com::sun::star::uno::RuntimeException);
void SAL_CALL addLocationToTrustedSources( const ::rtl::OUString& Location ) throw (::com::sun::star::uno::RuntimeException);
+ ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate > SAL_CALL chooseCertificate( ) throw (::com::sun::star::uno::RuntimeException);
};
com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL DocumentDigitalSignatures_CreateInstance(