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 
37 #include "securityenvironment_nssimpl.hxx"
38 #include "xmlelementwrapper_xmlsecimpl.hxx"
39 
40 #include "nspr.h"
41 #include "prtypes.h"
42 
43 #include "pk11func.h"
44 #include "cert.h"
45 #include "cryptohi.h"
46 #include "certdb.h"
47 #include "nss.h"
48 
49 #include "xmlsec/strings.h"
50 #include "xmlsec/xmltree.h"
51 
52 #include <rtl/ustring.hxx>
53 #include <cppuhelper/bootstrap.hxx>
54 #include <cppuhelper/servicefactory.hxx>
55 
56 #include <com/sun/star/beans/PropertyValue.hpp>
57 #include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
58 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp>
59 #include <com/sun/star/xml/crypto/XXMLEncryption.hpp>
60 #include <com/sun/star/xml/crypto/XXMLEncryptionTemplate.hpp>
61 #include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
62 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
63 
64 
65 using namespace ::rtl ;
66 using namespace ::cppu ;
67 using namespace ::com::sun::star::uno ;
68 using namespace ::com::sun::star::io ;
69 using namespace ::com::sun::star::ucb ;
70 using namespace ::com::sun::star::beans ;
71 using namespace ::com::sun::star::document ;
72 using namespace ::com::sun::star::lang ;
73 using namespace ::com::sun::star::registry ;
74 using namespace ::com::sun::star::xml::wrapper ;
75 using namespace ::com::sun::star::xml::crypto ;
76 
77 
78 int SAL_CALL main( int argc, char **argv )
79 {
80 	CERTCertDBHandle*	certHandle = NULL ;
81 	PK11SlotInfo*		slot = NULL ;
82 	xmlDocPtr			doc = NULL ;
83 	xmlNodePtr			tplNode ;
84 	xmlNodePtr			tarNode ;
85 	FILE*				dstFile = NULL ;
86 
87 
88 	if( argc != 5 ) {
89 		fprintf( stderr, "Usage: %s < CertDir > <input file_url> <output file_url> <rdb file>\n\n" , argv[0] ) ;
90 		return 1 ;
91 	}
92 
93 	//Init libxml and libxslt libraries
94 	xmlInitParser();
95 	LIBXML_TEST_VERSION
96 	xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
97 	xmlSubstituteEntitiesDefault(1);
98 
99 	#ifndef XMLSEC_NO_XSLT
100 	xmlIndentTreeOutput = 1;
101 	#endif // XMLSEC_NO_XSLT
102 
103 
104 	//Initialize NSPR and NSS
105 	PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1 ) ;
106 	PK11_SetPasswordFunc( PriPK11PasswordFunc ) ;
107 	if( NSS_Init( argv[1] ) != SECSuccess ) {
108 		fprintf( stderr , "### cannot intialize NSS!\n" ) ;
109 		goto done ;
110 	}
111 
112 	certHandle = CERT_GetDefaultCertDB() ;
113 	slot = PK11_GetInternalKeySlot() ;
114 
115 	//Load XML document
116 	doc = xmlParseFile( argv[2] ) ;
117 	if( doc == NULL || xmlDocGetRootElement( doc ) == NULL ) {
118 		fprintf( stderr , "### Cannot load template xml document!\n" ) ;
119 		goto done ;
120 	}
121 
122 	//Find the encryption template
123 	tplNode = xmlSecFindNode( xmlDocGetRootElement( doc ), xmlSecNodeEncryptedData, xmlSecEncNs ) ;
124 	if( tplNode == NULL ) {
125 		fprintf( stderr , "### Cannot find the encryption template!\n" ) ;
126 		goto done ;
127 	}
128 
129 
130 	try {
131 		Reference< XMultiComponentFactory > xManager = NULL ;
132 		Reference< XComponentContext > xContext = NULL ;
133 
134 		xManager = serviceManager( xContext , OUString::createFromAscii( "local" ), OUString::createFromAscii( argv[4] ) ) ;
135 
136 		//Create encryption template
137 		Reference< XInterface > tplElement =
138 			xManager->createInstanceWithContext( OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.XMLElementWrapper_XmlSecImpl" ) , xContext ) ;
139 		OSL_ENSURE( tplElement.is() ,
140 			"Decryptor - "
141 			"Cannot get service instance of \"xsec.XMLElementWrapper\"" ) ;
142 
143 		Reference< XXMLElementWrapper > xTplElement( tplElement , UNO_QUERY ) ;
144 		OSL_ENSURE( xTplElement.is() ,
145 			"Decryptor - "
146 			"Cannot get interface of \"XXMLElementWrapper\" from service \"xsec.XMLElementWrapper\"" ) ;
147 
148 		Reference< XUnoTunnel > xTplEleTunnel( xTplElement , UNO_QUERY ) ;
149 		OSL_ENSURE( xTplEleTunnel.is() ,
150 			"Decryptor - "
151 			"Cannot get interface of \"XUnoTunnel\" from service \"xsec.XMLElementWrapper\"" ) ;
152 
153 		XMLElementWrapper_XmlSecImpl* pTplElement = ( XMLElementWrapper_XmlSecImpl* )xTplEleTunnel->getSomething( XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ) ;
154 		OSL_ENSURE( pTplElement != NULL ,
155 			"Decryptor - "
156 			"Cannot get implementation of \"xsec.XMLElementWrapper\"" ) ;
157 
158 		pTplElement->setNativeElement( tplNode ) ;
159 
160 		//Build XML Encryption template
161 		Reference< XInterface > enctpl =
162 			xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.crypto.XMLEncryptionTemplate"), xContext ) ;
163 		OSL_ENSURE( enctpl.is() ,
164 			"Decryptor - "
165 			"Cannot get service instance of \"xsec.XMLEncryptionTemplate\"" ) ;
166 
167 		Reference< XXMLEncryptionTemplate > xTemplate( enctpl , UNO_QUERY ) ;
168 		OSL_ENSURE( xTemplate.is() ,
169 			"Decryptor - "
170 			"Cannot get interface of \"XXMLEncryptionTemplate\" from service \"xsec.XMLEncryptionTemplate\"" ) ;
171 
172 		//Import the encryption template
173 		xTemplate->setTemplate( xTplElement ) ;
174 
175 		//Create security environment
176 		//Build Security Environment
177 		Reference< XInterface > xsecenv =
178 			xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_NssImpl"), xContext ) ;
179 		OSL_ENSURE( xsecenv.is() ,
180 			"Decryptor - "
181 			"Cannot get service instance of \"xsec.SecurityEnvironment\"" ) ;
182 
183 		Reference< XSecurityEnvironment > xSecEnv( xsecenv , UNO_QUERY ) ;
184 		OSL_ENSURE( xSecEnv.is() ,
185 			"Decryptor - "
186 			"Cannot get interface of \"XSecurityEnvironment\" from service \"xsec.SecurityEnvironment\"" ) ;
187 
188 		//Setup key slot and certDb
189 		Reference< XUnoTunnel > xEnvTunnel( xsecenv , UNO_QUERY ) ;
190 		OSL_ENSURE( xEnvTunnel.is() ,
191 			"Decryptor - "
192 			"Cannot get interface of \"XUnoTunnel\" from service \"xsec.SecurityEnvironment\"" ) ;
193 
194 		SecurityEnvironment_NssImpl* pSecEnv = ( SecurityEnvironment_NssImpl* )xEnvTunnel->getSomething( SecurityEnvironment_NssImpl::getUnoTunnelId() ) ;
195 		OSL_ENSURE( pSecEnv != NULL ,
196 			"Decryptor - "
197 			"Cannot get implementation of \"xsec.SecurityEnvironment\"" ) ;
198 
199 		pSecEnv->setCryptoSlot( slot ) ;
200 		pSecEnv->setCertDb( certHandle ) ;
201 
202 
203 		//Build XML Security Context
204 		Reference< XInterface > xmlsecctx =
205 			xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLSecurityContext_NssImpl"), xContext ) ;
206 		OSL_ENSURE( xmlsecctx.is() ,
207 			"Decryptor - "
208 			"Cannot get service instance of \"xsec.XMLSecurityContext\"" ) ;
209 
210 		Reference< XXMLSecurityContext > xSecCtx( xmlsecctx , UNO_QUERY ) ;
211 		OSL_ENSURE( xSecCtx.is() ,
212 			"Decryptor - "
213 			"Cannot get interface of \"XXMLSecurityContext\" from service \"xsec.XMLSecurityContext\"" ) ;
214 
215 		xSecCtx->setSecurityEnvironment( xSecEnv ) ;
216 
217 
218 		//Get encrypter
219 		Reference< XInterface > xmlencrypter =
220 			xManager->createInstanceWithContext( OUString::createFromAscii("com.sun.star.xml.security.bridge.xmlsec.XMLEncryption_NssImpl"), xContext ) ;
221 		OSL_ENSURE( xmlencrypter.is() ,
222 			"Decryptor - "
223 			"Cannot get service instance of \"xsec.XMLEncryption\"" ) ;
224 
225 		Reference< XXMLEncryption > xEncrypter( xmlencrypter , UNO_QUERY ) ;
226 		OSL_ENSURE( xEncrypter.is() ,
227 			"Decryptor - "
228 			"Cannot get interface of \"XXMLEncryption\" from service \"xsec.XMLEncryption\"" ) ;
229 
230 
231 		//Perform decryption
232 		Reference< XXMLElementWrapper> xDecrRes = xEncrypter->decrypt( xTemplate , xSecCtx ) ;
233 		OSL_ENSURE( xDecrRes.is() ,
234 			"Decryptor - "
235 			"Cannot decrypt the xml document" ) ;
236 	} catch( Exception& e ) {
237 		fprintf( stderr , "Error Message: %s\n" , OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).getStr() ) ;
238 		goto done ;
239 	}
240 
241 	dstFile = fopen( argv[3], "w" ) ;
242 	if( dstFile == NULL ) {
243 		fprintf( stderr , "### Can not open file %s\n", argv[3] ) ;
244 		goto done ;
245 	}
246 
247 	//Save result
248 	xmlDocDump( dstFile, doc ) ;
249 
250 done:
251 	if( dstFile != NULL )
252 		fclose( dstFile ) ;
253 
254 	if( slot != NULL )
255 		PK11_FreeSlot( slot ) ;
256 
257 	PK11_LogoutAll() ;
258 	NSS_Shutdown() ;
259 
260 	/* Shutdown libxslt/libxml */
261 	#ifndef XMLSEC_NO_XSLT
262 	xsltCleanupGlobals();
263 	#endif /* XMLSEC_NO_XSLT */
264 	xmlCleanupParser();
265 
266 	return 0;
267 }
268 
269