openssl problem mit lesen eines privaten Schlüssels von einer pfx - key Datei



  • Hallo,

    vielleicht kann mir hier jemand helfen:
    Ich habe einen Speicherfehler in openssl. Wenn ich versuch private Schlüssel aus pfx - Dateien in kurzer Zeit hintereinander zu erhalten erhalten ich manchmal einen Fehler von openssl. Ich verwende openssl auf SuSE Linux 9, openssl.0.9.8d (aber auch in der aktuellen Version passiert dieser Fehler!). Auf Windows habe ich dasselbe getestet, dort gibt es jedoch keine Probleme.

    Um diesen Verhalten zu simulieren habe ich ein kurzen Programm geschrieben. Nur um es leichter zu machen, wird dieselbe pfx - Datei in einer for - Schleife gelesen und immer dieselben Aktionen ausgeführt. Der Fehler tritt aber auch auf, wenn man verschiedene pfx - Dateien verwendet.
    Wenn der Fehler auftritt sind es immer zwei mögliche. Jedoch kann es auch vorkommen, dass kein Fehler auftritt. Für mich klingt dies stark nach einem Speicher - Problem. Mein Frage ist nur, ist etwas an meinen Aufruf - Parametern falsch oder ist dies ein Speicherfehler in openssl?

    Hier kommt der Programm code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    #include <fstream>
    #include <string>

    #include <openssl/pkcs12.h>
    #include <openssl/x509.h>

    using namespace std;

    int main(int argc, char **argv ) {
    try {
    if (argc != 2) {
    printf("Usage: openssltest file1 !\n");
    return -1;
    }

    string filename = argv[1]; //pfx - file
    for (int i = 0; i < 50; ++i) {
    ifstream *fd_in = new ifstream(filename.c_str(), ios::in|ios::binary|ios::ate);
    if (!fd_in->is_open()) {
    printf("Error: Could not open file! \n");
    return -1;
    }

    int len = fd_in->tellg();
    char * text = new char [len + 1]; //input from file
    memset(text, 0x00, len + 1);

    fd_in->seekg(0, ios::beg);
    fd_in->read(text, len);
    fd_in->close();

    string password = "test"; //this is fixed

    PKCS12 *aCert;
    PKCS7 *p7;
    PKCS12_SAFEBAG *bag;
    STACK *asafes, *bags;

    int i, bagnid;
    unsigned int pwLen =3D password.size();
    unsigned char * tempPKCS12;
    X509 *x509;
    char *buf;
    char *pHelp;
    char *pHelp1;
    int nLength = 0;
    char *szOwner;

    SSLeay_add_all_algorithms();

    if (!(aCert = PKCS12_new())) {
    printf("Error: Could not init PKCS12! \n");
    return -1;
    }

    tempPKCS12 = (unsigned char *)malloc(len);
    if (tempPKCS12 == NULL) {
    printf("Error: No Memory!\n");
    return -1;
    }

    memset(tempPKCS12, 0x00, len);
    memcpy(tempPKCS12, text, len);
    //file content in unsigned char array

    if(!(aCert = d2i_PKCS12(&aCert, (const unsigned char**)&tempPKCS12, len))) {
    printf("Error: Error in d2i_PKCS12! \n");
    return -1;
    }

    if (!PKCS12_verify_mac (aCert, password.c_str(),
    -1)) {
    printf("Error: in PKCS12_verify_mac! \n");
    retun -1;
    }

    if (!( asafes = M_PKCS12_unpack_authsafes (aCert)=
    )) {
    printf("Error:in M_PKCS12_unpack_authsafes!\n");
    return -1;
    }

    for (i = 0; i < sk_num (asafes); i++) {
    p7 = (PKCS7 😉 sk_value (asafes, i);
    bagnid = OBJ_obj2nid (p7->type);
    if (bagnid == NID_pkcs7_data) {
    bags = M_PKCS12_unpack_p7data(p7);
    }
    else if (bagnid == NID_pkcs7_encrypted) {
    bags = M_PKCS12_unpack_p7encdata(p7, password.c_str(), -1);
    }
    else {
    printf("bagnid: %d\n", bagnid);
    }

    if (!bags) {
    printf("Error: in bags!\n");
    return -1;
    }
    }
    }
    } catch(...) {
    printf("Exception in new!\n");
    return -1;
    }

    return 0;
    }

    Die zwei möglichen Fehler sind:
    1. Fehler in PKCS12_verify_mac --> Error: in function PKCS12_verify_mac
    2. Fehler in bags! --> Error: in function M_PKCS12_unpack_p7encdata

    Um es noch einmal klar zu machen. Dies ist immer dieselbe Datei. Manchmal funktioniert es mit 50 Aufrufen und manchmal tritt einer der beiden Fehler auf.
    Wenn der Fehler auftritt dann immer an denselben Positionen. Das ist mir zu eindeutig um ein Zufall zu sein. Wo und was kann die Ursache sein?

    Für jede Hilfe wäre ich sehr dankbar.

    Gruß

    Pferdle



  • Also dazu fällt mir vieles auf, ohne auf das eigentliche Problem zu betrachten. Zunächst solltest Du unbedingt Code-tags verwenden, sonst blickt keiner durch und keiner hat Lust Dir zu helfen.

    Dann hast Du so sinnfreie Codesequenzen wie:

    memset(tempPKCS12, 0x00, len);
    memcpy(tempPKCS12, text, len);
    

    Warum setzt zu den Speicher erst auf 0 und dann auf einen anderen Wert?

    fd_in->read(text, len);
    

    Unvollständige Fehlerprüfung. Hat das überhaupt geklappt? Wenn das nicht klappt, dann wird dein Openssl auch nicht funktionieren.

    Wo löschst Du das fd_in? Warum legst Du das Objekt nicht einfach auf den Stack anstatt mit Zeigern zu hantieren?

    } catch(...) {
      printf("Exception in new!\n");
      return -1;
    }
    

    Alles was schief geht, ist new??? Na ja - in deinem Fall wird das so sein, aber so etwas tut in der Seele weh.

    Das sind nur so Sachen, die mir beim ersten überfliegen aufgefallen sind. Da sind sicherlich noch andere Dinge, die nicht in Ordnung sind. Bereinige erst mal das Programm, dann bekommst Du vielleicht auch Hilfe, wenn Du sie dann noch brauchst.
    😞 👎

    Tntnet



  • Also dies ist nur ein Beispiel - Programm und darin sind sicherlich einige kleine Unaufmerksamkeiten enthalten. Aber es funktioniert natürlich und an diesem Punkten tritt auch kein Fehler auf. Die Datei - Information wird im original Programm nicht über open und read realisiert und ich habe den gesamten Code auch nicht geschrieben.

    Aber als Anmerkung:
    C/C++ Code:
    memset(tempPKCS12, 0x00, len);
    memcpy(tempPKCS12, text, len);

    Warum setzt zu den Speicher erst auf 0 und dann auf einen anderen Wert?

    Antwort: Ist hier wohl wirklich überflüssig!

    C/C++ Code:
    fd_in->read(text, len);

    Unvollständige Fehlerprüfung. Hat das überhaupt geklappt? Wenn das nicht klappt, dann wird dein Openssl auch nicht funktionieren. --> Ach nein, wirklich.

    Anwort: Kann man natürlich noch Abfragen. Aber wie schon gesagt es funktioniert.

    } catch(...) {
    printf("Exception in new!\n");
    return -1;
    }

    Alles was schief geht, ist new???
    Antwort: Da habe ich mich wohl verschrieben. Aber das ist doch nur Formalismus hat mit meinem Problem relative wenig zu tun!

    #include <openssl/pkcs12.h> 
    #include <openssl/x509.h> 
    
    using namespace std; 
    
    int main(int argc, char **argv ) { 
    try { 
    if (argc != 2) { 
    printf("Usage: openssltest file1 !\n"); 
    return -1; 
    } 
    
    string filename = argv[1]; //pfx - file 
    for (int i = 0; i < 50; ++i) { 
    ifstream *fd_in = new ifstream(filename.c_str(), ios::in|ios::binary|ios::ate); 
    if (!fd_in->is_open()) { 
    printf("Error: Could not open file! \n"); 
    return -1; 
    } 
    
    int len = fd_in->tellg(); 
    char * text = new char [len + 1]; //input from file 
    
    fd_in->seekg(0, ios::beg); 
    fd_in->read(text, len); 
    fd_in->close(); 
    
    string password = "test"; //this is fixed 
    
    PKCS12 *aCert; 
    PKCS7 *p7; 
    PKCS12_SAFEBAG *bag; 
    STACK *asafes, *bags; 
    
    int i, bagnid; 
    unsigned int pwLen =3D password.size(); 
    unsigned char * tempPKCS12; 
    X509 *x509; 
    char *buf; 
    char *pHelp; 
    char *pHelp1; 
    int nLength = 0; 
    char *szOwner; 
    
    SSLeay_add_all_algorithms(); 
    
    if (!(aCert = PKCS12_new())) { 
    printf("Error: Could not init PKCS12! \n"); 
    return -1; 
    } 
    
    tempPKCS12 = (unsigned char *)malloc(len); 
    if (tempPKCS12 == NULL) { 
    printf("Error: No Memory!\n"); 
    return -1; 
    } 
    
    memcpy(tempPKCS12, text, len); //file content in unsigned char array 
    
    if(!(aCert = d2i_PKCS12(&aCert, (const unsigned char**)&tempPKCS12, len))) { 
    printf("Error: Error in d2i_PKCS12! \n"); 
    return -1; 
    } 
    
    if (!PKCS12_verify_mac (aCert, password.c_str(), 
    -1)) { 
    printf("Error: in PKCS12_verify_mac! \n"); 
    retun -1; 
    } 
    
    if (!( asafes = M_PKCS12_unpack_authsafes (aCert)= 
    )) { 
    printf("Error:in M_PKCS12_unpack_authsafes!\n"); 
    return -1; 
    } 
    
    for (i = 0; i < sk_num (asafes); i++) { 
    p7 = (PKCS7 *) sk_value (asafes, i); 
    bagnid = OBJ_obj2nid (p7->type); 
    if (bagnid == NID_pkcs7_data) { 
    bags = M_PKCS12_unpack_p7data(p7); 
    } 
    else if (bagnid == NID_pkcs7_encrypted) { 
    bags = M_PKCS12_unpack_p7encdata(p7, password.c_str(), -1); 
    } 
    else { 
    printf("bagnid: %d\n", bagnid); 
    } 
    
    if (!bags) { 
    printf("Error: in bags!\n"); 
    return -1; 
    } 
    } 
    } 
    } catch(...) { 
    printf("Unknown Exception!\n"); 
    return -1; 
    } 
    
    return 0; 
    }
    

    Gruß

    Pferdele


Anmelden zum Antworten