summaryrefslogtreecommitdiff
path: root/lib/crypto/CipherContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/crypto/CipherContext.cpp')
-rw-r--r--lib/crypto/CipherContext.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/crypto/CipherContext.cpp b/lib/crypto/CipherContext.cpp
index e5cd9b0e..6621f79a 100644
--- a/lib/crypto/CipherContext.cpp
+++ b/lib/crypto/CipherContext.cpp
@@ -13,6 +13,10 @@
#include "CipherContext.h"
#include "CipherDescription.h"
#include "CipherException.h"
+<<<<<<< HEAD
+=======
+#include "CryptoUtils.h"
+>>>>>>> 0.12
#include "Random.h"
#include "MemLeakFindOn.h"
@@ -26,12 +30,21 @@
//
// --------------------------------------------------------------------------
CipherContext::CipherContext()
+<<<<<<< HEAD
: mInitialised(false),
mWithinTransform(false),
mPaddingOn(true)
#ifdef HAVE_OLD_SSL
, mFunction(Decrypt),
mpDescription(0)
+=======
+: mInitialised(false),
+ mWithinTransform(false),
+ mPaddingOn(true),
+ mFunction(None)
+#ifdef HAVE_OLD_SSL
+, mpDescription(0)
+>>>>>>> 0.12
#endif
{
}
@@ -64,6 +77,31 @@ CipherContext::~CipherContext()
// --------------------------------------------------------------------------
//
// Function
+<<<<<<< HEAD
+=======
+// Name: CipherContext::LogError(const std::string& operation)
+// Purpose: Logs and clears any OpenSSL errors, returning the
+// most recent error message for use in exception
+// messages.
+//
+// It's essential to clear the OpenSSL error queue after
+// ANY failed OpenSSL operation, because OpenSSL may
+// decide that a later non-blocking read (returning -1
+// with errno == EAGAIN) is actually an error if there's
+// any errors left in the queue. See SSL_get_error
+// (called from SocketStreamTLS::Read) for the details.
+// Created: 26/04/12
+//
+// --------------------------------------------------------------------------
+std::string CipherContext::LogError(const std::string& operation)
+{
+ return CryptoUtils::LogError(operation);
+}
+
+// --------------------------------------------------------------------------
+//
+// Function
+>>>>>>> 0.12
// Name: CipherContext::Init(CipherContext::CipherFunction, const CipherDescription &)
// Purpose: Initialises the context, specifying the direction for the encryption, and a
// description of the cipher to use, it's keys, etc
@@ -82,10 +120,17 @@ void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDes
THROW_EXCEPTION(CipherException, BadArguments)
}
+<<<<<<< HEAD
+=======
+ // Store function for later
+ mFunction = Function;
+
+>>>>>>> 0.12
// Initialise the cipher
#ifndef HAVE_OLD_SSL
EVP_CIPHER_CTX_init(&ctx); // no error return code, even though the docs says it does
+<<<<<<< HEAD
if(EVP_CipherInit_ex(&ctx, rDescription.GetCipher(), NULL, NULL, NULL, Function) != 1)
#else
// Store function for later
@@ -96,10 +141,27 @@ void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDes
#endif
{
THROW_EXCEPTION(CipherException, EVPInitFailure)
+=======
+ if(EVP_CipherInit_ex(&ctx, rDescription.GetCipher(), NULL, NULL, NULL,
+ (mFunction == Encrypt) ? 1 : 0) != 1)
+#else
+ // Use old version of init call
+ if(EVP_CipherInit(&ctx, rDescription.GetCipher(), NULL, NULL,
+ (mFunction == Encrypt) ? 1 : 0) != 1)
+#endif
+ {
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
+ "Failed to initialise " << rDescription.GetFullName()
+ << "cipher: " << LogError("initialising cipher"));
+>>>>>>> 0.12
}
try
{
+<<<<<<< HEAD
+=======
+ mCipherName = rDescription.GetFullName();
+>>>>>>> 0.12
#ifndef HAVE_OLD_SSL
// Let the description set up everything else
rDescription.SetupParameters(&ctx);
@@ -114,6 +176,12 @@ void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDes
}
catch(...)
{
+<<<<<<< HEAD
+=======
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
+ "Failed to configure " << mCipherName << " cipher: " <<
+ LogError("configuring cipher"));
+>>>>>>> 0.12
EVP_CIPHER_CTX_cleanup(&ctx);
throw;
}
@@ -174,7 +242,13 @@ void CipherContext::Begin()
// Initialise the cipher context again
if(EVP_CipherInit(&ctx, NULL, NULL, NULL, -1) != 1)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CipherException, EVPInitFailure)
+=======
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
+ "Failed to reset " << mCipherName << " cipher: " <<
+ LogError("resetting cipher"));
+>>>>>>> 0.12
}
// Mark as being within a transform
@@ -227,7 +301,13 @@ int CipherContext::Transform(void *pOutBuffer, int OutLength, const void *pInBuf
int outLength = OutLength;
if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CipherException, EVPUpdateFailure)
+=======
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPUpdateFailure,
+ "Failed to " << GetFunction() << " (update) " <<
+ mCipherName << " cipher: " << LogError(GetFunction()));
+>>>>>>> 0.12
}
return outLength;
@@ -273,9 +353,18 @@ int CipherContext::Final(void *pOutBuffer, int OutLength)
// Do the transform
int outLength = OutLength;
#ifndef HAVE_OLD_SSL
+<<<<<<< HEAD
if(EVP_CipherFinal_ex(&ctx, (unsigned char*)pOutBuffer, &outLength) != 1)
{
THROW_EXCEPTION(CipherException, EVPFinalFailure)
+=======
+ if(EVP_CipherFinal(&ctx, (unsigned char*)pOutBuffer, &outLength) != 1)
+ {
+ mWithinTransform = false;
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPFinalFailure,
+ "Failed to " << GetFunction() << " (final) " <<
+ mCipherName << " cipher: " << LogError(GetFunction()));
+>>>>>>> 0.12
}
#else
OldOpenSSLFinal((unsigned char*)pOutBuffer, outLength);
@@ -353,7 +442,12 @@ void CipherContext::OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut)
}
}
// Reinitialise the cipher for the next time around
+<<<<<<< HEAD
if(EVP_CipherInit(&ctx, mpDescription->GetCipher(), NULL, NULL, mFunction) != 1)
+=======
+ if(EVP_CipherInit(&ctx, mpDescription->GetCipher(), NULL, NULL,
+ (mFunction == Encrypt) ? 1 : 0) != 1)
+>>>>>>> 0.12
{
THROW_EXCEPTION(CipherException, EVPInitFailure)
}
@@ -451,6 +545,7 @@ int CipherContext::TransformBlock(void *pOutBuffer, int OutLength, const void *p
// Do the entire block
int outLength = 0;
+<<<<<<< HEAD
try
{
// Update
@@ -482,6 +577,31 @@ int CipherContext::TransformBlock(void *pOutBuffer, int OutLength, const void *p
#endif
throw;
}
+=======
+
+ // Update
+ outLength = OutLength;
+ if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1)
+ {
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPUpdateFailure,
+ "Failed to " << GetFunction() << " (update) " <<
+ mCipherName << " cipher: " << LogError(GetFunction()));
+ }
+
+ // Finalise
+ int outLength2 = OutLength - outLength;
+#ifndef HAVE_OLD_SSL
+ if(EVP_CipherFinal(&ctx, ((unsigned char*)pOutBuffer) + outLength, &outLength2) != 1)
+ {
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPFinalFailure,
+ "Failed to " << GetFunction() << " (final) " <<
+ mCipherName << " cipher: " << LogError(GetFunction()));
+ }
+#else
+ OldOpenSSLFinal(((unsigned char*)pOutBuffer) + outLength, outLength2);
+#endif
+ outLength += outLength2;
+>>>>>>> 0.12
return outLength;
}
@@ -531,7 +651,13 @@ void CipherContext::SetIV(const void *pIV)
// Set IV
if(EVP_CipherInit(&ctx, NULL, NULL, (unsigned char *)pIV, -1) != 1)
{
+<<<<<<< HEAD
THROW_EXCEPTION(CipherException, EVPInitFailure)
+=======
+ THROW_EXCEPTION_MESSAGE(CipherException, EVPInitFailure,
+ "Failed to " << GetFunction() << " (set IV) " <<
+ mCipherName << " cipher: " << LogError(GetFunction()));
+>>>>>>> 0.12
}
#ifdef HAVE_OLD_SSL
@@ -576,6 +702,7 @@ const void *CipherContext::SetRandomIV(int &rLengthOut)
// Generate some random data
Random::Generate(mGeneratedIV, ivLen);
+<<<<<<< HEAD
// Set IV
if(EVP_CipherInit(&ctx, NULL, NULL, mGeneratedIV, -1) != 1)
@@ -590,6 +717,9 @@ const void *CipherContext::SetRandomIV(int &rLengthOut)
mpDescription->SetIV(mGeneratedIV);
}
#endif
+=======
+ SetIV(mGeneratedIV);
+>>>>>>> 0.12
// Return the IV and it's length
rLengthOut = ivLen;