Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace app_applestreamingclient {
private:
IOBuffer _tempBuffer;
IOBuffer _inputBuffer;
EVP_CIPHER_CTX _decContex;
EVP_CIPHER_CTX *_decContex;
bool _lastChunk;
uint8_t *_pIV;
uint8_t *_pKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ InboundAESProtocol::InboundAESProtocol()
memset(_pIV, 0, 16);
_pKey = new uint8_t[16];
memset(_pKey, 0, 16);
memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX));
_decContex = EVP_CIPHER_CTX_new();
_totalDecrypted = 0;
}

InboundAESProtocol::~InboundAESProtocol() {
EVP_CIPHER_CTX_cleanup(&_decContex);
memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX));
EVP_CIPHER_CTX_free(_decContex);
delete[] _pIV;
delete[] _pKey;
}
Expand All @@ -60,11 +59,9 @@ bool InboundAESProtocol::Initialize(Variant &parameters) {
_inputBuffer.IgnoreAll();
_tempBuffer.IgnoreAll();

EVP_CIPHER_CTX_cleanup(&_decContex);
memset(&_decContex, 0, sizeof (EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(&_decContex);
EVP_DecryptInit_ex(&_decContex, EVP_aes_128_cbc(), NULL, _pKey, _pIV);
EVP_CIPHER_CTX_set_padding(&_decContex, 0);
EVP_CIPHER_CTX_reset(_decContex);
EVP_DecryptInit_ex(_decContex, EVP_aes_128_cbc(), NULL, _pKey, _pIV);
EVP_CIPHER_CTX_set_padding(_decContex, 0);

return true;
}
Expand Down Expand Up @@ -105,14 +102,14 @@ bool InboundAESProtocol::SignalInputData(IOBuffer &buffer) {
int decryptedFinalSize = 0;
uint32_t padding = 0;

EVP_DecryptUpdate(&_decContex, pTempData, &decryptedSize, GETIBPOINTER(buffer), safeSize);
EVP_DecryptUpdate(_decContex, pTempData, &decryptedSize, GETIBPOINTER(buffer), safeSize);
_totalDecrypted += decryptedSize;

//6. Decrypt leftovers
bool transferCompleted = false;
if (((HTTPBufferProtocol *) GetFarProtocol())->TransferCompleted()) {
transferCompleted = true;
EVP_DecryptFinal_ex(&_decContex,
EVP_DecryptFinal_ex(_decContex,
pTempData + decryptedSize,
&decryptedFinalSize);
_totalDecrypted += decryptedFinalSize;
Expand Down
3 changes: 2 additions & 1 deletion sources/common/include/utils/misc/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <openssl/aes.h>
#include <openssl/engine.h>
#include <openssl/conf.h>
#include "utils/misc/libcrypto-compat.h"

/*!
@class DHWrapper
Expand Down Expand Up @@ -83,7 +84,7 @@ class DLLEXP DHWrapper {
bool CopySharedKey(uint8_t *pDst, int32_t dstLength);
private:
void Cleanup();
bool CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength);
bool CopyKey(const BIGNUM *pNum, uint8_t *pDst, int32_t dstLength);
};

DLLEXP void InitRC4Encryption(uint8_t *secretKey, uint8_t *pubKeyIn, uint8_t *pubKeyOut,
Expand Down
25 changes: 25 additions & 0 deletions sources/common/include/utils/misc/libcrypto-compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef LIBCRYPTO_COMPAT_H
#define LIBCRYPTO_COMPAT_H

#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L

#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>

int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key);
int DH_set_length(DH *dh, long length);

EVP_MD_CTX *EVP_MD_CTX_new(void);
void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
#define EVP_MD_CTX_reset EVP_MD_CTX_cleanup

HMAC_CTX *HMAC_CTX_new(void);
void HMAC_CTX_free(HMAC_CTX *ctx);
#define HMAC_CTX_reset HMAC_CTX_cleanup

#endif /* OPENSSL_VERSION_NUMBER */

#endif /* LIBCRYPTO_COMPAT_H */
116 changes: 64 additions & 52 deletions sources/common/src/utils/misc/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ DHWrapper::~DHWrapper() {
}

bool DHWrapper::Initialize() {
BIGNUM *p = NULL, *g = NULL;
Cleanup();

//1. Create the DH
Expand All @@ -46,42 +47,53 @@ bool DHWrapper::Initialize() {
}

//2. Create his internal p and g
_pDH->p = BN_new();
if (_pDH->p == NULL) {
p = BN_new();
if (p == NULL) {
FATAL("Unable to create p");
Cleanup();
return false;
goto return_error;
}
_pDH->g = BN_new();
if (_pDH->g == NULL) {
g = BN_new();
if (g == NULL) {
FATAL("Unable to create g");
Cleanup();
return false;
goto return_error;
}

//3. initialize p, g and key length
if (BN_hex2bn(&_pDH->p, P1024) == 0) {
if (BN_hex2bn(&p, P1024) == 0) {
FATAL("Unable to parse P1024");
Cleanup();
return false;
goto return_error;
}
if (BN_set_word(_pDH->g, 2) != 1) {
if (BN_set_word(g, 2) != 1) {
FATAL("Unable to set g");
Cleanup();
return false;
goto return_error;
}

//4. Set internal p and g
if (DH_set0_pqg(_pDH, p, NULL, g) != 1) {
FATAL("Unable to set internal p and g");
goto return_error;
}
p = g = NULL;

//4. Set the key length
_pDH->length = _bitsCount;
//5. Set the key length
if (DH_set_length(_pDH, _bitsCount) != 1) {
FATAL("Unable to set length");
goto return_error;
}

//5. Generate private and public key
//6. Generate private and public key
if (DH_generate_key(_pDH) != 1) {
FATAL("Unable to generate DH public/private keys");
Cleanup();
return false;
goto return_error;
}

return true;

return_error:
if (p != NULL) BN_free(p);
if (g != NULL) BN_free(g);
Cleanup();
return false;
}

bool DHWrapper::CopyPublicKey(uint8_t *pDst, int32_t dstLength) {
Expand All @@ -90,7 +102,9 @@ bool DHWrapper::CopyPublicKey(uint8_t *pDst, int32_t dstLength) {
return false;
}

return CopyKey(_pDH->pub_key, pDst, dstLength);
const BIGNUM *pub_key;
DH_get0_key(_pDH, &pub_key, NULL);
return CopyKey(pub_key, pDst, dstLength);
}

bool DHWrapper::CopyPrivateKey(uint8_t *pDst, int32_t dstLength) {
Expand All @@ -99,7 +113,9 @@ bool DHWrapper::CopyPrivateKey(uint8_t *pDst, int32_t dstLength) {
return false;
}

return CopyKey(_pDH->priv_key, pDst, dstLength);
const BIGNUM *priv_key;
DH_get0_key(_pDH, NULL, &priv_key);
return CopyKey(priv_key, pDst, dstLength);
}

bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length) {
Expand Down Expand Up @@ -153,14 +169,6 @@ bool DHWrapper::CopySharedKey(uint8_t *pDst, int32_t dstLength) {

void DHWrapper::Cleanup() {
if (_pDH != NULL) {
if (_pDH->p != NULL) {
BN_free(_pDH->p);
_pDH->p = NULL;
}
if (_pDH->g != NULL) {
BN_free(_pDH->g);
_pDH->g = NULL;
}
DH_free(_pDH);
_pDH = NULL;
}
Expand All @@ -177,7 +185,7 @@ void DHWrapper::Cleanup() {
}
}

bool DHWrapper::CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength) {
bool DHWrapper::CopyKey(const BIGNUM *pNum, uint8_t *pDst, int32_t dstLength) {
int32_t keySize = BN_num_bytes(pNum);
if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)) {
FATAL("CopyPublicKey failed due to either invalid DH state or invalid call");
Expand All @@ -197,20 +205,21 @@ void InitRC4Encryption(uint8_t *secretKey, uint8_t *pubKeyIn, uint8_t *pubKeyOut
uint8_t digest[SHA256_DIGEST_LENGTH];
unsigned int digestLen = 0;

HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(&ctx, pubKeyIn, 128);
HMAC_Final(&ctx, digest, &digestLen);
HMAC_CTX_cleanup(&ctx);
HMAC_CTX *ctx;
ctx = HMAC_CTX_new();
if (ctx == NULL)
return;
HMAC_Init_ex(ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(ctx, pubKeyIn, 128);
HMAC_Final(ctx, digest, &digestLen);
HMAC_CTX_reset(ctx);

RC4_set_key(rc4keyOut, 16, digest);

HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(&ctx, pubKeyOut, 128);
HMAC_Final(&ctx, digest, &digestLen);
HMAC_CTX_cleanup(&ctx);
HMAC_Init_ex(ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(ctx, pubKeyOut, 128);
HMAC_Final(ctx, digest, &digestLen);
HMAC_CTX_free(ctx);

RC4_set_key(rc4keyIn, 16, digest);
}
Expand All @@ -220,14 +229,17 @@ string md5(string source, bool textResult) {
}

string md5(uint8_t *pBuffer, uint32_t length, bool textResult) {
EVP_MD_CTX mdctx;
EVP_MD_CTX *mdctx;
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len;

EVP_DigestInit(&mdctx, EVP_md5());
EVP_DigestUpdate(&mdctx, pBuffer, length);
EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
EVP_MD_CTX_cleanup(&mdctx);
mdctx = EVP_MD_CTX_new();
if (mdctx == NULL)
return "";
EVP_DigestInit(mdctx, EVP_md5());
EVP_DigestUpdate(mdctx, pBuffer, length);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);

if (textResult) {
string result = "";
Expand All @@ -244,12 +256,12 @@ void HMACsha256(const void *pData, uint32_t dataLength,
const void *pKey, uint32_t keyLength, void *pResult) {
unsigned int digestLen;

HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, (unsigned char*) pKey, keyLength, EVP_sha256(), NULL);
HMAC_Update(&ctx, (unsigned char *) pData, dataLength);
HMAC_Final(&ctx, (unsigned char *) pResult, &digestLen);
HMAC_CTX_cleanup(&ctx);
HMAC_CTX *ctx;
ctx = HMAC_CTX_new();
HMAC_Init_ex(ctx, (unsigned char*) pKey, keyLength, EVP_sha256(), NULL);
HMAC_Update(ctx, (unsigned char *) pData, dataLength);
HMAC_Final(ctx, (unsigned char *) pResult, &digestLen);
HMAC_CTX_free(ctx);

o_assert(digestLen == 32);
}
Expand Down
90 changes: 90 additions & 0 deletions sources/common/src/utils/misc/libcrypto-compat.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include "utils/misc/libcrypto-compat.h"

#if OPENSSL_VERSION_NUMBER < 0x10100000L

#include <string.h>

static void *OPENSSL_zalloc(size_t num)
{
void *ret = OPENSSL_malloc(num);

if (ret != NULL)
memset(ret, 0, num);
return ret;
}

int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
{
/* If the fields p and g in d are NULL, the corresponding input
* parameters MUST be non-NULL. q may remain NULL.
*/
if ((dh->p == NULL && p == NULL)
|| (dh->g == NULL && g == NULL))
return 0;

if (p != NULL) {
BN_free(dh->p);
dh->p = p;
}
if (q != NULL) {
BN_free(dh->q);
dh->q = q;
}
if (g != NULL) {
BN_free(dh->g);
dh->g = g;
}

if (q != NULL) {
dh->length = BN_num_bits(q);
}

return 1;
}

void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
{
if (pub_key != NULL)
*pub_key = dh->pub_key;
if (priv_key != NULL)
*priv_key = dh->priv_key;
}

int DH_set_length(DH *dh, long length)
{
dh->length = length;
return 1;
}

EVP_MD_CTX *EVP_MD_CTX_new(void)
{
return (EVP_MD_CTX *)OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}

void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
{
EVP_MD_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}

HMAC_CTX *HMAC_CTX_new(void)
{
return (HMAC_CTX *)OPENSSL_zalloc(sizeof(HMAC_CTX));
}

void HMAC_CTX_free(HMAC_CTX *ctx)
{
HMAC_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}

#endif /* OPENSSL_VERSION_NUMBER */
Loading