Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #10 from jpmorganchase/master
Browse files Browse the repository at this point in the history
pull changes fron jpm master
  • Loading branch information
lazar-ivanov authored May 3, 2017
2 parents 6b56ff4 + 8fdcff9 commit b4c1f3a
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 74 deletions.
96 changes: 84 additions & 12 deletions src/include/baselib/core/SecureStringWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,57 @@ namespace bl
INITIAL_CAPACITY = 16u
};

SecureStringWrapperT( SAA_inout std::string* externalString = nullptr )
: m_implPtr( externalString ? externalString : &m_impl )
SecureStringWrapperT(
SAA_inout_opt std::string* externalString = nullptr,
SAA_in_opt const std::size_t initialCapacity = 0U
)
: m_implPtr( externalString ? externalString : &m_impl ),
m_dataPtr( m_implPtr -> data() )
{
/*
* This class can be used in three ways:
* 1. as a standalone object, which uses internal string as a storage
* 2. as a wrapper of an external string, which will be managed only by object of this class
* 3. as a wrapper of an external string, which will be modified outside of this class
* In order to assure a secure memory cleanup in the last case, user has to specify
* an initial capacity up to which the string is expected to grow. The string has to
* be empty, otherwise the allocation hint will be ignored. If the string is reallocated
* due to external changes, the wrapper is no longer able to wipe it securely.In such case,
* the application will be terminated. Due to this, the only safe operations are probably
* 'push_back', 'append' and some forms of 'assign' with the first being recommended way of
* updating the string.
*/

if( initialCapacity > 0 )
{
BL_CHK(
false,
externalString && externalString -> empty(),
"Initial capacity can only be specified for empty external string "
);

reserve( initialCapacity );
}
}

SecureStringWrapperT( SAA_in const SecureStringWrapperT& other )
: m_implPtr( &m_impl )
: m_implPtr( &m_impl ),
m_dataPtr( m_implPtr -> data() )
{
append( *other.m_implPtr );
append( other );
}

SecureStringWrapperT( SAA_in SecureStringWrapperT&& other )
: m_implPtr( &m_impl )
: m_implPtr( &m_impl ),
m_dataPtr( m_implPtr -> data() )
{
append( *other.m_implPtr );
append( other );
other.clear();
}

explicit SecureStringWrapperT( SAA_in std::string&& other )
: m_implPtr( &m_impl )
: m_implPtr( &m_impl ),
m_dataPtr( m_implPtr -> data() )
{
append( other );
secureClear( other );
Expand All @@ -78,7 +109,7 @@ namespace bl
}

clear();
append( *other.m_implPtr );
append( other );

return *this;
}
Expand All @@ -90,7 +121,11 @@ namespace bl
return *this;
}

return *this = std::move( *other.m_implPtr );
clear();
append( other );
other.clear();

return *this;
}

SecureStringWrapperT& operator=( SAA_in std::string&& other )
Expand Down Expand Up @@ -124,13 +159,17 @@ namespace bl
{
m_implPtr -> push_back( ch );
}

m_size = size();
}

void append( SAA_in const char ch )
{
grow( size() + 1 );

m_implPtr -> push_back( ch );

m_size = size();
}

const std::string& getAsNonSecureString() const NOEXCEPT
Expand All @@ -150,11 +189,38 @@ namespace bl

void clear() NOEXCEPT
{
checkWrappedStringIntegrity();

secureClear( *m_implPtr );

m_size = size();
}

private:

void reserve( SAA_in const std::size_t newCapacity )
{
m_implPtr -> reserve( newCapacity );
m_dataPtr = m_implPtr -> data();
}

void checkWrappedStringIntegrity()
{
BL_RT_ASSERT(
m_dataPtr == m_implPtr -> data(),
"Unable to ensure integrity of the wrapped string, as it was reallocated by external operation"
);

/*
* The wrapped external string can grow as a result of external operation but cannot shrink.
*/

BL_RT_ASSERT(
m_size <= size(),
"Unable to ensure integrity of the wrapped string, as it was shrank by external operation"
);
}

static void secureClear( SAA_inout std::string& other ) NOEXCEPT
{
BL_NOEXCEPT_BEGIN()
Expand Down Expand Up @@ -186,23 +252,29 @@ namespace bl
{
if( m_implPtr -> empty() )
{
m_implPtr -> reserve( calculateNewCapacity( newSize ) );
reserve( calculateNewCapacity( newSize ) );
}
else if( newSize > m_implPtr -> capacity() )
{
SecureStringWrapperT temp( *this );

clear();
reserve( calculateNewCapacity( newSize ) );

m_implPtr -> reserve( calculateNewCapacity( newSize ) );
m_implPtr -> assign( *temp.m_implPtr );
for( const auto ch : *temp.m_implPtr )
{
m_implPtr -> push_back( ch );
}
}
}

private:

std::string m_impl;
std::string* m_implPtr;

const char* m_dataPtr;
cpp::ScalarTypeIniter< std::size_t > m_size;
};

using SecureStringWrapper = SecureStringWrapperT<>;
Expand Down
4 changes: 1 addition & 3 deletions src/include/baselib/http/SimpleSecureHttpSslTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ namespace bl
str::empty() /* content */,
BL_PARAM_FWD( requestHeaders )
),
m_secureContentIn( &this -> m_contentIn ),
m_secureContentOut( &this -> m_contentOut )
m_secureContentIn( &this -> m_contentIn )
{
m_secureContentIn = content;

Expand All @@ -82,7 +81,6 @@ namespace bl
protected:

str::SecureStringWrapper m_secureContentIn;
str::SecureStringWrapper m_secureContentOut;

};

Expand Down
1 change: 1 addition & 0 deletions src/utests/include/utests/baselib/HttpServerHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <baselib/http/SimpleHttpTask.h>
#include <baselib/http/SimpleHttpSslTask.h>
#include <baselib/http/SimpleSecureHttpSslTask.h>
#include <baselib/http/Globals.h>

#include <baselib/tasks/TasksUtils.h>
Expand Down
108 changes: 49 additions & 59 deletions src/utests/utf_baselib/TestBaselibDefault.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* This file is part of the swblocks-baselib library.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand Down Expand Up @@ -5160,83 +5160,59 @@ UTF_AUTO_TEST_CASE( BaseLib_StringUtilsSecureStringWrapper )
UTF_CHECK_EQUAL( sec1.size(), 0U );
UTF_CHECK( sec1.empty() );

const char* dataPtr = nullptr;

const auto chkDataPtrIsNot = [](
SAA_in const char* dataPtr,
SAA_in const char* cmpString
)
{
while( *cmpString )
{
UTF_CHECK( *dataPtr != *cmpString );
++cmpString;
++dataPtr;
}
};

{
std::string s( "test" );

dataPtr = s.c_str();

bl::str::SecureStringWrapper sec2( std::move( s ) );
/*
* Testing wipe functionality
*/

chkDataPtrIsNot( dataPtr, "test" );
std::string s( "test" );

UTF_CHECK( s.empty() );
UTF_CHECK( ! sec2.empty() );
UTF_CHECK_EQUAL( sec2.getAsNonSecureString(), "test" );
{
bl::str::SecureStringWrapper sec2( std::move( s ) );

dataPtr = sec2.getAsNonSecureString().c_str();
UTF_CHECK( s.empty() );
UTF_CHECK( ! sec2.empty() );
UTF_CHECK_EQUAL( sec2.getAsNonSecureString(), "test" );
}
}

chkDataPtrIsNot( dataPtr, "test" );

{
std::string s( "test" );
dataPtr = s.c_str();
/*
* Testing move assignment operator from string and move ctor from SecureStringWrapper
*/

std::string s( "test" );
bl::str::SecureStringWrapper sec2;
sec2 = std::move( s );

chkDataPtrIsNot( dataPtr, "test" );
sec2 = std::move( s );

UTF_CHECK( s.empty() );
UTF_CHECK( ! sec2.empty() );
UTF_CHECK_EQUAL( sec2.getAsNonSecureString(), "test" );

dataPtr = sec2.getAsNonSecureString().c_str();

bl::str::SecureStringWrapper sec3( std::move( sec2 ) );

chkDataPtrIsNot( dataPtr, "test" );

UTF_CHECK( sec2.empty() );
UTF_CHECK( ! sec3.empty() );
UTF_CHECK_EQUAL( sec3.getAsNonSecureString(), "test" );

dataPtr = sec3.getAsNonSecureString().c_str();

sec3.clear();

UTF_CHECK( sec3.empty() );

chkDataPtrIsNot( dataPtr, "test" );
}

{
/*
* Testing move ctor from string + reallocation
*/

std::string s( "test" );

bl::str::SecureStringWrapper sec2( std::move( s ) );
bl::str::SecureStringWrapper sec3;

dataPtr = sec2.getAsNonSecureString().c_str();

sec3 = std::move( sec2 );

chkDataPtrIsNot( dataPtr, "test" );

UTF_CHECK( sec2.empty() );
UTF_CHECK( ! sec3.empty() );
UTF_CHECK_EQUAL( sec3.getAsNonSecureString(), "test" );
Expand All @@ -5249,8 +5225,6 @@ UTF_AUTO_TEST_CASE( BaseLib_StringUtilsSecureStringWrapper )

UTF_CHECK_EQUAL( sec3.getAsNonSecureString(), "testtest1" );

dataPtr = sec3.getAsNonSecureString().c_str();

bl::str::SecureStringWrapper sec4( "long string, long string, long string, long string, " );
sec4.append( "long string, long string, long string, long string, " );
sec4.append( "long string, long string, long string, long string, " );
Expand All @@ -5263,21 +5237,20 @@ UTF_AUTO_TEST_CASE( BaseLib_StringUtilsSecureStringWrapper )

sec3 = std::move( sec4 );

chkDataPtrIsNot( dataPtr, "test" );
chkDataPtrIsNot( dataPtr4, "long" );

UTF_CHECK( sec4.empty() );
UTF_CHECK( ! sec3.empty() );
UTF_CHECK_EQUAL( sec3.size(), size4 );
UTF_CHECK( dataPtr4 != sec3.getAsNonSecureString().c_str() );
}

{
/*
* Testing SecureStringWrapper management of external string
*/

std::string s( "test" );

{
dataPtr = s.c_str();

bl::str::SecureStringWrapper sec2( &s );

UTF_CHECK( ! s.empty() );
Expand All @@ -5287,17 +5260,34 @@ UTF_AUTO_TEST_CASE( BaseLib_StringUtilsSecureStringWrapper )

sec2.append( "long string, long string, long string, long string" );

chkDataPtrIsNot( dataPtr, "test" );

UTF_CHECK( dataPtr != s.c_str() );
UTF_CHECK_EQUAL( s.c_str(), sec2.getAsNonSecureString().c_str() );

dataPtr = s.c_str();
}

UTF_CHECK( s.empty() );
}

chkDataPtrIsNot( dataPtr, "test" );
{
/*
* Initial capacity can only be specified for external and empty string
*/

UTF_CHECK_THROW(
bl::str::SecureStringWrapper sec1( nullptr, 1024 ),
bl::UnexpectedException
);

std::string s( "test" );

UTF_CHECK_THROW(
bl::str::SecureStringWrapper sec2( &s, 1024 ),
bl::UnexpectedException
);

std::string s2;

UTF_CHECK_NO_THROW(
bl::str::SecureStringWrapper sec3( &s2, 1024 )
);
}
}

Expand Down
Loading

0 comments on commit b4c1f3a

Please sign in to comment.