xref: /AOO41X/main/xmlsecurity/tools/standalone/csfit/signer.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlsecurity.hxx"
26 
27 #include <stdio.h>
28 #include "helper.hxx"
29 
30 #include "libxml/tree.h"
31 #include "libxml/parser.h"
32 #ifndef XMLSEC_NO_XSLT
33 #include "libxslt/xslt.h"
34 #endif
35 
36 #include "securityenvironment_nssimpl.hxx"
37 #include "xmlelementwrapper_xmlsecimpl.hxx"
38 
39 #include "nspr.h"
40 #include "prtypes.h"
41 
42 #include "pk11func.h"
43 #include "cert.h"
44 #include "cryptohi.h"
45 #include "certdb.h"
46 #include "nss.h"
47 
48 #include "xmlsec/strings.h"
49 #include "xmlsec/xmltree.h"
50 
51 #include <rtl/ustring.hxx>
52 
53 #include <com/sun/star/beans/PropertyValue.hpp>
54 #include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
55 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp>
56 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
57 #include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp>
58 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
59 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
60 
61 using namespace ::rtl ;
62 using namespace ::cppu ;
63 using namespace ::com::sun::star::uno ;
64 using namespace ::com::sun::star::io ;
65 using namespace ::com::sun::star::ucb ;
66 using namespace ::com::sun::star::beans ;
67 using namespace ::com::sun::star::document ;
68 using namespace ::com::sun::star::lang ;
69 using namespace ::com::sun::star::xml::wrapper ;
70 using namespace ::com::sun::star::xml::crypto ;
71 
72 
main(int argc,char ** argv)73 int SAL_CALL main( int argc, char **argv )
74 {
75     CERTCertDBHandle*   certHandle ;
76     PK11SlotInfo*       slot ;
77     xmlDocPtr           doc ;
78     xmlNodePtr          tplNode ;
79     xmlNodePtr          tarNode ;
80     xmlAttrPtr          idAttr ;
81     xmlChar*            idValue ;
82     xmlAttrPtr          uriAttr ;
83     xmlChar*            uriValue ;
84     OUString*           uri ;
85     Reference< XUriBinding >    xUriBinding ;
86     FILE*               dstFile ;
87 
88     if( argc != 5 ) {
89         fprintf( stderr, "Usage: %s < CertDir > <file_url of template> <file_url of result> <rdb file>\n\n" , argv[0] ) ;
90         return 1 ;
91     }
92 
93     for( int hhh = 0 ; hhh < 10 ; hhh ++ ) {
94         slot = NULL ;
95         doc = NULL ;
96         uri = NULL ;
97         dstFile = NULL ;
98 
99 
100     //Init libxml and libxslt libraries
101     xmlInitParser();
102     LIBXML_TEST_VERSION
103     xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
104     xmlSubstituteEntitiesDefault(1);
105 
106     #ifndef XMLSEC_NO_XSLT
107     xmlIndentTreeOutput = 1;
108     #endif // XMLSEC_NO_XSLT
109 
110 
111     //Initialize NSPR and NSS
112     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1 ) ;
113     PK11_SetPasswordFunc( PriPK11PasswordFunc ) ;
114     if( NSS_Init( argv[1] ) != SECSuccess ) {
115         fprintf( stderr , "### cannot intialize NSS!\n" ) ;
116         goto done ;
117     }
118 
119     certHandle = CERT_GetDefaultCertDB() ;
120     slot = PK11_GetInternalKeySlot() ;
121 
122     if( PK11_NeedLogin( slot ) ) {
123         SECStatus nRet = PK11_Authenticate( slot, PR_TRUE, NULL );
124         if( nRet != SECSuccess ) {
125             fprintf( stderr , "### cannot authehticate the crypto token!\n" ) ;
126             goto done ;
127         }
128     }
129 
130     //Load XML document
131     doc = xmlParseFile( argv[2] ) ;
132     if( doc == NULL || xmlDocGetRootElement( doc ) == NULL ) {
133         fprintf( stderr , "### Cannot load template xml document!\n" ) ;
134         goto done ;
135     }
136 
137     //Find the signature template
138     tplNode = xmlSecFindNode( xmlDocGetRootElement( doc ), xmlSecNodeSignature, xmlSecDSigNs ) ;
139     if( tplNode == NULL ) {
140         fprintf( stderr , "### Cannot find the signature template!\n" ) ;
141         goto done ;
142     }
143 
144     //Find the element with ID attribute
145     //Here we only try to find the "document" node.
146     tarNode = xmlSecFindNode( xmlDocGetRootElement( doc ), ( xmlChar* )"document", ( xmlChar* )"http://openoffice.org/2000/office" ) ;
147     if( tarNode == NULL ) {
148         tarNode = xmlSecFindNode( xmlDocGetRootElement( doc ), ( xmlChar* )"document", NULL ) ;
149     }
150 
151     //Find the "id" attrbute in the element
152     if( tarNode != NULL ) {
153         if( ( idAttr = xmlHasProp( tarNode, ( xmlChar* )"id" ) ) != NULL ) {
154             //NULL
155         } else if( ( idAttr = xmlHasProp( tarNode, ( xmlChar* )"Id" ) ) != NULL ) {
156             //NULL
157         } else {
158             idAttr = NULL ;
159         }
160     }
161 
162     //Add ID to DOM
163     if( idAttr != NULL ) {
164         idValue = xmlNodeListGetString( tarNode->doc, idAttr->children, 1 ) ;
165         if( idValue == NULL ) {
166             fprintf( stderr , "### the ID value is NULL!\n" ) ;
167             goto done ;
168         }
169 
170         if( xmlAddID( NULL, doc, idValue, idAttr ) == NULL ) {
171             fprintf( stderr , "### Can not add the ID value!\n" ) ;
172             goto done ;
173         }
174     }
175 
176     //Reference handler
177     //Find the signature reference
178     tarNode = xmlSecFindNode( tplNode, xmlSecNodeReference, xmlSecDSigNs ) ;
179     if( tarNode == NULL ) {
180         fprintf( stderr , "### Cannot find the signature reference!\n" ) ;
181         goto done ;
182     }
183 
184     //Find the "URI" attrbute in the reference
185     uriAttr = xmlHasProp( tarNode, ( xmlChar* )"URI" ) ;
186     if( tarNode == NULL ) {
187         fprintf( stderr , "### Cannot find URI of the reference!\n" ) ;
188         goto done ;
189     }
190 
191     //Get the "URI" attrbute value
192     uriValue = xmlNodeListGetString( tarNode->doc, uriAttr->children, 1 ) ;
193     if( uriValue == NULL ) {
194         fprintf( stderr , "### the URI value is NULL!\n" ) ;
195         goto done ;
196     }
197 
198     if( strchr( ( const char* )uriValue, '/' ) != NULL && strchr( ( const char* )uriValue, '#' ) == NULL ) {
199         fprintf( stdout , "### Find a stream URI [%s]\n", uriValue ) ;
200     //  uri = new ::rtl::OUString( ( const sal_Unicode* )uriValue ) ;
201         uri = new ::rtl::OUString( ( const sal_Char* )uriValue, xmlStrlen( uriValue ), RTL_TEXTENCODING_ASCII_US ) ;
202     }
203 
204     if( uri != NULL ) {
205         fprintf( stdout , "### Find the URI [%s]\n", OUStringToOString( *uri , RTL_TEXTENCODING_ASCII_US ).getStr() ) ;
206         Reference< XInputStream > xStream = createStreamFromFile( *uri ) ;
207         if( !xStream.is() ) {
208             fprintf( stderr , "### Can not get the URI stream!\n" ) ;
209             goto done ;
210         }
211 
212         xUriBinding = new OUriBinding( *uri, xStream ) ;
213     }
214 
215     try {
216         Reference< XMultiComponentFactory > xManager = NULL ;
217         Reference< XComponentContext > xContext = NULL ;
218 
219         xManager = serviceManager( xContext , OUString::createFromAscii( "local" ), OUString::createFromAscii( argv[4] ) ) ;
220         OSL_ENSURE( xManager.is() ,
221             "ServicesManager - "
222             "Cannot get service manager" ) ;
223 
224         //Create signature template
225         Reference< XInterface > element =
226             xManager->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLElementWrapper_XmlSecImpl" ) , xContext ) ;
227         OSL_ENSURE( element.is() ,
228             "Signer - "
229             "Cannot get service instance of \"wrapper.XMLElementWrapper\"" ) ;
230 
231         Reference< XXMLElementWrapper > xElement( element , UNO_QUERY ) ;
232         OSL_ENSURE( xElement.is() ,
233             "Signer - "
234             "Cannot get interface of \"XXMLElement\" from service \"xsec.XMLElement\"" ) ;
235 
236         Reference< XUnoTunnel > xEleTunnel( xElement , UNO_QUERY ) ;
237         OSL_ENSURE( xEleTunnel.is() ,
238             "Signer - "
239             "Cannot get interface of \"XUnoTunnel\" from service \"xsec.XMLElement\"" ) ;
240 
241         XMLElementWrapper_XmlSecImpl* pElement = ( XMLElementWrapper_XmlSecImpl* )xEleTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
242         OSL_ENSURE( pElement != NULL ,
243             "Signer - "
244             "Cannot get implementation of \"xsec.XMLElement\"" ) ;
245 
246         //Set signature template
247         pElement->setNativeElement( tplNode ) ;
248 
249         //Build XML Signature template
250         Reference< XInterface > signtpl =
251             xManager->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.crypto.XMLSignatureTemplate" ) , xContext ) ;
252         OSL_ENSURE( signtpl.is() ,
253             "Signer - "
254             "Cannot get service instance of \"xsec.XMLSignatureTemplate\"" ) ;
255 
256         Reference< XXMLSignatureTemplate > xTemplate( signtpl , UNO_QUERY ) ;
257         OSL_ENSURE( xTemplate.is() ,
258             "Signer - "
259             "Cannot get interface of \"XXMLSignatureTemplate\" from service \"xsec.XMLSignatureTemplate\"" ) ;
260 
261         //Import the signature template
262         xTemplate->setTemplate( xElement ) ;
263 
264         //Import the URI/Stream binding
265         if( xUriBinding.is() )
266             xTemplate->setBinding( xUriBinding ) ;
267 
268         //Create security environment
269         //Build Security Environment
270         Reference< XInterface > xsecenv =
271             xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl"), xContext ) ;
272         OSL_ENSURE( xsecenv.is() ,
273             "Signer - "
274             "Cannot get service instance of \"xsec.SecurityEnvironment\"" ) ;
275 
276         Reference< XSecurityEnvironment > xSecEnv( xsecenv , UNO_QUERY ) ;
277         OSL_ENSURE( xSecEnv.is() ,
278             "Signer - "
279             "Cannot get interface of \"XSecurityEnvironment\" from service \"xsec.SecurityEnvironment\"" ) ;
280 
281         //Setup key slot and certDb
282         Reference< XUnoTunnel > xEnvTunnel( xsecenv , UNO_QUERY ) ;
283         OSL_ENSURE( xElement.is() ,
284             "Signer - "
285             "Cannot get interface of \"XUnoTunnel\" from service \"xsec.SecurityEnvironment\"" ) ;
286 
287         SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xEnvTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
288         OSL_ENSURE( pSecEnv != NULL ,
289             "Signer - "
290             "Cannot get implementation of \"xsec.SecurityEnvironment\"" ) ;
291 
292         pSecEnv->setCryptoSlot( slot ) ;
293         pSecEnv->setCertDb( certHandle ) ;
294 
295         //Build XML Security Context
296         Reference< XInterface > xmlsecctx =
297             xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_NssImpl"), xContext ) ;
298         OSL_ENSURE( xsecenv.is() ,
299             "Signer - "
300             "Cannot get service instance of \"xsec.XMLSecurityContext\"" ) ;
301 
302         Reference< XXMLSecurityContext > xSecCtx( xmlsecctx , UNO_QUERY ) ;
303         OSL_ENSURE( xSecCtx.is() ,
304             "Signer - "
305             "Cannot get interface of \"XXMLSecurityContext\" from service \"xsec.XMLSecurityContext\"" ) ;
306 
307         xSecCtx->setSecurityEnvironment( xSecEnv ) ;
308 
309         //Generate XML signature
310         Reference< XInterface > xmlsigner =
311             xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLSignature_NssImpl"), xContext ) ;
312         OSL_ENSURE( xmlsigner.is() ,
313             "Signer - "
314             "Cannot get service instance of \"xsec.XMLSignature\"" ) ;
315 
316         Reference< XXMLSignature > xSigner( xmlsigner , UNO_QUERY ) ;
317         OSL_ENSURE( xSigner.is() ,
318             "Signer - "
319             "Cannot get interface of \"XXMLSignature\" from service \"xsec.XMLSignature\"" ) ;
320 
321         //perform signature
322         xTemplate = xSigner->generate( xTemplate , xSecCtx ) ;
323         OSL_ENSURE( xTemplate.is() ,
324             "Signer - "
325             "Cannot generate the xml signature" ) ;
326     } catch( Exception& e ) {
327         fprintf( stderr , "Error Message: %s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() ) ;
328         goto done ;
329     }
330 
331     dstFile = fopen( argv[3], "w" ) ;
332     if( dstFile == NULL ) {
333         fprintf( stderr , "### Can not open file %s\n", argv[3] ) ;
334         goto done ;
335     }
336 
337     //Save result
338     xmlDocDump( dstFile, doc ) ;
339 
340 done:
341     if( uri != NULL )
342         delete uri ;
343 
344     if( dstFile != NULL )
345         fclose( dstFile ) ;
346 
347     if( doc != NULL )
348         xmlFreeDoc( doc ) ;
349 
350     if( slot != NULL )
351         PK11_FreeSlot( slot ) ;
352 
353     PK11_LogoutAll() ;
354     NSS_Shutdown() ;
355 
356     /* Shutdown libxslt/libxml */
357     #ifndef XMLSEC_NO_XSLT
358     xsltCleanupGlobals();
359     #endif /* XMLSEC_NO_XSLT */
360     xmlCleanupParser();
361 
362     }
363 
364     return 0;
365 }
366 
367