C++ XML Parsing and Verifying

Discussion in 'OT Technology' started by antiyou, May 3, 2006.

  1. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    Does anyone know of an XML library with parser tools AND digital signature verification methods? Currently I am using expat for XML parsing and it looks as though I will need another tool to verify. If you know of an general c++ tool or lib for verifying let me know. I know that this is a simple task in C# but it is not an option for me at the moment.
     
  2. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    So in short I have an XML Packet and a parser now I need to verify the signature and x509 certificate
     
  3. samm

    samm Next in Line

    Joined:
    Dec 22, 2000
    Messages:
    2,630
    Likes Received:
    0
    Location:
    San Jose, CA
  4. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    I saw that but I had a hard time finding methods for verifying certs and sigs...

    Alright so I am looking at using OpenSSL libs to verify the signature and certificate. It's a huge lib the documentation isn't that great, and I'm not quite sure where to start. I'm doing something but I don't know what.

    Any suggestions would be appreciated
     
  5. samm

    samm Next in Line

    Joined:
    Dec 22, 2000
    Messages:
    2,630
    Likes Received:
    0
    Location:
    San Jose, CA
    I use OpenSSL to generate and verify signatures also, it's fairly straightforward. I've attached an example to create a signature. The code is a bit crufty, it comes from an old project at Pacific Northwest National Lab (PNNL, nice acronym...). The code to check a signature value with what is expected is slightly similar, let me know if you're interested and I can provide another example.

    Code:
    #include <openssl/sha.h>
    #include <string>
    #include <iostream>
    
    using std::string;
    using std::cout;
    using std::cin;
    
    bool createSignature(const std::string& text, std::string& result);
    std::string Base64encode(const std::string& raw);
    void encodeBlock(char base64[4], const std::string& raw, int offset);
    char getChar(short sixBit);
    
    int main() {
        cout << "enter text to create a signature for:\n";
        string text;
        cin >> text;
        string signature;
        createSignature(text, signature);
        cout << "signature value: " << Base64encode(signature) << "\n";
    }
    
    bool createSignature(const std::string& text, std::string& result) {
            result = "";
       if (!text.length()) {
            return false;
       }
    
       unsigned long dlen = SHA_DIGEST_LENGTH;
       unsigned char md[SHA_DIGEST_LENGTH];
       unsigned char*cp;
       cp = ::SHA1((const unsigned char*) text.data(), (unsigned long) text.length(), md);
       for (unsigned int i = 0; i != dlen; ++i) {
           result += md[i];
       }
       return true;
    }
    
    std::string Base64encode(const std::string& raw) {
        string encoded;
        for (unsigned int i = 0; i < raw.length(); i += 3) {
            char  base64[4];
            encodeBlock( base64, raw, i );
            encoded.append( base64, 4 );
        }
        return encoded;
    }
    
    void encodeBlock(char base64[4], const std::string& raw, int offset) {
       int block = 0;
            int slack = raw.length() - offset - 1;
       int end   = (slack >= 2) ? 2 : slack;
    
       for (int i = 0; i <= end; ++i) {
           unsigned char b      = (unsigned char) raw[offset + i];
           int           neuter = (b < 0) ? b + 256 : b;
           block += ( neuter << (8 * (2 - i) ) );
       }
       for (int i = 0; i != 4; ++i) {
           short sixbit = (block >> (6 * (3 - i) ) ) & 0x003f;
           base64[i] = getChar(sixbit);
       }
       if (slack < 1) base64[2] = '=';
       if (slack < 2) base64[3] = '=';
    }
    
    char getChar(short sixBit) {
       if (sixBit >= 0 && sixBit <= 25) {
           return (char)('A' + sixBit);
       }
       if (sixBit >= 26 && sixBit <= 51) {
           return (char)('a' + (sixBit - 26));
       }
       if (sixBit >= 52 && sixBit <= 61) {
           return (char)('0' + (sixBit - 52));
       }
       if (sixBit == 62) {
           return '+';
       }
       if (sixBit == 63) {
           return '/';
       }
       return '?';
    }
    
     
  6. D1G1T4L

    D1G1T4L Active Member

    Joined:
    May 4, 2001
    Messages:
    16,489
    Likes Received:
    0
    Location:
    Bay Area
    c++ should just die damn it =/
     
  7. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    don't be hatin :rolleyes:
     
  8. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    Nice thanks for the example.

    I am using expat an event driven XML parser, to parse my XML file. However my XML file is not in fact a file but a character string recieved as a packet from some arbitrary device.

    In my case I will have an event hadler for the signature tag. At which point I want to verify the signature now I don't know what parameters would be needed by openssl to verify the signature but within the signature I have X509Data which contains a certificate

    so does the sslverify signature handle the X509 cert naturally or will I need to do more parsing and create a specific structure to it or can I just get everything between <Signature...> </Signature> and pass that to be verified.

    Do you have an example of verifying a certificate that was not just created for instance one extracted from a file or string?

    I am not very familiar with the openssl libs but I see that there are verification methods and a lot of X509 specific code.
     
  9. samm

    samm Next in Line

    Joined:
    Dec 22, 2000
    Messages:
    2,630
    Likes Received:
    0
    Location:
    San Jose, CA
    same here. The code I posted above comes from our wire protocol library. We include the generated signature in each message sent, as a separate XML element. When the receiver parses the message, it will calculate the signature using the same method as the sender, then compare its value with the received one. If they differ, the message is rejected since it would imply tampering.

    I don't have any experience verifying an X509 certificate but I am sure it can be done. Have you searched the openssl mailing list archives? I am sure someone has tried to do this before.
     
  10. antiyou

    antiyou OT Supporter

    Joined:
    Jul 13, 2005
    Messages:
    25,295
    Likes Received:
    0
    Location:
    in ur base
    ^do you have an example of this using openssl...

    I am going to search the archives, but other than that due to poor documentation, the only other idea I have is to try and run the app through a debugger and open a signed XML file with X509 certificate then trace the call stack to view the openssl calls and function parameters.
     

Share This Page