22#include <com/sun/star/lang/DisposedException.hpp>
23#include <osl/diagnose.h>
24#include <rtl/random.h>
32uno::Reference< xml::crypto::XCipherContext >
OCipherContext::Create( CK_MECHANISM_TYPE nNSSCipherID,
const uno::Sequence< ::sal_Int8 >& aKey,
const uno::Sequence< ::sal_Int8 >& aInitializationVector,
bool bEncryption,
bool bW3CPadding )
36 xResult->m_pSlot = PK11_GetBestSlot( nNSSCipherID,
nullptr );
37 if ( xResult->m_pSlot )
39 SECItem aKeyItem = { siBuffer,
const_cast< unsigned char*
>(
reinterpret_cast< const unsigned char*
>( aKey.getConstArray() ) ), sal::static_int_cast<unsigned>( aKey.getLength() ) };
40 xResult->m_pSymKey = PK11_ImportSymKey( xResult->m_pSlot, nNSSCipherID, PK11_OriginDerive, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, &aKeyItem,
nullptr );
41 if ( xResult->m_pSymKey )
43 SECItem aIVItem = { siBuffer,
const_cast< unsigned char*
>(
reinterpret_cast< const unsigned char*
>( aInitializationVector.getConstArray() ) ), sal::static_int_cast<unsigned>( aInitializationVector.getLength() ) };
44 xResult->m_pSecParam = PK11_ParamFromIV( nNSSCipherID, &aIVItem );
45 if ( xResult->m_pSecParam )
47 xResult->m_pContext = PK11_CreateContextBySymKey( nNSSCipherID, bEncryption ? CKA_ENCRYPT : CKA_DECRYPT, xResult->m_pSymKey, xResult->m_pSecParam);
48 if ( xResult->m_pContext )
50 xResult->m_bEncryption = bEncryption;
51 xResult->m_bW3CPadding = bW3CPadding;
52 xResult->m_bPadding = bW3CPadding || ( PK11_GetPadMechanism( nNSSCipherID ) == nNSSCipherID );
53 xResult->m_nBlockSize = PK11_GetBlockSize( nNSSCipherID, xResult->m_pSecParam );
61 return uno::Reference< xml::crypto::XCipherContext >();
98 throw uno::RuntimeException();
101 throw lang::DisposedException();
103 uno::Sequence< sal_Int8 > aToConvert;
104 if (
aData.hasElements() )
107 OSL_ENSURE( nOldLastBlockLen <=
m_nBlockSize,
"Unexpected last block size!" );
109 sal_Int32 nAvailableData = nOldLastBlockLen +
aData.getLength();
110 sal_Int32 nToConvertLen;
114 nToConvertLen = nAvailableData;
118 nToConvertLen = nAvailableData - nAvailableData %
m_nBlockSize;
129 aToConvert.realloc( nToConvertLen );
130 if ( nToConvertLen == 0 )
136 else if ( nToConvertLen < nOldLastBlockLen )
138 memcpy( aToConvert.getArray(),
m_aLastBlock.getConstArray(), nToConvertLen );
141 memcpy(
m_aLastBlock.getArray() + nOldLastBlockLen - nToConvertLen,
aData.getConstArray(),
aData.getLength() );
145 memcpy( aToConvert.getArray(),
m_aLastBlock.getConstArray(), nOldLastBlockLen );
146 if ( nToConvertLen > nOldLastBlockLen )
147 memcpy( aToConvert.getArray() + nOldLastBlockLen,
aData.getConstArray(), nToConvertLen - nOldLastBlockLen );
149 memcpy(
m_aLastBlock.getArray(),
aData.getConstArray() + nToConvertLen - nOldLastBlockLen, nAvailableData - nToConvertLen );
153 uno::Sequence< sal_Int8 > aResult;
154 OSL_ENSURE( aToConvert.getLength() %
m_nBlockSize == 0,
"Unexpected size of the data to encrypt!" );
155 if ( aToConvert.hasElements() )
158 aResult.realloc( aToConvert.getLength() +
m_nBlockSize );
159 if ( PK11_CipherOp(
m_pContext,
reinterpret_cast< unsigned char*
>( aResult.getArray() ), &nResultLen, aResult.getLength(),
reinterpret_cast< const unsigned char*
>( aToConvert.getConstArray() ), aToConvert.getLength() ) != SECSuccess )
163 throw uno::RuntimeException();
167 aResult.realloc( nResultLen );
175 std::unique_lock aGuard(
m_aMutex );
178 throw uno::RuntimeException();
181 throw lang::DisposedException();
189 throw uno::RuntimeException(
"The data should contain complete blocks only." );
198 sal_Int32 nPaddingSize =
m_nBlockSize - nSizeForPadding;
200 m_aLastBlock.realloc( nOldLastBlockLen + nPaddingSize );
203 if ( nPaddingSize > 1 )
206 rtl_random_getBytes( aRandomPool, pLastBlock + nOldLastBlockLen, nPaddingSize - 1 );
207 rtl_random_destroyPool ( aRandomPool );
215 uno::Sequence< sal_Int8 > aResult;
220 if ( PK11_CipherOp(
m_pContext,
reinterpret_cast< unsigned char*
>( aResult.getArray() ), &nPrefResLen, aResult.getLength(),
reinterpret_cast< const unsigned char*
>(
m_aLastBlock.getConstArray() ),
m_aLastBlock.getLength() ) != SECSuccess )
224 throw uno::RuntimeException();
227 aResult.realloc( nPrefResLen );
231 sal_Int32 nPrefixLen = aResult.getLength();
233 unsigned nFinalLen = 0;
234 if ( PK11_DigestFinal(
m_pContext,
reinterpret_cast< unsigned char*
>( aResult.getArray() + nPrefixLen ), &nFinalLen, aResult.getLength() - nPrefixLen ) != SECSuccess )
238 throw uno::RuntimeException();
241 aResult.realloc( nPrefixLen + nFinalLen );
247 OSL_ENSURE( aResult.getLength() >=
m_nBlockSize,
"Not enough data to handle the padding!" );
249 sal_Int8 nBytesToRemove = aResult[aResult.getLength() - 1];
250 if ( nBytesToRemove <= 0 || nBytesToRemove > aResult.getLength() )
254 throw uno::RuntimeException();
257 aResult.realloc( aResult.getLength() - nBytesToRemove );
static css::uno::Reference< css::xml::crypto::XCipherContext > Create(CK_MECHANISM_TYPE nNSSCipherID, const css::uno::Sequence< ::sal_Int8 > &aKey, const css::uno::Sequence< ::sal_Int8 > &aInitializationVector, bool bEncryption, bool bW3CPadding)
virtual css::uno::Sequence< ::sal_Int8 > SAL_CALL convertWithCipherContext(const css::uno::Sequence< ::sal_Int8 > &aData) override
virtual css::uno::Sequence< ::sal_Int8 > SAL_CALL finalizeCipherContextAndDispose() override
css::uno::Sequence< sal_Int8 > m_aLastBlock
constexpr OUStringLiteral aData