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 #ifndef _XSEC_CTL_HXX 25 #define _XSEC_CTL_HXX 26 27 #include <xmlsecurity/sigstruct.hxx> 28 29 #include <com/sun/star/uno/XComponentContext.hpp> 30 #include <com/sun/star/xml/sax/XParser.hpp> 31 #include <com/sun/star/lang/XInitialization.hpp> 32 #include <com/sun/star/xml/sax/XDocumentHandler.hpp> 33 #include <com/sun/star/xml/sax/XAttributeList.hpp> 34 #include <com/sun/star/xml/crypto/XXMLSignature.hpp> 35 #include <com/sun/star/xml/crypto/XSEInitializer.hpp> 36 #include <com/sun/star/xml/crypto/sax/XSecurityController.hpp> 37 #include <com/sun/star/xml/crypto/sax/XElementStackKeeper.hpp> 38 #include <com/sun/star/xml/crypto/sax/XSecuritySAXEventKeeper.hpp> 39 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedListener.hpp> 40 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeListener.hpp> 41 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp> 42 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp> 43 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp> 44 #include <com/sun/star/beans/XFastPropertySet.hpp> 45 #include <com/sun/star/io/XOutputStream.hpp> 46 #include <com/sun/star/io/XInputStream.hpp> 47 48 #include <rtl/ustrbuf.hxx> 49 50 #include <cppuhelper/implbase4.hxx> 51 52 #ifndef INCLUDED_VECTOR 53 #include <vector> 54 #define INCLUDED_VECTOR 55 #endif 56 57 /* 58 * all error information 59 */ 60 #define ERROR_CANNOTCREATEXMLSECURITYCOMPONENT "Can't create XML security components." 61 #define ERROR_SAXEXCEPTIONDURINGCREATION "A SAX exception is throwed during signature creation." 62 #define ERROR_IOEXCEPTIONDURINGCREATION "An IO exception is throwed during signature creation." 63 #define ERROR_EXCEPTIONDURINGCREATION "An exception is throwed during signature creation." 64 65 /* 66 * all stringS in signature element 67 */ 68 #define TAG_SIGNATURE "Signature" 69 #define TAG_SIGNEDINFO "SignedInfo" 70 #define TAG_CANONICALIZATIONMETHOD "CanonicalizationMethod" 71 #define TAG_SIGNATUREMETHOD "SignatureMethod" 72 #define TAG_REFERENCE "Reference" 73 #define TAG_TRANSFORMS "Transforms" 74 #define TAG_TRANSFORM "Transform" 75 #define TAG_DIGESTMETHOD "DigestMethod" 76 #define TAG_DIGESTVALUE "DigestValue" 77 #define TAG_SIGNATUREVALUE "SignatureValue" 78 #define TAG_KEYINFO "KeyInfo" 79 #define TAG_X509DATA "X509Data" 80 #define TAG_X509ISSUERSERIAL "X509IssuerSerial" 81 #define TAG_X509ISSUERNAME "X509IssuerName" 82 #define TAG_X509SERIALNUMBER "X509SerialNumber" 83 #define TAG_X509CERTIFICATE "X509Certificate" 84 #define TAG_OBJECT "Object" 85 #define TAG_SIGNATUREPROPERTIES "SignatureProperties" 86 #define TAG_SIGNATUREPROPERTY "SignatureProperty" 87 #define TAG_TIMESTAMP "timestamp" 88 #define TAG_DATE "date" 89 //#define TAG_TIME "time" 90 91 #define ATTR_XMLNS "xmlns" 92 #define ATTR_ALGORITHM "Algorithm" 93 #define ATTR_URI "URI" 94 #define ATTR_ID "Id" 95 #define ATTR_TARGET "Target" 96 97 #define NSTAG_DC "dc" 98 99 #define NS_XMLDSIG "http://www.w3.org/2000/09/xmldsig#" 100 //#define NS_DATETIME "http://www.ietf.org/rfcXXXX.txt" 101 #define NS_DC "http://purl.org/dc/elements/1.1/" 102 103 #define ALGO_C14N "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" 104 #define ALGO_RSASHA1 "http://www.w3.org/2000/09/xmldsig#rsa-sha1" 105 #define ALGO_XMLDSIGSHA1 "http://www.w3.org/2000/09/xmldsig#sha1" 106 107 #define CHAR_FRAGMENT "#" 108 #define CHAR_BLANK " " 109 110 111 /* 112 * status of security related components 113 */ 114 #define UNINITIALIZED 0 115 #define INITIALIZED 1 116 #define FAILTOINITIALIZED 2 117 118 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US 119 120 // forward declaration 121 class XSecParser; 122 123 class InternalSignatureInformation 124 { 125 public: 126 SignatureInformation signatureInfor; 127 128 com::sun::star::uno::Reference< 129 com::sun::star::xml::crypto::sax::XReferenceResolvedListener > 130 xReferenceResolvedListener; 131 132 ::std::vector< sal_Int32 > vKeeperIds; 133 InternalSignatureInformation(sal_Int32 nId,com::sun::star::uno::Reference<com::sun::star::xml::crypto::sax::XReferenceResolvedListener> xListener)134 InternalSignatureInformation( 135 sal_Int32 nId, 136 com::sun::star::uno::Reference< com::sun::star::xml::crypto::sax::XReferenceResolvedListener > 137 xListener) 138 :signatureInfor(nId) 139 { 140 xReferenceResolvedListener = xListener; 141 } 142 addReference(sal_Int32 type,rtl::OUString uri,sal_Int32 keeperId)143 void addReference( sal_Int32 type, rtl::OUString uri, sal_Int32 keeperId ) 144 { 145 signatureInfor.vSignatureReferenceInfors.push_back( 146 SignatureReferenceInformation(type, uri)); 147 vKeeperIds.push_back( keeperId ); 148 } 149 }; 150 151 typedef ::std::vector< InternalSignatureInformation > InternalSignatureInformations; 152 153 class XSecController : public cppu::WeakImplHelper4 154 < 155 com::sun::star::xml::crypto::sax::XSecurityController, 156 //com::sun::star::beans::XFastPropertySet, 157 com::sun::star::xml::crypto::sax::XSAXEventKeeperStatusChangeListener, 158 com::sun::star::xml::crypto::sax::XSignatureCreationResultListener, 159 com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener 160 > 161 /****** XSecController.hxx/CLASS XSecController ******************************* 162 * 163 * NAME 164 * XSecController -- the xml security framework controller 165 * 166 * FUNCTION 167 * Controlls the whole xml security framework to create signatures or to 168 * verify signatures. 169 * 170 * HISTORY 171 * 05.01.2004 - Interface supported: XSecurityController, 172 * XFastPropertySet, XSAXEventKeeperStatusChangeListener, 173 * XSignatureCreationResultListener, 174 * XSignatureVerifyResultListener 175 * 176 * NOTES 177 * The XFastPropertySet interface is used to transfer common values to 178 * classes in other module, for instance, the signature id for all 179 * sessions is transferred to xmloff module through this interface. 180 * 181 * AUTHOR 182 * Michael Mi 183 * Email: michael.mi@sun.com 184 ******************************************************************************/ 185 { 186 friend class XSecParser; 187 188 private: 189 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext> mxCtx; 190 191 /* 192 * used to buffer SAX events 193 */ 194 com::sun::star::uno::Reference< 195 com::sun::star::xml::wrapper::XXMLDocumentWrapper > m_xXMLDocumentWrapper; 196 197 /* 198 * the SAX events keeper 199 */ 200 com::sun::star::uno::Reference< 201 com::sun::star::xml::crypto::sax::XSecuritySAXEventKeeper > m_xSAXEventKeeper; 202 203 /* 204 * the bridge component which creates/verifies signature 205 */ 206 com::sun::star::uno::Reference< 207 com::sun::star::xml::crypto::XXMLSignature > m_xXMLSignature; 208 209 /* 210 * the Security Context 211 */ 212 com::sun::star::uno::Reference< 213 com::sun::star::xml::crypto::XXMLSecurityContext > m_xSecurityContext; 214 215 #if 0 216 /* 217 * the signature creation result listener 218 */ 219 com::sun::star::uno::Reference< 220 com::sun::star::xml::crypto::sax::XSignatureCreationResultListener > m_xSignatureCreationResultListener; 221 /* 222 * the signature verify result listener 223 */ 224 com::sun::star::uno::Reference< 225 com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener > m_xSignatureVerifyResultListener; 226 #endif 227 228 /* 229 * the security id incrementer, in order to make any security id unique 230 * to the SAXEventKeeper. 231 * Because each XSecController has its own SAXEventKeeper, so this variable 232 * is not necessary to be static. 233 */ 234 sal_Int32 m_nNextSecurityId; 235 236 /* 237 * Signature information 238 */ 239 InternalSignatureInformations m_vInternalSignatureInformations; 240 241 /* 242 * the previous node on the SAX chain. 243 * The reason that use a Reference<XInterface> type variable 244 * is that the previous components are different when exporting 245 * and importing, and there is no other common interface they 246 * can provided. 247 */ 248 com::sun::star::uno::Reference< 249 com::sun::star::uno::XInterface > m_xPreviousNodeOnSAXChain; 250 /* 251 * whether the preivous node can provide an XInitiazlize interface, 252 * use this variable in order to typecast the XInterface to the 253 * correct interface type. 254 */ 255 bool m_bIsPreviousNodeInitializable; 256 257 /* 258 * the next node on the SAX chain. 259 * it can always provide an XDocumentHandler interface. 260 */ 261 com::sun::star::uno::Reference< 262 com::sun::star::xml::sax::XDocumentHandler > m_xNextNodeOnSAXChain; 263 264 /* 265 * the ElementStackKeeper is used to reserve the key SAX events. 266 * when the SAXEventKeeper is chained on the SAX chain, it need 267 * first get all missed key SAX events in order to make sure the 268 * DOM tree it buffering has the same structure with the original 269 * document. 270 * 271 * For a given section of a SAX event stream, the key SAX events 272 * are the minimal SAX event subset of that section, which, 273 * combining with SAX events outside of this section, has the same 274 * structure with the original document. 275 * 276 * For example, sees the following dom fragment: 277 * <A> 278 * <B/> 279 * <C> 280 * <D> 281 * <E/> 282 * </D> 283 * </C> 284 * </A> 285 * 286 * If we consider the SAX event section from startElement(<A>) to 287 * startElement(<D>), then the key SAX events are: 288 * 289 * startElement(<A>), startElement(<C>), startElement(<D>) 290 * 291 * The startElement(<B>) and endElement(<B>) is ignored, because 292 * they are unimportant for the tree structure in this section. 293 * 294 * If we consider the SAX event section from startElement(<D>) to 295 * endElement(<A>), the key SAX events are: 296 * 297 * startElement(<D>), endElement(<D>), endElement(<C>), 298 * endElement(<A>). 299 */ 300 com::sun::star::uno::Reference< 301 com::sun::star::xml::crypto::sax::XElementStackKeeper > m_xElementStackKeeper; 302 303 /* 304 * a flag representing whether the SAXEventKeeper is now on the 305 * SAX chain. 306 */ 307 bool m_bIsSAXEventKeeperConnected; 308 309 /* 310 * a flag representing whether it is collecting some element, 311 * which means that the SAXEventKeeper can't be chained off the 312 * SAX chain. 313 */ 314 bool m_bIsCollectingElement; 315 316 /* 317 * a flag representing whether the SAX event stream is blocking, 318 * which also means that the SAXEventKeeper can't be chained off 319 * the SAX chain. 320 */ 321 bool m_bIsBlocking; 322 323 /* 324 * a flag representing the current status of security related 325 * components. 326 */ 327 sal_Int32 m_nStatusOfSecurityComponents; 328 329 /* 330 * a flag representing whether the SAXEventKeeper need to be 331 * on the SAX chain all the time. 332 * This flag is used to the situation when creating signature. 333 */ 334 bool m_bIsSAXEventKeeperSticky; 335 336 /* 337 * fast property vector 338 */ 339 std::vector< sal_Int32 > m_vFastPropertyIndexs; 340 std::vector< com::sun::star::uno::Any > m_vFastPropertyValues; 341 342 /* 343 * error message pointer 344 */ 345 const char *m_pErrorMessage; 346 347 /* 348 * the XSecParser which is used to parse the signature stream 349 */ 350 XSecParser *m_pXSecParser; 351 352 /* 353 * the caller assigned signature id for the next signature in the 354 * signature stream 355 */ 356 sal_Int32 m_nReservedSignatureId; 357 358 /* 359 * representing whether to verify the current signature 360 */ 361 bool m_bVerifyCurrentSignature; 362 public: 363 /* 364 * An xUriBinding is provided to map Uris to XInputStream interfaces. 365 */ 366 com::sun::star::uno::Reference< 367 com::sun::star::xml::crypto::XUriBinding > m_xUriBinding; 368 369 private: 370 371 /* 372 * Common methods 373 */ 374 sal_Bool convertNumber( sal_Int32& rValue, const rtl::OUString& rString, sal_Int32 nMin, sal_Int32 nMax ); 375 void convertDateTime( ::rtl::OUStringBuffer& rBuffer, const com::sun::star::util::DateTime& rDateTime ); 376 sal_Bool convertDateTime( com::sun::star::util::DateTime& rDateTime, const ::rtl::OUString& rString ); 377 378 void createXSecComponent( ); 379 int findSignatureInfor( sal_Int32 nSecurityId ) const; 380 bool chainOn( bool bRetrievingLastEvent ); 381 void chainOff(); 382 void checkChainingStatus(); 383 void initializeSAXChain(); 384 385 com::sun::star::uno::Reference< 386 com::sun::star::io::XInputStream > getObjectInputStream( const rtl::OUString& objectURL ); 387 388 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const; 389 390 /* 391 * For signature generation 392 */ 393 rtl::OUString createId(); 394 com::sun::star::uno::Reference< 395 com::sun::star::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite( 396 InternalSignatureInformation& signatureInfo ); 397 398 /* 399 * For signature verification 400 */ 401 void addSignature(); 402 void addReference( const rtl::OUString& ouUri); 403 void addStreamReference( 404 const rtl::OUString& ouUri, 405 bool isBinary ); 406 void setReferenceCount() const; 407 408 /** Set a variable unless already set with a different value. 409 * 410 * @param variable variable to set. 411 * @param value value to set. 412 * 413 * @throw com::sun::star::uno::RuntimeException if the variable is not 414 * empty and its contents are different from value. 415 */ 416 void setIfEmpty(rtl::OUString &variable, const rtl::OUString &value); 417 /** Set the X509 issuer name 418 * 419 * @param ouX509IssuerName value to set. 420 * 421 * This method should be called not more than once. 422 * 423 * @throw com::sun:star::uno::RuntimeException if a tampering is 424 * detected. 425 */ 426 void setX509IssuerName( rtl::OUString& ouX509IssuerName ); 427 /** Set the X509 serial number. 428 * 429 * @param ouX509SerialNumber value to set. 430 * 431 * This method should be called not more than once. 432 * 433 * @throw com::sun:star::uno::RuntimeException if a tampering is 434 * detected. 435 */ 436 void setX509SerialNumber( rtl::OUString& ouX509SerialNumber ); 437 /** Set the X509 certificate. 438 * 439 * @param ouX509Certificate value to set. 440 * 441 * This method should be called not more than once. 442 * 443 * @throw com::sun:star::uno::RuntimeException if a tampering is 444 * detected. 445 */ 446 void setX509Certificate( rtl::OUString& ouX509Certificate ); 447 void setSignatureValue( rtl::OUString& ouSignatureValue ); 448 void setDigestValue( rtl::OUString& ouDigestValue ); 449 450 /** Set the signature date. 451 * 452 * @param ouDate value to set. 453 * 454 * This method should be called not more than once. 455 * 456 * @throw com::sun:star::uno::RuntimeException if a tampering is 457 * detected. 458 */ 459 void setDate( rtl::OUString& ouDate ); 460 461 void setId( rtl::OUString& ouId ); 462 void setPropertyId( rtl::OUString& ouPropertyId ); 463 464 com::sun::star::uno::Reference< 465 com::sun::star::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead( 466 sal_Int32 nSecurityId ); 467 468 public: 469 XSecController(const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>& rxCtx); 470 ~XSecController(); 471 472 sal_Int32 getNewSecurityId( ); 473 474 void startMission( const com::sun::star::uno::Reference< 475 com::sun::star::xml::crypto::XUriBinding >& xUriBinding, 476 const com::sun::star::uno::Reference< 477 com::sun::star::xml::crypto::XXMLSecurityContext >& xSecurityContext ); 478 479 void setSAXChainConnector( 480 const com::sun::star::uno::Reference< 481 com::sun::star::lang::XInitialization >& xInitialization, 482 const com::sun::star::uno::Reference< 483 com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler, 484 const com::sun::star::uno::Reference< 485 com::sun::star::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper); 486 487 void setSAXChainConnector( 488 const com::sun::star::uno::Reference< 489 com::sun::star::xml::sax::XParser >& xParser, 490 const com::sun::star::uno::Reference< 491 com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler, 492 const com::sun::star::uno::Reference< 493 com::sun::star::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper); 494 495 void clearSAXChainConnector(); 496 void endMission(); 497 const char* getErrorMessage(); 498 499 SignatureInformation getSignatureInformation( sal_Int32 nSecurityId ) const; 500 SignatureInformations getSignatureInformations() const; 501 502 void exportSignature( 503 const com::sun::star::uno::Reference< 504 com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler, 505 const SignatureInformation& signatureInfo ); 506 507 508 /* 509 * For signature generation 510 */ 511 void collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId ); 512 void signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool isBinary); 513 514 515 /** sets data that describes the certificate. 516 517 It is absolutely necessary that the parameter ouX509IssuerName is set. It contains 518 the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find 519 the private key. Although issuer name and certificate should be sufficient to identify 520 the certificate the implementation in XMLSec is broken, both for Windows and mozilla. 521 The reason is that they use functions to find the certificate which take as parameter 522 the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes 523 are of type DirectoryName, which is a choice of 5 string types. This information is 524 not contained in the issuer string and while it is converted to the ASN.1 name the 525 conversion function must assume a particular type, which is often wrong. For example, 526 the Windows function CertStrToName will use a T.61 string if the string does not contain 527 special characters. So if the certificate uses simple characters but encodes the 528 issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded 529 ASN.1 name now contains different bytes which indicate the string type. The functions 530 for finding the certificate apparently use memcmp - hence they fail to find the 531 certificate. 532 */ 533 void setX509Certificate( 534 sal_Int32 nSecurityId, 535 const rtl::OUString& ouX509IssuerName, 536 const rtl::OUString& ouX509SerialNumber, 537 const rtl::OUString& ouX509Cert); 538 // see the other setX509Certifcate function 539 void setX509Certificate( 540 sal_Int32 nSecurityId, 541 const sal_Int32 nSecurityEnvironmentIndex, 542 const rtl::OUString& ouX509IssuerName, 543 const rtl::OUString& ouX509SerialNumber, 544 const rtl::OUString& ouX509Cert); 545 546 void setDate( 547 sal_Int32 nSecurityId, 548 const ::com::sun::star::util::DateTime& rDateTime ); 549 550 551 bool WriteSignature( 552 const com::sun::star::uno::Reference< 553 com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler ); 554 555 /* 556 * For signature verification 557 */ 558 void collectToVerify( const rtl::OUString& referenceId ); 559 void addSignature( sal_Int32 nSignatureId ); 560 com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler > createSignatureReader(); 561 void releaseSignatureReader(); 562 563 public: 564 /* Interface methods */ 565 566 /* 567 * XSecurityController 568 * 569 * no method in XSecurityController interface 570 */ 571 572 /* 573 * XFastPropertySet 574 */ 575 /* 576 virtual void SAL_CALL setFastPropertyValue( 577 sal_Int32 nHandle, 578 const com::sun::star::uno::Any& aValue ) 579 throw ( 580 com::sun::star::beans::UnknownPropertyException, 581 com::sun::star::beans::PropertyVetoException, 582 com::sun::star::lang::IllegalArgumentException, 583 com::sun::star::lang::WrappedTargetException, 584 com::sun::star::uno::RuntimeException); 585 virtual com::sun::star::uno::Any SAL_CALL getFastPropertyValue( 586 sal_Int32 nHandle ) 587 throw ( 588 com::sun::star::beans::UnknownPropertyException, 589 com::sun::star::lang::WrappedTargetException, 590 com::sun::star::uno::RuntimeException); 591 */ 592 593 /* 594 * XSAXEventKeeperStatusChangeListener 595 */ 596 virtual void SAL_CALL blockingStatusChanged( sal_Bool isBlocking ) 597 throw (com::sun::star::uno::RuntimeException); 598 virtual void SAL_CALL collectionStatusChanged( 599 sal_Bool isInsideCollectedElement ) 600 throw (com::sun::star::uno::RuntimeException); 601 virtual void SAL_CALL bufferStatusChanged( sal_Bool isBufferEmpty ) 602 throw (com::sun::star::uno::RuntimeException); 603 604 /* 605 * XSignatureCreationResultListener 606 */ 607 virtual void SAL_CALL signatureCreated( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult ) 608 throw (com::sun::star::uno::RuntimeException); 609 610 /* 611 * XSignatureVerifyResultListener 612 */ 613 virtual void SAL_CALL signatureVerified( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult ) 614 throw (com::sun::star::uno::RuntimeException); 615 }; 616 617 #endif 618 619