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 #include "oox/core/encryption.hxx" 25 #include "oox/core/fastparser.hxx" 26 #include "oox/helper/attributelist.hxx" 27 #include "oox/helper/helper.hxx" 28 #include "oox/helper/openssl_wrapper.hxx" 29 30 #include <rtl/digest.h> 31 #include <cppuhelper/implbase1.hxx> 32 #include <openssl/evp.h> 33 34 #include <com/sun/star/io/XStream.hpp> 35 36 37 38 namespace oox { 39 namespace core { 40 41 // ============================================================================ 42 43 using namespace ::com::sun::star::beans; 44 using namespace ::com::sun::star::uno; 45 using namespace ::com::sun::star::xml::sax; 46 47 using ::com::sun::star::io::XInputStream; 48 using ::comphelper::SequenceAsHashMap; 49 using ::rtl::OUString; 50 using ::std::vector; 51 52 // ============================================================================ 53 54 55 /* =========================================================================== */ 56 /* Kudos to Caolan McNamara who provided the core decryption implementation */ 57 /* of Standard Encryption (MS-OFFCRYPTO section 2.3.4.5). */ 58 /* =========================================================================== */ 59 60 #define ENCRYPTINFO_CRYPTOAPI 0x00000004U 61 #define ENCRYPTINFO_DOCPROPS 0x00000008U 62 #define ENCRYPTINFO_EXTERNAL 0x00000010U 63 #define ENCRYPTINFO_AES 0x00000020U 64 65 #define ENCRYPT_ALGO_AES128 0x0000660EU 66 #define ENCRYPT_ALGO_AES192 0x0000660FU 67 #define ENCRYPT_ALGO_AES256 0x00006610U 68 #define ENCRYPT_ALGO_RC4 0x00006801U 69 70 #define ENCRYPT_HASH_SHA1 0x00008004U 71 72 class StandardEncryptionInfo : public EncryptionInfo 73 { 74 public: 75 StandardEncryptionInfo( BinaryInputStream& rStrm ) throw ( Exception ); 76 ~StandardEncryptionInfo() {} 77 bool isImplemented(); 78 Sequence< NamedValue > verifyPassword( const OUString& rPassword ) throw ( Exception ); 79 bool verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) throw ( Exception ); 80 bool checkEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const sal_uInt8* pnVerifier, sal_uInt32 nVerifierSize, const sal_uInt8* pnVerifierHash, sal_uInt32 nVerifierHashSize ) throw ( Exception ); 81 void decryptStream( BinaryXInputStream &aEncryptedPackage, BinaryXOutputStream &aDecryptedPackage ) throw ( Exception ); 82 83 private: 84 sal_uInt8 mpnSalt[ 16 ]; 85 sal_uInt8 mpnEncrVerifier[ 16 ]; 86 sal_uInt8 mpnEncrVerifierHash[ 32 ]; 87 sal_uInt32 mnFlags; 88 sal_uInt32 mnAlgorithmId; 89 sal_uInt32 mnAlgorithmIdHash; 90 sal_uInt32 mnKeySize; 91 sal_uInt32 mnSaltSize; 92 sal_uInt32 mnVerifierHashSize; 93 vector< sal_uInt8> encryptionKey; 94 }; 95 96 StandardEncryptionInfo::StandardEncryptionInfo( BinaryInputStream& rStrm ) throw ( Exception ) 97 { 98 char msg[ 1024 ]; 99 rStrm >> mnFlags; 100 if( getFlag( mnFlags, ENCRYPTINFO_EXTERNAL ) ) 101 throw Exception( OUString::createFromAscii( "EncryptionInfo::readEncryptionInfo() error: \"Extensible encryption\" is not currently supported, please report" ), Reference< XInterface >() ); 102 103 sal_uInt32 nHeaderSize, nRepeatedFlags; 104 rStrm >> nHeaderSize >> nRepeatedFlags; 105 if( nHeaderSize < 20 ) 106 { 107 snprintf( msg, sizeof( msg ), "EncryptionInfo::readEncryptionInfo() error: header size %u is too short", nHeaderSize ); 108 throw Exception( OUString::createFromAscii( msg ), Reference< XInterface >() ); 109 } 110 if( nRepeatedFlags != mnFlags ) 111 throw Exception( OUString::createFromAscii( "EncryptionInfo::readEncryptionInfo() error: flags don't match" ), Reference< XInterface>() ); 112 113 rStrm.skip( 4 ); 114 rStrm >> mnAlgorithmId >> mnAlgorithmIdHash >> mnKeySize; 115 rStrm.skip( nHeaderSize - 20 ); 116 rStrm >> mnSaltSize; 117 if( mnSaltSize != 16 ) 118 { 119 snprintf( msg, sizeof( msg ), "EncryptionInfo::readEncryptionInfo() error: salt size is %u instead of 16", mnSaltSize ); 120 throw Exception( OUString::createFromAscii( msg ), Reference< XInterface >() ); 121 } 122 123 rStrm.readMemory( mpnSalt, 16 ); 124 rStrm.readMemory( mpnEncrVerifier, 16 ); 125 rStrm >> mnVerifierHashSize; 126 rStrm.readMemory( mpnEncrVerifierHash, 32 ); 127 if( rStrm.isEof() ) 128 throw Exception( OUString::createFromAscii( "EncryptionInfo::readEncryptionInfo() error: standard encryption header too short" ), Reference< XInterface >() ); 129 } 130 131 bool StandardEncryptionInfo::isImplemented() 132 { 133 return getFlag( mnFlags, ENCRYPTINFO_CRYPTOAPI ) && 134 getFlag( mnFlags, ENCRYPTINFO_AES ) && 135 // algorithm ID 0 defaults to AES128 too, if ENCRYPTINFO_AES flag is set 136 ( ( mnAlgorithmId == 0 ) || ( mnAlgorithmId == ENCRYPT_ALGO_AES128 ) ) && 137 // hash algorithm ID 0 defaults to SHA-1 too 138 ( ( mnAlgorithmIdHash == 0 ) || ( mnAlgorithmIdHash == ENCRYPT_HASH_SHA1 ) ) && 139 ( mnVerifierHashSize == 20 ); 140 } 141 142 static void deriveKey( const sal_uInt8* pnHash, sal_uInt32 nHashLen, sal_uInt8* pnKeyDerived, sal_uInt32 nRequiredKeyLen ) 143 { 144 sal_uInt8 pnBuffer[ 64 ]; 145 memset( pnBuffer, 0x36, sizeof( pnBuffer ) ); 146 for( sal_uInt32 i = 0; i < nHashLen; ++i ) 147 pnBuffer[ i ] ^= pnHash[ i ]; 148 149 rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 150 rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) ); 151 sal_uInt8 pnX1[ RTL_DIGEST_LENGTH_SHA1 ]; 152 aError = rtl_digest_get( aDigest, pnX1, RTL_DIGEST_LENGTH_SHA1 ); 153 rtl_digest_destroy( aDigest ); 154 155 memset( pnBuffer, 0x5C, sizeof( pnBuffer ) ); 156 for( sal_uInt32 i = 0; i < nHashLen; ++i ) 157 pnBuffer[ i ] ^= pnHash[ i ]; 158 159 aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 160 aError = rtl_digest_update( aDigest, pnBuffer, sizeof( pnBuffer ) ); 161 sal_uInt8 pnX2[ RTL_DIGEST_LENGTH_SHA1 ]; 162 aError = rtl_digest_get( aDigest, pnX2, RTL_DIGEST_LENGTH_SHA1 ); 163 rtl_digest_destroy( aDigest ); 164 165 if( nRequiredKeyLen > RTL_DIGEST_LENGTH_SHA1 ) 166 { 167 memcpy( pnKeyDerived + RTL_DIGEST_LENGTH_SHA1, pnX2, nRequiredKeyLen - RTL_DIGEST_LENGTH_SHA1 ); 168 nRequiredKeyLen = RTL_DIGEST_LENGTH_SHA1; 169 } 170 memcpy( pnKeyDerived, pnX1, nRequiredKeyLen ); 171 } 172 173 Sequence< NamedValue > StandardEncryptionInfo::verifyPassword( const OUString& rPassword ) throw ( Exception ) 174 { 175 size_t nBufferSize = mnSaltSize + 2 * rPassword.getLength(); 176 sal_uInt8* pnBuffer = new sal_uInt8[ nBufferSize ]; 177 memcpy( pnBuffer, mpnSalt, mnSaltSize ); 178 179 sal_uInt8* pnPasswordLoc = pnBuffer + mnSaltSize; 180 const sal_Unicode* pStr = rPassword.getStr(); 181 for( sal_Int32 i = 0, nLen = rPassword.getLength(); i < nLen; ++i, ++pStr, pnPasswordLoc += 2 ) 182 ByteOrderConverter::writeLittleEndian( pnPasswordLoc, static_cast< sal_uInt16 >( *pStr ) ); 183 184 rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 185 rtlDigestError aError = rtl_digest_update( aDigest, pnBuffer, nBufferSize ); 186 delete[] pnBuffer; 187 188 size_t nHashSize = RTL_DIGEST_LENGTH_SHA1 + 4; 189 sal_uInt8* pnHash = new sal_uInt8[ nHashSize ]; 190 aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); 191 rtl_digest_destroy( aDigest ); 192 193 for( sal_uInt32 i = 0; i < 50000; ++i ) 194 { 195 ByteOrderConverter::writeLittleEndian( pnHash, i ); 196 aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 197 aError = rtl_digest_update( aDigest, pnHash, nHashSize ); 198 aError = rtl_digest_get( aDigest, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); 199 rtl_digest_destroy( aDigest ); 200 } 201 202 memmove( pnHash, pnHash + 4, RTL_DIGEST_LENGTH_SHA1 ); 203 memset( pnHash + RTL_DIGEST_LENGTH_SHA1, 0, 4 ); 204 aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 205 aError = rtl_digest_update( aDigest, pnHash, nHashSize ); 206 aError = rtl_digest_get( aDigest, pnHash, RTL_DIGEST_LENGTH_SHA1 ); 207 rtl_digest_destroy( aDigest ); 208 209 vector< sal_uInt8 > key( mnKeySize / 8 ); 210 deriveKey( pnHash, RTL_DIGEST_LENGTH_SHA1, key.data(), key.size() ); 211 delete[] pnHash; 212 213 Sequence< NamedValue > aResult; 214 if( checkEncryptionData( key.data(), key.size(), mpnEncrVerifier, sizeof( mpnEncrVerifier ), mpnEncrVerifierHash, sizeof( mpnEncrVerifierHash ) ) ) 215 { 216 SequenceAsHashMap aEncryptionData; 217 aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionKey" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( key.data() ), key.size() ); 218 aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionSalt" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( mpnSalt ), mnSaltSize ); 219 aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifier" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( mpnEncrVerifier ), sizeof( mpnEncrVerifier ) ); 220 aEncryptionData[ CREATE_OUSTRING( "AES128EncryptionVerifierHash" ) ] <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( mpnEncrVerifierHash ), sizeof( mpnEncrVerifierHash ) ); 221 encryptionKey = key; 222 aResult = aEncryptionData.getAsConstNamedValueList(); 223 } 224 225 return aResult; 226 } 227 228 bool StandardEncryptionInfo::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) throw ( Exception ) 229 { 230 SequenceAsHashMap aHashData( rEncryptionData ); 231 Sequence< sal_Int8 > aKey = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionKey" ), Sequence< sal_Int8 >() ); 232 Sequence< sal_Int8 > aVerifier = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifier" ), Sequence< sal_Int8 >() ); 233 Sequence< sal_Int8 > aVerifierHash = aHashData.getUnpackedValueOrDefault( CREATE_OUSTRING( "AES128EncryptionVerifierHash" ), Sequence< sal_Int8 >() ); 234 const sal_uInt8 *pnKey = reinterpret_cast< const sal_uInt8* >( aKey.getConstArray() ); 235 sal_uInt32 nKeySize = aKey.getLength(); 236 const sal_uInt8 *pnVerifier = reinterpret_cast< const sal_uInt8* >( aVerifier.getConstArray() ); 237 sal_uInt32 nVerifierSize = aVerifier.getLength(); 238 const sal_uInt8 *pnVerifierHash = reinterpret_cast< const sal_uInt8* >( aVerifierHash.getConstArray() ); 239 sal_uInt32 nVerifierHashSize = aVerifierHash.getLength(); 240 if( checkEncryptionData( pnKey, nKeySize, pnVerifier, nVerifierSize, pnVerifierHash, nVerifierHashSize ) ) 241 { 242 encryptionKey = vector< sal_uInt8 >( &pnKey[ 0 ], &pnKey[ nKeySize ] ); 243 return true; 244 } 245 else 246 return false; 247 } 248 249 bool StandardEncryptionInfo::checkEncryptionData( const sal_uInt8* pnKey, sal_uInt32 nKeySize, const sal_uInt8* pnVerifier, sal_uInt32 nVerifierSize, const sal_uInt8* pnVerifierHash, sal_uInt32 nVerifierHashSize ) throw ( Exception ) 250 { 251 bool bResult = false; 252 253 // the only currently supported algorithm needs key size 128 254 if ( nKeySize == 16 && nVerifierSize == 16 && nVerifierHashSize == 32 ) 255 { 256 // check password 257 EVP_CIPHER_CTX *aes_ctx; 258 aes_ctx = EVP_CIPHER_CTX_new(); 259 if ( aes_ctx == NULL ) 260 return false; 261 EVP_DecryptInit_ex( aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); 262 EVP_CIPHER_CTX_set_padding( aes_ctx, 0 ); 263 int nOutLen = 0; 264 sal_uInt8 pnTmpVerifier[ 16 ]; 265 (void) memset( pnTmpVerifier, 0, sizeof(pnTmpVerifier) ); 266 267 /*int*/ EVP_DecryptUpdate( aes_ctx, pnTmpVerifier, &nOutLen, pnVerifier, nVerifierSize ); 268 EVP_CIPHER_CTX_free( aes_ctx ); 269 270 aes_ctx = EVP_CIPHER_CTX_new(); 271 if ( aes_ctx == NULL ) 272 return false; 273 EVP_DecryptInit_ex( aes_ctx, EVP_aes_128_ecb(), 0, pnKey, 0 ); 274 EVP_CIPHER_CTX_set_padding( aes_ctx, 0 ); 275 sal_uInt8 pnTmpVerifierHash[ 32 ]; 276 (void) memset( pnTmpVerifierHash, 0, sizeof(pnTmpVerifierHash) ); 277 278 /*int*/ EVP_DecryptUpdate( aes_ctx, pnTmpVerifierHash, &nOutLen, pnVerifierHash, nVerifierHashSize ); 279 EVP_CIPHER_CTX_free( aes_ctx ); 280 281 rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 ); 282 rtlDigestError aError = rtl_digest_update( aDigest, pnTmpVerifier, sizeof( pnTmpVerifier ) ); 283 sal_uInt8 pnSha1Hash[ RTL_DIGEST_LENGTH_SHA1 ]; 284 aError = rtl_digest_get( aDigest, pnSha1Hash, RTL_DIGEST_LENGTH_SHA1 ); 285 rtl_digest_destroy( aDigest ); 286 287 bResult = ( memcmp( pnSha1Hash, pnTmpVerifierHash, RTL_DIGEST_LENGTH_SHA1 ) == 0 ); 288 } 289 290 return bResult; 291 } 292 293 void StandardEncryptionInfo::decryptStream( BinaryXInputStream &aEncryptedPackage, BinaryXOutputStream &aDecryptedPackage ) throw ( Exception ) 294 { 295 EVP_CIPHER_CTX *aes_ctx; 296 aes_ctx = EVP_CIPHER_CTX_new(); 297 if ( aes_ctx == NULL ) 298 throw Exception(); 299 EVP_DecryptInit_ex( aes_ctx, EVP_aes_128_ecb(), 0, encryptionKey.data(), 0 ); 300 EVP_CIPHER_CTX_set_padding( aes_ctx, 0 ); 301 302 sal_uInt8 pnInBuffer[ 1024 ]; 303 sal_uInt8 pnOutBuffer[ 1024 ]; 304 sal_Int32 nInLen; 305 int nOutLen; 306 aEncryptedPackage.skip( 8 ); // decrypted size 307 while( (nInLen = aEncryptedPackage.readMemory( pnInBuffer, sizeof( pnInBuffer ) )) > 0 ) 308 { 309 EVP_DecryptUpdate( aes_ctx, pnOutBuffer, &nOutLen, pnInBuffer, nInLen ); 310 aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); 311 } 312 EVP_DecryptFinal_ex( aes_ctx, pnOutBuffer, &nOutLen ); 313 aDecryptedPackage.writeMemory( pnOutBuffer, nOutLen ); 314 315 EVP_CIPHER_CTX_free( aes_ctx ); 316 aDecryptedPackage.flush(); 317 } 318 319 // ============================================================================ 320 // "Agile" encryption, 2.3.4.10 of MS-OFFCRYPTO 321 // ============================================================================ 322 323 struct AgileKeyData 324 { 325 sal_Int32 saltSize; 326 sal_Int32 blockSize; 327 sal_Int32 keyBits; 328 sal_Int32 hashSize; 329 OUString cipherAlgorithm; 330 OUString cipherChaining; 331 OUString hashAlgorithm; 332 vector< sal_uInt8 > saltValue; 333 }; 334 335 struct AgileDataIntegrity 336 { 337 vector< sal_uInt8 > encryptedHmacKey; 338 vector< sal_uInt8 > encryptedHmacValue; 339 }; 340 341 struct AgilePasswordKeyEncryptor 342 { 343 sal_Int32 saltSize; 344 sal_Int32 blockSize; 345 sal_Int32 keyBits; 346 sal_Int32 hashSize; 347 OUString cipherAlgorithm; 348 OUString cipherChaining; 349 OUString hashAlgorithm; 350 vector< sal_uInt8 > saltValue; 351 sal_Int32 spinCount; 352 vector< sal_uInt8 > encryptedVerifierHashInput; 353 vector< sal_uInt8 > encryptedVerifierHashValue; 354 vector< sal_uInt8 > encryptedKeyValue; 355 }; 356 357 static bool decodeBase64( OUString& base64, vector< sal_uInt8 >& bytes ) 358 { 359 ::rtl::OString base64Ascii = ::rtl::OUStringToOString( base64, RTL_TEXTENCODING_UTF8 ); 360 const sal_uInt32 len = base64Ascii.getLength(); 361 bytes.resize( (len + 3) / 4 * 3 ); 362 int decodedSize = EVP_DecodeBlock( bytes.data(), reinterpret_cast< sal_uInt8 const * >( base64Ascii.getStr() ), len ); 363 if ( decodedSize < 0 ) 364 return false; 365 if ( len >= 2 && base64Ascii[ len-1 ] == '=' && base64Ascii[ len-2 ] == '=' ) 366 decodedSize -= 2; 367 else if ( len >= 1 && base64Ascii[ len-1] == '=' ) 368 decodedSize--; 369 bytes.resize( decodedSize ); 370 return true; 371 } 372 373 class AgileEncryptionInfo : public EncryptionInfo 374 { 375 public: 376 AgileEncryptionInfo( const Reference< XComponentContext >& context, Reference< XInputStream >& inputStream ) throw ( Exception ); 377 ~AgileEncryptionInfo() {} 378 bool isImplemented() { return true; } // FIXME 379 Sequence< NamedValue > verifyPassword( const OUString& rPassword ) throw ( Exception ); 380 bool verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) throw ( Exception ); 381 void decryptStream( BinaryXInputStream &aEncryptedPackage, BinaryXOutputStream &aDecryptedPackage ) throw ( Exception ); 382 383 private: 384 AgileKeyData keyData; 385 AgileDataIntegrity dataIntegrity; 386 AgilePasswordKeyEncryptor passwordKeyEncryptor; 387 vector< sal_uInt8> encryptionKey; 388 vector< sal_uInt8> hmacKey; 389 vector< sal_uInt8> hmacValue; 390 }; 391 392 // A SAX handler that parses the XML from the "XmlEncryptionDescriptor" in the EncryptionInfo stream. 393 class AgileEncryptionHandler : public ::cppu::WeakImplHelper1< XFastDocumentHandler > 394 { 395 public: 396 AgileEncryptionHandler( AgileKeyData &aKeyData, AgileDataIntegrity &aDataIntegrity, AgilePasswordKeyEncryptor &aPasswordKeyEncryptor ) 397 : keyData( aKeyData ), 398 dataIntegrity( aDataIntegrity ), 399 passwordKeyEncryptor( aPasswordKeyEncryptor ) 400 { 401 } 402 403 // XFastDocumentHandler 404 virtual void SAL_CALL startDocument() throw (SAXException, RuntimeException); 405 virtual void SAL_CALL endDocument() throw (SAXException, RuntimeException); 406 virtual void SAL_CALL setDocumentLocator( const Reference< XLocator >& xLocator ) throw (SAXException, RuntimeException); 407 408 // XFastContextHandler 409 virtual void SAL_CALL startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); 410 virtual void SAL_CALL startUnknownElement( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); 411 virtual void SAL_CALL endFastElement( sal_Int32 Element ) throw (SAXException, RuntimeException); 412 virtual void SAL_CALL endUnknownElement( const OUString& Namespace, const OUString& Name ) throw (SAXException, RuntimeException); 413 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( sal_Int32 Element, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); 414 virtual Reference< XFastContextHandler > SAL_CALL createUnknownChildContext( const OUString& Namespace, const OUString& Name, const Reference< XFastAttributeList >& Attribs ) throw (SAXException, RuntimeException); 415 virtual void SAL_CALL characters( const OUString& aChars ) throw (SAXException, RuntimeException); 416 virtual void SAL_CALL ignorableWhitespace( const OUString& aWhitespaces ) throw (SAXException, RuntimeException); 417 virtual void SAL_CALL processingInstruction( const OUString& aTarget, const OUString& aData ) throw (SAXException, RuntimeException); 418 419 OUString& getLastError() { return lastError; } 420 421 private: 422 void parseKeyData( const AttributeList& attribs ) throw (SAXException, RuntimeException); 423 void parseDataIntegrity( const AttributeList& attribs ) throw (SAXException, RuntimeException); 424 void parseEncryptedKey( const AttributeList& attribs ) throw (SAXException, RuntimeException); 425 426 vector< sal_Int32 > stack; 427 OUString lastError; 428 AgileKeyData &keyData; 429 AgileDataIntegrity &dataIntegrity; 430 AgilePasswordKeyEncryptor &passwordKeyEncryptor; 431 }; 432 433 void AgileEncryptionHandler::startDocument() 434 throw ( SAXException, RuntimeException ) 435 { 436 } 437 438 void AgileEncryptionHandler::endDocument() 439 throw ( SAXException, RuntimeException ) 440 { 441 } 442 443 void AgileEncryptionHandler::setDocumentLocator( const Reference< XLocator >& ) 444 throw ( SAXException, RuntimeException ) 445 { 446 } 447 448 void AgileEncryptionHandler::startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& attribs ) 449 throw( SAXException, RuntimeException ) 450 { 451 switch ( nElement ) 452 { 453 case ENCRYPTION_TOKEN( encryption ): 454 break; 455 456 case ENCRYPTION_TOKEN( keyData ): 457 if ( stack.size() == 1 && (stack[ 0 ] == ENCRYPTION_TOKEN( encryption )) ) 458 parseKeyData( AttributeList( attribs ) ); 459 break; 460 461 case ENCRYPTION_TOKEN( dataIntegrity ): 462 if ( stack.size() == 1 && (stack[ 0 ] == ENCRYPTION_TOKEN( encryption )) ) 463 parseDataIntegrity( AttributeList ( attribs ) ); 464 break; 465 466 case ENCRYPTION_TOKEN( keyEncryptors ): 467 break; 468 469 case ENCRYPTION_TOKEN( keyEncryptor ): 470 break; 471 472 case KEY_ENCRYPTOR_PASSWORD_TOKEN( encryptedKey ): 473 if ( stack.size() == 3 474 && (stack[ 0 ] == ENCRYPTION_TOKEN( encryption )) 475 && (stack[ 1 ] == ENCRYPTION_TOKEN( keyEncryptors )) 476 && (stack[ 2 ] == ENCRYPTION_TOKEN( keyEncryptor )) ) 477 parseEncryptedKey( AttributeList ( attribs ) ); 478 break; 479 } 480 stack.push_back( nElement ); 481 } 482 483 void AgileEncryptionHandler::startUnknownElement( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) 484 throw( SAXException, RuntimeException ) 485 { 486 stack.push_back( -1 ); 487 } 488 489 void AgileEncryptionHandler::endFastElement( sal_Int32 nElement ) 490 throw( SAXException, RuntimeException ) 491 { 492 stack.pop_back(); 493 } 494 495 void AgileEncryptionHandler::endUnknownElement( const OUString&, const OUString& ) 496 throw( SAXException, RuntimeException ) 497 { 498 stack.pop_back(); 499 } 500 501 Reference< XFastContextHandler > AgileEncryptionHandler::createFastChildContext( sal_Int32, const Reference< XFastAttributeList >& ) 502 throw (SAXException, RuntimeException) 503 { 504 return this; 505 } 506 507 Reference< XFastContextHandler > AgileEncryptionHandler::createUnknownChildContext( const OUString&, const OUString&, const Reference< XFastAttributeList >& ) 508 throw (SAXException, RuntimeException) 509 { 510 return this; 511 } 512 513 void AgileEncryptionHandler::characters( const ::rtl::OUString& rStr ) 514 throw( SAXException, RuntimeException ) 515 { 516 } 517 518 void AgileEncryptionHandler::ignorableWhitespace( const ::rtl::OUString& str ) 519 throw( SAXException, RuntimeException ) 520 { 521 } 522 523 void AgileEncryptionHandler::processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) 524 throw( SAXException, RuntimeException ) 525 { 526 } 527 528 void AgileEncryptionHandler::parseKeyData( const AttributeList& attribs ) 529 throw ( SAXException, RuntimeException ) 530 { 531 keyData.saltSize = attribs.getInteger( XML_saltSize, 0 ); 532 keyData.blockSize = attribs.getInteger( XML_blockSize, 0 ); 533 keyData.keyBits = attribs.getInteger( XML_keyBits, 0 ); 534 keyData.hashSize = attribs.getInteger( XML_hashSize, 0 ); 535 keyData.cipherAlgorithm = attribs.getString( XML_cipherAlgorithm, OUString() ); 536 keyData.cipherChaining = attribs.getString( XML_cipherChaining, OUString() ); 537 keyData.hashAlgorithm = attribs.getString( XML_hashAlgorithm, OUString() ); 538 539 OUString saltValue = attribs.getString( XML_saltValue, OUString() ); 540 if( !decodeBase64( saltValue, keyData.saltValue ) ) 541 lastError = OUString::createFromAscii( "Failed to base64 decode the keyData.saltValue " ) + saltValue; 542 } 543 544 void AgileEncryptionHandler::parseDataIntegrity( const AttributeList& attribs ) 545 throw ( SAXException, RuntimeException ) 546 { 547 OUString encryptedHmacKey = attribs.getString( XML_encryptedHmacKey, OUString() ); 548 if( !decodeBase64( encryptedHmacKey, dataIntegrity.encryptedHmacKey ) ) 549 lastError = OUString::createFromAscii( "Failed to base64 decode the dataIntegrity.encryptedHmacKey " ) + encryptedHmacKey; 550 OUString encryptedHmacValue = attribs.getString( XML_encryptedHmacValue, OUString() ); 551 if( !decodeBase64( encryptedHmacValue, dataIntegrity.encryptedHmacValue ) ) 552 lastError = OUString::createFromAscii( "Failed to base64 decode the dataIntegrity.encryptedHmacValue " ) + encryptedHmacValue; 553 } 554 555 void AgileEncryptionHandler::parseEncryptedKey( const AttributeList& attribs ) 556 throw ( SAXException, RuntimeException ) 557 { 558 passwordKeyEncryptor.spinCount = attribs.getInteger( XML_spinCount, 0 ); 559 passwordKeyEncryptor.saltSize = attribs.getInteger( XML_saltSize, 0 ); 560 passwordKeyEncryptor.blockSize = attribs.getInteger( XML_blockSize, 0 ); 561 passwordKeyEncryptor.keyBits = attribs.getInteger( XML_keyBits, 0 ); 562 passwordKeyEncryptor.hashSize = attribs.getInteger( XML_hashSize, 0 ); 563 passwordKeyEncryptor.cipherAlgorithm = attribs.getString( XML_cipherAlgorithm, OUString() ); 564 passwordKeyEncryptor.cipherChaining = attribs.getString( XML_cipherChaining, OUString() ); 565 passwordKeyEncryptor.hashAlgorithm = attribs.getString( XML_hashAlgorithm, OUString() ); 566 OUString saltValue = attribs.getString( XML_saltValue, OUString() ); 567 if( !decodeBase64( saltValue, passwordKeyEncryptor.saltValue ) ) 568 lastError = OUString::createFromAscii( "Failed to base64 decode the passwordKeyEncryptor.saltValue " ) + saltValue; 569 OUString encryptedVerifierHashInput = attribs.getString( XML_encryptedVerifierHashInput, OUString() ); 570 if( !decodeBase64( encryptedVerifierHashInput, passwordKeyEncryptor.encryptedVerifierHashInput ) ) 571 lastError = OUString::createFromAscii( "Failed to base64 decode the passwordKeyEncryptor.encryptedVerifierHashInput " ) + encryptedVerifierHashInput; 572 OUString encryptedVerifierHashValue = attribs.getString( XML_encryptedVerifierHashValue, OUString() ); 573 if( !decodeBase64( encryptedVerifierHashValue, passwordKeyEncryptor.encryptedVerifierHashValue ) ) 574 lastError = OUString::createFromAscii( "Failed to base64 decode the passwordKeyEncryptor.encryptedVerifierHashValue " ) + encryptedVerifierHashValue; 575 OUString encryptedKeyValue = attribs.getString( XML_encryptedKeyValue, OUString() ); 576 if( !decodeBase64( encryptedKeyValue, passwordKeyEncryptor.encryptedKeyValue ) ) 577 lastError = OUString::createFromAscii( "Failed to base64 decode the passwordKeyEncryptor.encryptedKeyValue " ) + encryptedKeyValue; 578 } 579 580 static sal_uInt16 readUInt16LE( Reference< XInputStream >& inputStream ) throw ( Exception ) 581 { 582 Sequence< sal_Int8 > bytes( 2 ); 583 sal_Int32 bytesRead = inputStream->readBytes( bytes, 2 ); 584 if( bytesRead < 2 ) 585 throw new Exception( OUString::createFromAscii( "EncryptionInfo::readEncryptionInfo() failed, early end of file" ), Reference< XInterface >() ); 586 return (sal_uInt16) ( bytes[0] | (bytes[1] << 8) ); 587 } 588 589 static sal_uInt32 readUInt32LE( Reference< XInputStream >& inputStream ) throw ( Exception ) 590 { 591 Sequence< sal_Int8 > bytes( 4 ); 592 sal_Int32 bytesRead = inputStream->readBytes( bytes, 4 ); 593 if( bytesRead < 4 ) 594 throw new Exception( OUString::createFromAscii( "EncryptionInfo::readEncryptionInfo() failed, early end of file" ), Reference< XInterface >() ); 595 return (sal_uInt32) ( bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24) ); 596 } 597 598 AgileEncryptionInfo::AgileEncryptionInfo( const Reference< XComponentContext >& context, Reference< XInputStream >& inputStream ) throw ( Exception ) 599 { 600 sal_uInt32 nReserved = readUInt32LE( inputStream ); 601 if( nReserved != 0x40 ) 602 throw new Exception( OUString::createFromAscii( "reserved field isn't 0x40" ), Reference< XInterface >() ); 603 AgileEncryptionHandler *agileEncryptionHandler = new AgileEncryptionHandler( keyData, dataIntegrity, passwordKeyEncryptor ); 604 Reference< XFastDocumentHandler > documentHandler( agileEncryptionHandler ); 605 FastParser fastParser( context ); 606 fastParser.registerNamespace( NMSP_encryption ); 607 fastParser.registerNamespace( NMSP_keyEncryptorPassword ); 608 fastParser.setDocumentHandler( documentHandler ); 609 fastParser.parseStream( inputStream, OUString::createFromAscii( "EncryptionInfo" ), false ); 610 if( !agileEncryptionHandler->getLastError().isEmpty() ) 611 throw new Exception( agileEncryptionHandler->getLastError(), Reference< XInterface >() ); 612 } 613 614 static const EVP_MD* toOpenSSLDigestAlgorithm( const OUString& hashAlgorithm ) throw ( Exception ) 615 { 616 if( hashAlgorithm.equalsAscii( "SHA-1" ) ) 617 return EVP_sha1(); 618 else if( hashAlgorithm.equalsAscii( "SHA1" ) ) // Typical Microsoft. The specification says "SHA-1", but documents use "SHA1". 619 return EVP_sha1(); 620 else if( hashAlgorithm.equalsAscii( "SHA256" ) ) 621 return EVP_sha256(); 622 else if( hashAlgorithm.equalsAscii( "SHA384" ) ) 623 return EVP_sha384(); 624 else if( hashAlgorithm.equalsAscii( "SHA512" ) ) 625 return EVP_sha512(); 626 else if( hashAlgorithm.equalsAscii( "MD5" ) ) 627 return EVP_md5(); 628 else if( hashAlgorithm.equalsAscii( "MD4" ) ) 629 return EVP_md4(); 630 #if !defined(OPENSSL_NO_MD2) 631 else if( hashAlgorithm.equalsAscii( "MD2" ) ) 632 return EVP_md2(); 633 #endif 634 else if( hashAlgorithm.equalsAscii( "RIPEMD-160" ) ) 635 return EVP_ripemd160(); 636 else if( hashAlgorithm.equalsAscii( "WHIRLPOOL" ) ) 637 return EVP_whirlpool(); 638 char buffer[ 256 ]; 639 ::rtl::OString str = ::rtl::OUStringToOString( hashAlgorithm, RTL_TEXTENCODING_UTF8 ); 640 snprintf( buffer, sizeof( buffer ), "Unsupported digest algorithm %s", str.getStr() ); 641 throw Exception( OUString::createFromAscii( buffer ), Reference< XInterface >() ); 642 } 643 644 static const EVP_CIPHER* toOpenSSLCipherAlgorithm( const OUString& cipherName, sal_uInt32 keyBits, const OUString &chainingMode ) throw ( Exception ) 645 { 646 if( cipherName.equalsAscii( "AES" ) && keyBits == 128 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 647 return EVP_aes_128_cbc(); 648 else if( cipherName.equalsAscii( "AES" ) && keyBits == 128 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 649 return EVP_aes_128_cfb(); 650 else if( cipherName.equalsAscii( "AES" ) && keyBits == 192 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 651 return EVP_aes_192_cbc(); 652 else if( cipherName.equalsAscii( "AES" ) && keyBits == 192 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 653 return EVP_aes_192_cfb(); 654 else if( cipherName.equalsAscii( "AES" ) && keyBits == 256 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 655 return EVP_aes_256_cbc(); 656 else if( cipherName.equalsAscii( "AES" ) && keyBits == 256 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 657 return EVP_aes_256_cfb(); 658 #if !defined(OPENSSL_NO_RC2) 659 else if( cipherName.equalsAscii( "RC2" ) && keyBits == 128 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 660 return EVP_rc2_cbc(); 661 else if( cipherName.equalsAscii( "RC2" ) && keyBits == 128 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 662 return EVP_rc2_cfb(); 663 #endif 664 #if !defined(OPENSSL_NO_DES) 665 else if( cipherName.equalsAscii( "DES" ) && keyBits == 56 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 666 return EVP_des_cbc(); 667 else if( cipherName.equalsAscii( "DES" ) && keyBits == 56 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 668 return EVP_des_cfb(); 669 else if( cipherName.equalsAscii( "DESX" ) && keyBits == 128 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 670 return EVP_desx_cbc(); 671 else if( cipherName.equalsAscii( "3DES" ) && keyBits == 168 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 672 return EVP_des_ede3_cbc(); 673 else if( cipherName.equalsAscii( "3DES" ) && keyBits == 168 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 674 return EVP_des_ede3_cfb(); 675 else if( cipherName.equalsAscii( "3DES_112" ) && keyBits == 112 && chainingMode.equalsAscii( "ChainingModeCBC" ) ) 676 return EVP_des_ede_cbc(); 677 else if( cipherName.equalsAscii( "3DES_112" ) && keyBits == 112 && chainingMode.equalsAscii( "ChainingModeCFB" ) ) 678 return EVP_des_ede_cfb(); 679 #endif 680 char buffer[ 256 ]; 681 ::rtl::OString cipherNameUtf8 = ::rtl::OUStringToOString( cipherName, RTL_TEXTENCODING_UTF8 ); 682 ::rtl::OString chainingModeUtf8 = ::rtl::OUStringToOString( chainingMode, RTL_TEXTENCODING_UTF8 ); 683 snprintf( buffer, sizeof( buffer ), "Unsupported cipher with name=%s, keyBits=%u, chainingMode=%s", cipherNameUtf8.getStr(), keyBits, chainingModeUtf8.getStr() ); 684 throw Exception( OUString::createFromAscii( buffer ), Reference< XInterface >() ); 685 } 686 687 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword(). 688 static vector< sal_uInt8 > hashPassword( const OUString& password, const EVP_MD *digestAlgorithm, vector< sal_uInt8 >& salt, sal_uInt32 spinCount ) throw ( Exception ) 689 { 690 OpenSSLDigest digest; 691 digest.initialize( digestAlgorithm ); 692 size_t digestSize = digest.digestSize(); 693 694 // Convert to little-endian UTF-16 695 vector< sal_uInt8 > passwordLE( 2 * password.getLength() ); 696 for ( int i = 0; i < password.getLength(); i++ ) 697 ByteOrderConverter::writeLittleEndian( &passwordLE[ 2 * i ], static_cast< sal_uInt16 >( password[ i ] ) ); 698 699 vector< sal_uInt8> digestBuffer( digestSize ); 700 digest.update( salt.data(), salt.size() ); 701 digest.update( passwordLE.data(), passwordLE.size() ); 702 digest.final( digestBuffer.data(), NULL ); 703 704 char iteratorBuffer[ 4 ]; 705 for (sal_uInt32 i = 0; i < spinCount; i++) 706 { 707 digest.initialize( digestAlgorithm ); 708 ByteOrderConverter::writeLittleEndian( &iteratorBuffer, i ); 709 digest.update( iteratorBuffer, sizeof( iteratorBuffer ) ); 710 digest.update( digestBuffer.data(), digestSize ); 711 digest.final( digestBuffer.data(), NULL ); 712 } 713 return digestBuffer; 714 } 715 716 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.getBlock36(). 717 static void toBlock36( vector< sal_uInt8 >& digest, sal_uInt32 size ) 718 { 719 if( digest.size() < size ) 720 { 721 sal_uInt32 i = digest.size(); 722 digest.resize( size ); 723 for (; i < size; i++) 724 digest[ i ] = 0x36; 725 } 726 else 727 digest.resize( size ); 728 } 729 730 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.getBlock0(). 731 static void toBlock0( vector< sal_uInt8 >& digest, sal_uInt32 size ) 732 { 733 if( digest.size() < size ) 734 { 735 sal_uInt32 i = digest.size(); 736 digest.resize( size ); 737 for (; i < size; i++) 738 digest[ i ] = 0; 739 } 740 else 741 digest.resize( size ); 742 } 743 744 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.generateKey(). 745 static vector< sal_uInt8 > generateKey( const vector< sal_uInt8 >& passwordHash, 746 const EVP_MD *digestAlgorithm, 747 const vector< sal_uInt8 >& blockKey, 748 sal_uInt32 keySize ) 749 throw ( Exception ) 750 { 751 OpenSSLDigest digest; 752 digest.initialize( digestAlgorithm ); 753 digest.update( passwordHash.data(), passwordHash.size() ); 754 digest.update( blockKey.data(), blockKey.size() ); 755 vector< sal_uInt8> key( digest.digestSize() ); 756 digest.final( key.data(), NULL ); 757 toBlock36( key, keySize ); 758 return key; 759 } 760 761 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.generateIv(). 762 static vector< sal_uInt8> generateIv( const vector< sal_uInt8 >& salt, 763 sal_uInt32 blockSize ) 764 throw ( Exception ) 765 { 766 vector< sal_uInt8> iv( salt ); 767 toBlock36( iv, blockSize ); 768 return iv; 769 } 770 771 // Ported from Apache POI's org.apache.poi.poifs.crypt.CryptoFunctions.generateIv(). 772 static vector< sal_uInt8> generateIv( const EVP_MD *digestAlgorithm, 773 const vector< sal_uInt8 >& salt, 774 const vector< sal_uInt8 >& blockKey, 775 sal_uInt32 blockSize ) 776 throw ( Exception ) 777 { 778 OpenSSLDigest digest; 779 digest.initialize( digestAlgorithm ); 780 digest.update( salt.data(), salt.size() ); 781 digest.update( blockKey.data(), blockKey.size() ); 782 vector< sal_uInt8> iv( digest.digestSize() ); 783 digest.final( iv.data(), NULL ); 784 toBlock36( iv, blockSize ); 785 return iv; 786 } 787 788 // Ported from Apache POI's org.apache.poi.poifs.crypt.agile.AgileDecryptor.getNextBlockSize(). 789 static sal_uInt32 getNextBlockSize( sal_uInt32 totalSize, sal_uInt32 blockSize ) 790 { 791 sal_uInt32 numberOfBlocks = ( totalSize + ( blockSize - 1 ) ) / blockSize; 792 return numberOfBlocks * blockSize; 793 } 794 795 static vector< sal_uInt8 > decryptAll( const EVP_CIPHER* cipherAlgorithm, 796 const sal_uInt8* iv, 797 const sal_uInt8* key, 798 const sal_uInt8* encryptedData, 799 sal_uInt32 encryptedDataLength ) 800 throw ( Exception ) 801 { 802 OpenSSLCipher cipher; 803 cipher.initialize( cipherAlgorithm, key, iv, 0 ); 804 cipher.setPadding( 0 ); 805 const int blockSize = cipher.blockSize(); 806 vector< sal_uInt8 > decryptedData( encryptedDataLength + 2*blockSize ); 807 808 int decryptedDataLength; 809 cipher.update( encryptedData, encryptedDataLength, decryptedData.data(), &decryptedDataLength ); 810 int finalDataLength; 811 cipher.final( &decryptedData[ decryptedDataLength ], &finalDataLength ); 812 decryptedDataLength += finalDataLength; 813 decryptedData.resize( decryptedDataLength ); 814 return decryptedData; 815 } 816 817 // Ported from Apache POI's org.apache.poi.poifs.crypt.agile.AgileDecryptor.hashInput(). 818 static vector< sal_uInt8 > hashInput( const vector< sal_uInt8 >& passwordHash, 819 const vector< sal_uInt8 >& salt, 820 const EVP_MD *digestAlgorithm, 821 const vector< sal_uInt8 >& blockKey, 822 const vector< sal_uInt8 >& inputKey, 823 const EVP_CIPHER *decryptionAlgorithm, 824 sal_uInt32 keySize, 825 sal_uInt32 blockSize ) 826 throw ( Exception ) 827 { 828 vector< sal_uInt8 > intermediateKey = generateKey( passwordHash, digestAlgorithm, blockKey, keySize ); 829 vector< sal_uInt8> iv = generateIv( salt, blockSize ); 830 vector< sal_uInt8 > zeroedInput( inputKey.size() ); 831 zeroedInput = inputKey; 832 toBlock0( zeroedInput, getNextBlockSize( zeroedInput.size(), blockSize ) ); 833 return decryptAll( decryptionAlgorithm, iv.data(), intermediateKey.data(), zeroedInput.data(), zeroedInput.size() ); 834 } 835 836 // Ported from Apache POI's org.apache.poi.poifs.crypt.agile.AgileDecryptor.verifyPassword(). 837 Sequence< NamedValue > AgileEncryptionInfo::verifyPassword( const OUString& password ) 838 throw ( Exception ) 839 { 840 const EVP_MD *digestAlgorithm = toOpenSSLDigestAlgorithm( passwordKeyEncryptor.hashAlgorithm ); 841 vector< sal_uInt8 > passwordHash = hashPassword( password, digestAlgorithm, passwordKeyEncryptor.saltValue, passwordKeyEncryptor.spinCount ); 842 843 static const sal_uInt8 verifierInputBlockData[] = { 0xfe, 0xa7, 0xd2, 0x76, 0x3b, 0x4b, 0x9e, 0x79 }; 844 vector< sal_uInt8 > verifierInputBlock( &verifierInputBlockData[ 0 ], &verifierInputBlockData[ sizeof( verifierInputBlockData ) ] ); 845 const EVP_CIPHER* cipher = toOpenSSLCipherAlgorithm( passwordKeyEncryptor.cipherAlgorithm, passwordKeyEncryptor.keyBits, passwordKeyEncryptor.cipherChaining ); 846 vector< sal_uInt8 > encryptedVerifierHash = hashInput( passwordHash, passwordKeyEncryptor.saltValue, digestAlgorithm, verifierInputBlock, 847 passwordKeyEncryptor.encryptedVerifierHashInput, cipher, passwordKeyEncryptor.keyBits, 848 passwordKeyEncryptor.blockSize ); 849 const EVP_MD *verifierDigestAlgorithm = toOpenSSLDigestAlgorithm( keyData.hashAlgorithm ); 850 OpenSSLDigest verifierDigest; 851 verifierDigest.initialize( verifierDigestAlgorithm ); 852 verifierDigest.update( encryptedVerifierHash.data(), encryptedVerifierHash.size() ); 853 encryptedVerifierHash.resize( verifierDigest.digestSize() ); 854 verifierDigest.final( encryptedVerifierHash.data(), NULL ); 855 856 static const sal_uInt8 verifierHashBlockData[] = { 0xd7, 0xaa, 0x0f, 0x6d, 0x30, 0x61, 0x34, 0x4e }; 857 vector< sal_uInt8 > verifierHashBlock( &verifierHashBlockData[ 0 ], &verifierHashBlockData[ sizeof( verifierHashBlockData ) ] ); 858 vector< sal_uInt8 > verifierHashDec = hashInput( passwordHash, passwordKeyEncryptor.saltValue, digestAlgorithm, verifierHashBlock, 859 passwordKeyEncryptor.encryptedVerifierHashValue, cipher, passwordKeyEncryptor.keyBits, 860 passwordKeyEncryptor.blockSize ); 861 toBlock0( verifierHashDec, verifierDigest.digestSize() ); 862 863 if( encryptedVerifierHash != verifierHashDec ) 864 return Sequence< NamedValue >(); 865 866 // Password is correct. Decrypt and store the encryption key. 867 static const sal_uInt8 cryptoKeyBlockData[] = { 0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6 }; 868 vector< sal_uInt8 > cryptoKeyBlock( &cryptoKeyBlockData[ 0 ], &cryptoKeyBlockData[ sizeof( cryptoKeyBlockData ) ] ); 869 encryptionKey = hashInput( passwordHash, passwordKeyEncryptor.saltValue, digestAlgorithm, cryptoKeyBlock, 870 passwordKeyEncryptor.encryptedKeyValue, cipher, passwordKeyEncryptor.keyBits, 871 passwordKeyEncryptor.blockSize ); 872 toBlock0( encryptionKey, passwordKeyEncryptor.keyBits / 8 ); 873 874 // Also decrypt the dataIntegrity fields for stream validation. Note that they are optional. 875 if( !dataIntegrity.encryptedHmacKey.empty() && !dataIntegrity.encryptedHmacValue.empty() ) 876 { 877 const EVP_MD* keyDataDigestAlgorithm = toOpenSSLDigestAlgorithm( keyData.hashAlgorithm ); 878 const EVP_CIPHER* keyDataCipher = toOpenSSLCipherAlgorithm( keyData.cipherAlgorithm, keyData.keyBits, keyData.cipherChaining ); 879 static const sal_uInt8 integrityKeyBlockData[] = { 0x5f, 0xb2, 0xad, 0x01, 0x0c, 0xb9, 0xe1, 0xf6 }; 880 vector< sal_uInt8 > integrityKeyBlock( &integrityKeyBlockData[ 0 ], &integrityKeyBlockData[ sizeof( integrityKeyBlockData ) ] ); 881 vector< sal_uInt8 > integrityKeyIv = generateIv( keyDataDigestAlgorithm, keyData.saltValue, integrityKeyBlock, keyData.blockSize ); 882 hmacKey = decryptAll( keyDataCipher, integrityKeyIv.data(), encryptionKey.data(), dataIntegrity.encryptedHmacKey.data(), dataIntegrity.encryptedHmacKey.size() ); 883 toBlock0( hmacKey, OpenSSLDigest::digestSize( keyDataDigestAlgorithm ) ); 884 885 static const sal_uInt8 integrityValueBlockData[] = { 0xa0, 0x67, 0x7f, 0x02, 0xb2, 0x2c, 0x84, 0x33 }; 886 vector< sal_uInt8 > integrityValueBlock( &integrityValueBlockData[ 0 ], &integrityValueBlockData[ sizeof( integrityValueBlockData ) ] ); 887 vector< sal_uInt8 > integrityValueIv = generateIv( keyDataDigestAlgorithm, keyData.saltValue, integrityValueBlock, keyData.blockSize ); 888 hmacValue = decryptAll( keyDataCipher, integrityValueIv.data(), encryptionKey.data(), dataIntegrity.encryptedHmacValue.data(), dataIntegrity.encryptedHmacValue.size() ); 889 toBlock0( hmacValue, OpenSSLDigest::digestSize( keyDataDigestAlgorithm ) ); 890 } 891 892 // On success, MUST populate something into the encryption data, even though we'll never use it. 893 SequenceAsHashMap encryptionData; 894 encryptionData[ CREATE_OUSTRING( "OOXMLAgileEncryptionPasswordVerified" ) ] <<= sal_True; 895 return encryptionData.getAsConstNamedValueList(); 896 } 897 898 bool AgileEncryptionInfo::verifyEncryptionData( const Sequence< NamedValue >& rEncryptionData ) 899 throw ( Exception ) 900 { 901 // OpenGrok shows how only main/comphelper/source/misc/docpasswordhelper.cxx calls IDocPasswordVerifier::verifyEncryptionData(), 902 // and only when the password is wrong and the rMediaEncData non-empty, which presumably allows other forms of encryption 903 // (eg. by certificate) to be used. We only support password for now. 904 return false; 905 } 906 907 // Ported from Apache POI's org.apache.poi.poifs.crypt.agile.AgileDecryptor.initCipherForBlock(). 908 void AgileEncryptionInfo::decryptStream( BinaryXInputStream &aEncryptedPackage, BinaryXOutputStream &aDecryptedPackage ) 909 throw ( Exception ) 910 { 911 if( encryptionKey.empty() ) 912 throw Exception( OUString::createFromAscii( "Encryption key not set, was the password wrong?" ), Reference< XInterface >() ); 913 const EVP_CIPHER* cipherAlgorithm = toOpenSSLCipherAlgorithm( keyData.cipherAlgorithm, keyData.keyBits, keyData.cipherChaining ); 914 const EVP_MD* digestAlgorithm = toOpenSSLDigestAlgorithm( keyData.hashAlgorithm ); 915 OpenSSLCipher cipher; 916 917 const sal_uInt64 decryptedSize = aEncryptedPackage.readuInt64(); 918 919 sal_uInt8 inputBuffer[ 4096 ]; 920 vector< sal_uInt8 > outputBuffer( 4096 + 2*cipher.blockSize() ); 921 sal_Int32 bytesIn; 922 int bytesOut; 923 int finalBytesOut; 924 sal_uInt64 totalBytesWritten = 0; 925 926 vector< sal_uInt8 > blockBytes( 4 ); 927 bool done = false; 928 for ( sal_uInt32 block = 0; !done; block++ ) 929 { 930 ByteOrderConverter::writeLittleEndian( blockBytes.data(), block ); 931 vector< sal_uInt8 > iv = generateIv( digestAlgorithm, keyData.saltValue, blockBytes, keyData.blockSize ); 932 cipher.initialize( cipherAlgorithm, encryptionKey.data(), iv.data(), 0 ); 933 cipher.setPadding( 0 ); 934 935 bytesIn = aEncryptedPackage.readMemory( inputBuffer, sizeof( inputBuffer ) ); 936 if( bytesIn > 0 ) 937 { 938 cipher.update( inputBuffer, bytesIn, outputBuffer.data(), &bytesOut ); 939 cipher.final( &outputBuffer[ bytesOut ], &finalBytesOut ); 940 bytesOut += finalBytesOut; 941 if( decryptedSize < (totalBytesWritten + bytesOut) ) 942 { 943 bytesOut = decryptedSize % sizeof( inputBuffer ); 944 done = true; 945 } 946 aDecryptedPackage.writeMemory( outputBuffer.data(), bytesOut ); 947 totalBytesWritten += bytesOut; 948 } else 949 done = true; 950 } 951 952 aDecryptedPackage.flush(); 953 } 954 955 EncryptionInfo* EncryptionInfo::readEncryptionInfo( const Reference< XComponentContext >& context, Reference< XInputStream >& inputStream ) 956 throw ( Exception ) 957 { 958 sal_uInt16 nVersionMajor = readUInt16LE( inputStream ); 959 sal_uInt16 nVersionMinor = readUInt16LE( inputStream ); 960 if( ( nVersionMajor == 2 && nVersionMinor == 2 ) || 961 ( nVersionMajor == 3 && nVersionMinor == 2 ) || 962 ( nVersionMajor == 4 && nVersionMinor == 2 ) ) 963 { 964 // 2.3.4.5 Standard Encryption 965 BinaryXInputStream aInfoStrm( inputStream, false ); 966 return new StandardEncryptionInfo( aInfoStrm ); 967 } 968 else if ( nVersionMajor == 4 && nVersionMajor == 4 ) 969 { 970 // 2.3.4.10 Agile Encryption 971 return new AgileEncryptionInfo( context, inputStream ); 972 } 973 else 974 { 975 char msg[ 1024 ]; 976 snprintf( msg, sizeof( msg ), "EncryptionInfo::readEncryptionInfo() error: unsupported EncryptionVersionInfo header with major=%hu minor=%hu", 977 nVersionMajor, nVersionMinor ); 978 throw Exception( OUString::createFromAscii( msg ), Reference< XInterface >() ); 979 } 980 } 981 982 // ============================================================================ 983 984 } // namespace core 985 } // namespace oox 986