IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Erreur de segmentation avec RSA_verify


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Points : 48
    Points
    48
    Par défaut Erreur de segmentation avec RSA_verify
    Bonjour à tous.

    Je cherche à signer un document. Pour commencer, je signe une chaine, en calculant son digest (SHA1) puis en le signant en RSA.

    Quand je le signe, je n'ai aucun problème. A la vérification cependant, j'ai une erreur de segmentation. D'après gdb, la raison est :
    Program received signal SIGSEGV, Segmentation fault.
    0xb7e1ccac in BN_num_bits () from /usr/lib/i686/cmov/libcrypto.so.0.9.8

    J'ai réglé mon compilateur selon les conseils de Emmanuel Delahaye (http://emmanuel-delahaye.developpez....tm#cfg_compilo) et compile sans erreur ni warning.

    J'ai du mal à déceler l'origine de mon problème, même avec l'aide de ddd ou gdb. gdb indique que l'erreur viendrait de BN_num_bits(), donc a priori de la longueur de la signature qui ne collerait pas avec le reste. Malheureusement j'ai du mal à comprendre, tout me porte à croire que le problème vient de l'utilisation d'openssl, mais d'après la page de man :
    int RSA_verify(int type, unsigned char *m, unsigned int m_len,
    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
    Ainsi je respecte les types et je vérifie que les paramètres que je passe à la fonction soient cohérents avec ce que cette dernière attend.

    Donc, si quelqu'un pouvait m'aider, ce serait très gentil.

    Je joins un code complet compilable de ce que j'essaye de faire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <openssl/sha.h>
    #include <openssl/rsa.h>
    #include <openssl/evp.h>
     
    int main(void)
    {
      unsigned int k = 0;
     
      /* SHA1 Initialization steps */
     
      const unsigned char *d = (unsigned char*)"Hi dude, what about a test?";
      unsigned long n = (unsigned long)strlen((char*)d);
      unsigned char *md = malloc(SHA_DIGEST_LENGTH);
     
      /* RSA Initialization steps */
     
      RSA *var_RSA = RSA_new();
      int modulus_size = 1024;
      long public_exponent = 65537;
     
      int V_sign = 0;
      int V_verif = 0;
     
      unsigned char *sigret = malloc(sizeof(RSA_size(var_RSA)));
     
      unsigned int siglen = 0;
     
      /* Generation of the digest */
      SHA1(d,n,md);
      fprintf(stdin,"%s\n\n",md);
     
      /* RSA part */
      var_RSA = RSA_generate_key(modulus_size,public_exponent,NULL,NULL);
     
      if(var_RSA==NULL)
        printf("Error during the generation of the keys\n\n");
      else
        printf("Everything went fine during the generation of the keys\n\n");
     
      V_sign = RSA_sign(NID_sha1,md,strlen((char*)md),sigret,&siglen,var_RSA);
     
      if(V_sign==0)
        printf("Problem while signing the digest\n\n");
      else
        printf("Everything went fine while signing the digest\n\n");  
     
      for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
     
      printf("\n\n");
     
      printf("---test---\n");
     
      /* Print all the variables to be given to RSA_verify to check their accuracy */
      printf("NID_sha1: %d\n",NID_sha1);
      printf("strlen(md): %d\n",strlen((char*)md));
      for(k=0;k<strlen((char*)md);k++)
    	printf("%02X",md[k]);
      printf("\n");
      printf("siglen: %d\n",siglen);
        for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
      printf("\n");
     
      V_verif = RSA_verify(NID_sha1,md,strlen((char*)md),sigret,siglen,var_RSA);
     
      printf("---test---\n");
     
      if(V_verif==0)
        printf("Problem while verifying the digest\n\n");
      else
        printf("Everything went fine while verifying the digest\n\n");  
     
      RSA_free(var_RSA);
     
      return 0;
    }

  2. #2
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Hello,

    Citation Envoyé par LorDjidane

    J'ai réglé mon compilateur selon les conseils de Emmanuel Delahaye (http://emmanuel-delahaye.developpez....tm#cfg_compilo) et compile sans erreur ni warning.

    J'ai du mal à déceler l'origine de mon problème, même avec l'aide de ddd ou gdb. gdb indique que l'erreur viendrait de BN_num_bits(), donc a priori de la longueur de la signature qui ne collerait pas avec le reste. Malheureusement j'ai du mal à comprendre, tout me porte à croire que le problème vient de l'utilisation d'openssl, mais d'après la page de man :
    int RSA_verify(int type, unsigned char *m, unsigned int m_len,
    unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
    Ainsi je respecte les types et je vérifie que les paramètres que je passe à la fonction soient cohérents avec ce que cette dernière attend.
    Un programmeur avisé peut parfois être plus utile qu'un compilateur bien réglé, des debuggers et autres

    Dans ton code tu as tout d'abord ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RSA *var_RSA = RSA_new();
    qui alloue et renvoie une variable var_RSA de type RSA *

    Puis plus loin, tu as ceci qui alloue de la mémoire pour la variable sigret, en utilisant un nombre de bytes provenant du var_RSA mentionné ci-dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unsigned char *sigret = malloc(sizeof(RSA_size(var_RSA)));
    Les soucis commencent ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var_RSA = RSA_generate_key(modulus_size,public_exponent,NULL,NULL);
    Paf, on écrase notre var_RSA précédent (entre parenthèses, fuite mémoire).

    Et ici, que fait-on, hé bien on utilise notre nouveau var_RSA qui a écrasé l'ancien, avec le sigret qui lui a utilisé l'ancien var_RSA pour son allocation. Donc il est plus que probable que var_RSA et sigret ne soient pas cohérents et de tailles différentes en nombre de bytes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    V_sign = RSA_sign(NID_sha1,md,strlen((char*)md),sigret,&siglen,var_RSA)
    Ce que je propose, c'est d'initialiser à NULL les pointeurs et de faire les allocations par la suite, en prenant soin d'allouer de la mémoire pour sigret APRES la génération de la clé. Le tiercé dans l'order est donc le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /* ... */
    RSA *var_RSA = NULL;
    unsigned char *sigret = NULL;
     
    /* ... */
     
    /* génération clé */
    var_RSA = RSA_generate_key(modulus_size,public_exponent,NULL,NULL);
     
    /* ... */
     
    /* allocation sigret */
    sigret = malloc(sizeof(RSA_size(var_RSA)));
     
    /* ... */
    A+

  3. #3
    Membre du Club
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Points : 48
    Points
    48
    Par défaut
    Salut

    Merci pour les indications. Elles paraissent logiques à première vue, mais il y a quelque chose que je ne comprends pas : une variable de type RSA occupera toujours la même taille en mémoire, de même pour un int, un char, etc.
    De fait, je ne comprends pas trop d'où vient le problème.

    Certes, mon code était plutôt laid, et ta méthode a le mérite d'être plus sérieuse. Mais sur un plan fonctionnel, je ne vois pas la différence.

    Pour preuve, en suivant tes conseils, j'obtiens encore une segfault, et cette fois dès le RSA_sign.

    J'ai initialisé mes pointeurs à NULL comme tu le suggérais, puis ai rajouté ceci après la génération des clefs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      sigret = malloc(sizeof(RSA_size(var_RSA)));
     
      if(sigret==NULL)
        printf("Error during the allocation of sigret\n\n");
      else
        printf("Everything went fine during the allocation of sigret\n\n");
    L'allocation a bien lieu (j'ai la phrase "Everything (...)"), et ensuite segmentation fault. J'avoue que je ne comprends plus grand chose, j'ai peut-être fait une autre erreur bête en suivant tes indications, mais... je sèche.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <openssl/sha.h>
    #include <openssl/rsa.h>
    #include <openssl/evp.h>
     
    int main(void)
    {
      unsigned int k = 0;
     
      /* SHA1 Initialization steps */
     
      const unsigned char *d = (unsigned char*)"Hi dude, what about a test?";
      unsigned long n = (unsigned long)strlen((char*)d);
      unsigned char *md = malloc(SHA_DIGEST_LENGTH);
     
      /* RSA Initialization steps */
     
      RSA *var_RSA = NULL;
      int modulus_size = 1024;
      long public_exponent = 65537;
     
      int V_sign = 0;
      int V_verif = 0;
     
      unsigned char *sigret = NULL;
     
      unsigned int siglen = 0;
     
      /* Generation of the digest */
      SHA1(d,n,md);
      fprintf(stdin,"%s\n\n",md);
     
      /* RSA part */
      var_RSA = RSA_new();
      var_RSA = RSA_generate_key(modulus_size,public_exponent,NULL,NULL);
     
      if(var_RSA==NULL)
        printf("Error during the generation of the keys\n\n");
      else
        printf("Everything went fine during the generation of the keys\n\n");
     
      sigret = malloc(sizeof(RSA_size(var_RSA)));
     
      if(sigret==NULL)
        printf("Error during the allocation of sigret\n\n");
      else
        printf("Everything went fine during the allocation of sigret\n\n");
     
      V_sign = RSA_sign(NID_sha1,md,strlen((char*)md),sigret,&siglen,var_RSA);
     
      if(V_sign==0)
        printf("Problem while signing the digest\n\n");
      else
        printf("Everything went fine while signing the digest\n\n");  
     
      for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
     
      printf("\n\n");
     
      printf("---test---\n");
     
      /* Print all the variables to be given to RSA_verify to check their accuracy */
      printf("NID_sha1: %d\n",NID_sha1);
      printf("strlen(md): %d\n",strlen((char*)md));
      for(k=0;k<strlen((char*)md);k++)
    	printf("%02X",md[k]);
      printf("\n");
      printf("siglen: %d\n",siglen);
        for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
      printf("\n");
     
      V_verif = RSA_verify(NID_sha1,md,strlen((char*)md),sigret,siglen,var_RSA);
     
      printf("---test---\n");
     
      if(V_verif==0)
        printf("Problem while verifying the digest\n\n");
      else
        printf("Everything went fine while verifying the digest\n\n");  
     
      RSA_free(var_RSA);
     
      return 0;
    }

  4. #4
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Hello,

    Citation Envoyé par LorDjidane
    Salut

    Merci pour les indications. Elles paraissent logiques à première vue, mais il y a quelque chose que je ne comprends pas : une variable de type RSA occupera toujours la même taille en mémoire, de même pour un int, un char, etc.
    De fait, je ne comprends pas trop d'où vient le problème.

    Certes, mon code était plutôt laid, et ta méthode a le mérite d'être plus sérieuse. Mais sur un plan fonctionnel, je ne vois pas la différence.

    Pour preuve, en suivant tes conseils, j'obtiens encore une segfault, et cette fois dès le RSA_sign.

    J'ai initialisé mes pointeurs à NULL comme tu le suggérais, puis ai rajouté ceci après la génération des clefs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
      sigret = malloc(sizeof(RSA_size(var_RSA)));
     
      if(sigret==NULL)
        printf("Error during the allocation of sigret\n\n");
      else
        printf("Everything went fine during the allocation of sigret\n\n");
    L'allocation a bien lieu (j'ai la phrase "Everything (...)"), et ensuite segmentation fault. J'avoue que je ne comprends plus grand chose, j'ai peut-être fait une autre erreur bête en suivant tes indications, mais... je sèche.
    Je te rassure, ton code n'est pas trop mal dans l'ensemble. Il s'agit d'un problème de compréhension de ce qu'est un message digest, qui est une juste une somme de contrôle de longueur fixe, tel un CRC. Cf MD5 par exemple. J'ai donc modifié et commenté ton code en fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <openssl/sha.h>
    #include <openssl/rsa.h>
    #include <openssl/evp.h>
     
    int main(void)
    {
      unsigned int k = 0;
     
      /* SHA1 Initialization steps */
     
      const unsigned char *d = (unsigned char*)"Hi dude, what about a test?";
     
      /* Foobar1329 */
      /* C'est la longueur en bytes qui est demandé, pas la longueur de la chaine */
      /* C'est important pour SHA1() plus bas */
      /* unsigned long n = (unsigned long)strlen((char*)d); */
      unsigned long n = (unsigned long)strlen((char*)d) + 1;
     
      unsigned char *md = malloc(SHA_DIGEST_LENGTH);
     
      /* RSA Initialization steps */
     
      RSA *var_RSA = NULL;
      int modulus_size = 1024;
      long public_exponent = 65537;
     
      int V_sign = 0;
      int V_verif = 0;
     
      unsigned char *sigret = NULL;
     
      unsigned int siglen = 0;
     
      /* Generation of the digest */
      SHA1(d,n,md);
     
      /* Foobar1329 */
      /* stdout plutôt ;)  et puis non, md n'est pas une chaine littérale */
      /* fprintf(stdin,"%s\n\n",md); */
     
      /* RSA part */
     
      /* Foobar1329 */
      /* Le RSA_new est inutile, RSA_generate_key renvoie un ptr alloué */
      /* var_RSA = RSA_new(); */
      var_RSA = RSA_generate_key(modulus_size,public_exponent,NULL,NULL);
     
      if(var_RSA==NULL)
        printf("Error during the generation of the keys\n\n");
      else
        printf("Everything went fine during the generation of the keys\n\n");
     
      sigret = malloc(sizeof(RSA_size(var_RSA)));
     
      if(sigret==NULL)
        printf("Error during the allocation of sigret\n\n");
      else
        printf("Everything went fine during the allocation of sigret\n\n");
     
     
      /* Foobar1329 */
      /* md est un message digest, de SHA_DIGEST_LENGTH bytes, et non une chaine 
         caractères, le pb vient de là ;) */
      /*
       V_sign = RSA_sign(NID_sha1,md,strlen((char*)md),sigret,&siglen,var_RSA);
       */
     
      V_sign = RSA_sign(NID_sha1,md,SHA_DIGEST_LENGTH,sigret,&siglen,var_RSA);
     
     
      if(V_sign==0)
        printf("Problem while signing the digest\n\n");
      else
        printf("Everything went fine while signing the digest\n\n");  
     
      for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
     
      printf("\n\n");
     
      printf("---test---\n");
     
      /* Print all the variables to be given to RSA_verify to check their accuracy */
      printf("NID_sha1: %d\n",NID_sha1);
     
      /* Foobar1329 */
      /* Il faut remplacer les strlen par SHA_DIGEST_LENGTH ici */
      printf("strlen(md): %d\n",strlen((char*)md));
      for(k=0;k<strlen((char*)md);k++)
    	printf("%02X",md[k]);
      printf("\n");
      printf("siglen: %d\n",siglen);
        for(k=0;k<siglen;k++)
    	printf("%02X",sigret[k]);
      printf("\n");
     
      /* Foobar1329 */
      /* Meme pb qu'avec RSA_sign */
      /* 
      V_verif = RSA_verify(NID_sha1,md,strlen((char*)md),sigret,siglen,var_RSA);
      */
      V_verif = RSA_verify(NID_sha1,md,SHA_DIGEST_LENGTH,sigret,siglen,var_RSA);
     
      printf("---test---\n");
     
      if(V_verif==0)
        printf("Problem while verifying the digest\n\n");
      else
        printf("Everything went fine while verifying the digest\n\n");  
     
      RSA_free(var_RSA);
     
      return 0;
    }

    A+

  5. #5
    Membre du Club
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Points : 48
    Points
    48
    Par défaut
    Salut

    Merci pour ton aide déjà.
    Cependant... ça marche pas.

    J'ai aporté tes modifications, rien n'y fit. Je décidai donc de copier ton code, le compiler (ok pas de souci) puis l'exécuter, et encore une fois, une erreur au niveau de RSA_sign fait son apparition.

    J'ai lancé gdb, puis ai fait un run > where pour avoir un peu la tête de ma stack.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    (gdb) where
    #0  0xb7d14dec in free () from /lib/tls/i686/cmov/libc.so.6
    #1  0xb7e28f5a in CRYPTO_free () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
    #2  0xb7e561c1 in BN_CTX_free () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
    #3  0xb7e73c7d in ?? () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
    #4  0x0804a1a8 in ?? ()
    #5  0x0804a218 in ?? ()
    #6  0x0804a2e8 in ?? ()
    #7  0x0804a1a8 in ?? ()
    #8  0xb7de74c0 in ?? () from /lib/tls/i686/cmov/libc.so.6
    #9  0xbfba8624 in ?? ()
    #10 0x00000021 in ?? ()
    #11 0xb7f1c8f8 in ?? () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
    #12 0xb7f0a388 in ?? () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
    ...
    Alors au début, je pensais que c'était dû à la non initialisation du pointeur var_RSA, mais en fait la fonction pour générer des clefs s'en tire sans problèmes, donc ce n'est pas ça. Tout vient peut-être du malloc() sur la taille SHA_DIGEST_LENGTH mais bon, je vois pas.

  6. #6
    Membre du Club
    Inscrit en
    Août 2005
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 49
    Points : 48
    Points
    48
    Par défaut
    Salut à tous.

    Mon binôme m'a éclairé, erreur horrible que j'aurais dû voir bien avant (comme toutes les erreurs n'est-ce pas ? ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sigret = malloc(sizeof(RSA_size(var_RSA)));
    Bien entendu, le sizeof est inutile, et ce n'était qu'un mauvais réflexe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sigret = malloc(RSA_size(var_RSA));
    Cette simple correction fait fonctionner le code.

    Sur ce, résolu, merci encore pour ton aide Foobar1329

  7. #7
    Membre averti
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Points : 387
    Points
    387
    Par défaut
    Hello,

    Citation Envoyé par LorDjidane
    Salut à tous.

    Mon binôme m'a éclairé, erreur horrible que j'aurais dû voir bien avant (comme toutes les erreurs n'est-ce pas ? ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sigret = malloc(sizeof(RSA_size(var_RSA)));
    Bien entendu, le sizeof est inutile, et ce n'était qu'un mauvais réflexe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      sigret = malloc(RSA_size(var_RSA));
    Cette simple correction fait fonctionner le code.

    Sur ce, résolu, merci encore pour ton aide Foobar1329
    Bah, bravo à ton binôme, tu peux lui payer un coup, c'est une erreur sur laquelle on peut rester longtemps. Ca plantait sur le free() chez moi et je me demandais le pourquoi du comment avec le programme ci-dessous et la boulette, car le pointeur n'était pas modifié. J'avoue que ça ne m'avait pas sauté aux yeux .

    Par contre, autant on peut dire ici à propos de sizeof() qu'il s'agit d'un mauvais réflexe, l'utilisation de sizeof() reste un excellent automatisme à avoir. Depuis le début nous n'avons en fait rencontré que des petits soucis liés globalement à l'appréhension des fonctions de la bibliothèque OpenSSL.

    Le code détaillé qui fonctionne et qui utilise le PRNG préconisé avan génération de la clé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    #include <openssl/sha.h>
    #include <openssl/rsa.h>
    #include <openssl/evp.h>
    #include <openssl/rand.h>
     
    #include <unistd.h>
     
    int main (void)
    {
     
      /* "Message digest" : somme de contrôle SHA1 */
      unsigned char * md = NULL;
     
      /* Objet RSA */
      RSA * var_RSA = NULL;
     
      /* Longueur de la clé */
      int key_size = 1024;
     
      /* Exposant public */
      long public_exponent = 65537;
     
      int V_sign = 0;
      int V_verif = 0;
      unsigned char * sigret = NULL;
      unsigned int siglen = 0u; 
      unsigned int k = 0u; 
      int randVal; 
      unsigned char randValBytes[sizeof(int)];  
     
      /* Message dont la somme de contrôle SHA1 est à signer */
      const unsigned char * d = (unsigned char *)"Hi dude, what about a test?";
     
      /* Taille du message en bytes (!= longueur de la chaîne du message) */
      unsigned long n = strlen((char *)d) + 1;
     
      /* Allocation des SHA_DIGEST_LENGTH (20) bytes nécessaires pour stocker la somme de contrôle SHA1*/
      md = malloc(SHA_DIGEST_LENGTH);
      if (!md) {
        fprintf(stderr, "md: allocation failure, exiting...\n");
        exit(EXIT_FAILURE);
      }
     
      /* Initialisation PRNG*/
      srand(time(NULL));
      randVal = rand();
      memcpy(randValBytes, &randVal, sizeof(int));
      RAND_seed(randValBytes, sizeof(int));
     
      /* Génération de la somme de controle SHA1 */ 
      SHA1(d, n, md);
     
      /* Génération de la clé */
      var_RSA = RSA_generate_key (key_size, public_exponent, NULL, NULL);
      if (var_RSA == NULL) {
        fprintf(stderr, "Error during the generation of the keys, exiting...\n");
        free(md);
        exit(EXIT_FAILURE);
      }
     
      /* Allocation d'espace pour stocker la somme de contrôle SHA1 signée */
      /* ! AIE !sigret = malloc(sizeof(RSA_size(var_RSA))); */
      sigret = malloc(RSA_size(var_RSA));
      if (sigret == NULL) {
        fprintf(stderr, "Error during the allocation of sigret, exiting...\n");
        free(md);
        RSA_free(var_RSA);
        exit(EXIT_FAILURE);
      }
     
      /* Affichage infos somme de contrôle SHA1 */
      puts("\n>>\n-- Printing the digest ---------");
      printf("-- Length: %9d   ---------\n", SHA_DIGEST_LENGTH);
      for (k = 0; k <SHA_DIGEST_LENGTH; k++) {
        printf ("%02X", md[k]);
      }
      puts("\n--------------------------------\n");
     
      /* Signature de la somme de contrôle SHA1 */ 
      V_sign = RSA_sign(NID_sha1, md, SHA_DIGEST_LENGTH, sigret, &siglen, var_RSA);
      if (V_sign == 0) {
        fprintf(stderr, "Problem while signing the digest\n");
      }
      else {
        printf ("Everything went fine while signing the digest\n");
      }
     
      /* Affichage infos somme de contrôle SHA1 signée */
      puts("\n>>\n-- Printing the signed digest --");
      printf("-- Length: %9d   ---------\n", siglen);
      for (k = 0; k < siglen; k++) {
        printf ("%02X", sigret[k]);
      }
      puts("\n--------------------------------\n");
     
      /* Verification de la signature */
      V_verif = RSA_verify (NID_sha1, md, SHA_DIGEST_LENGTH, sigret, siglen, var_RSA);
      if (V_verif == 0) {
        fprintf (stderr, "Problem while veryfying the digest\n");
      }
      else {
        printf ("Everything went fine while verifying the digest\n\n");
      }
     
      fflush(stdout);
     
      free(md);
      free(sigret);
      RSA_free(var_RSA);
     
      return 0;
     
    }
    Moralité, toujours regarder attentivement ce qu'on donne à manger à malloc (calloc/realloc), sinon c'est le free qui vomit. C'est valable pour tout le monde

    A+

  8. #8
    Membre du Club
    Inscrit en
    Mai 2005
    Messages
    88
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 88
    Points : 59
    Points
    59
    Par défaut
    euh je voudrais juste ajouter merci

    j'ai eu le même problème! lol (une histoire de malloc... alalaaaaaaaa)

    bon courage à vous,

    NiniE

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. erreur de segmentation avec pyopengl et glut
    Par bourriquet_42 dans le forum OpenGL
    Réponses: 3
    Dernier message: 01/03/2009, 13h35
  2. Erreur de segmentation avec delete
    Par ValyGator dans le forum C++
    Réponses: 13
    Dernier message: 11/02/2009, 20h44
  3. Erreur de segmentation avec fclose
    Par sylvanus35 dans le forum Débuter
    Réponses: 7
    Dernier message: 09/08/2008, 05h33
  4. Erreur de segmentation avec libxml2
    Par DevMg dans le forum XML
    Réponses: 0
    Dernier message: 18/02/2008, 14h44
  5. Erreur de segmentation avec un main vide
    Par matique dans le forum Réseau
    Réponses: 10
    Dernier message: 22/04/2007, 07h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo