2017-10-18 10 views
1

J'essaie de créer un fichier * .so pour une utilisation ultérieure en Python en utilisant SWIG. En particulier j'utilise des librairies de openssl (telles que opensll/bn.h). Mais de toute façon, il renvoie erreur ImportError: [...]/auxchash.so: undefined symbol: BN_bn2hex.swig C++ en python avec openssl/bn.h

J'ai la file.cpp, auxchash.cpp:

#include auxchash.h 

int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk){ 
    BN_CTX *ctx = BN_CTX_new(); 
    BIGNUM *bn_p = BN_new(); 
    BIGNUM *bn_q = BN_new(); 
    BIGNUM *bn_g = BN_new(); 
    BIGNUM *bn_hk = BN_new(); 
    BIGNUM *bn_tk = BN_new(); 
    BIGNUM *bn_two = BN_new(); 

    BN_CTX_init(ctx); 

    BN_dec2bn(&bn_two, "2"); //initialize a BIGNUM with value 2 

    //on non-unix platform needs to initialize the PRNG with randomness 
    //or BN_generate_prime_ex may fail 

    //computing the safe prime p and q = (p-1)/2 
    BN_generate_prime_ex(bn_p, bits, 1, NULL, NULL, NULL); 
    BN_sub(bn_q, bn_p, BN_value_one()); 
    BN_div(bn_q, NULL, bn_q, bn_two, ctx); 

    //finding the generator g (for the group QR_p) 
    BN_rand_range(bn_g, bn_p); 
    BN_mod_exp(bn_g, bn_g, bn_two, bn_p, ctx); 

    //choosing the keys hk and tk 
    BN_rand_range(bn_tk, bn_q); 
    BN_mod_exp(bn_hk, bn_g, bn_tk, bn_p, ctx); 

    //converting from BIGNUM to hex 
    p = BN_bn2hex(bn_p); 
    q = BN_bn2hex(bn_q); 
    g = BN_bn2hex(bn_g); 
    hk = BN_bn2hex(bn_hk); 
    tk = BN_bn2hex(bn_tk); 

    //freeing the resources 
    BN_CTX_free(ctx); 
    BN_free(bn_two); 
    BN_free(bn_p); 
    BN_free(bn_q); 
    BN_free(bn_g); 
    BN_free(bn_hk); 
    BN_clear_free(bn_tk); 

    return 0; 
} 

Le fichier.h, auxchash.h:

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include<openssl/bn.h> 
#include<openssl/sha.h> 
#include<openssl/rand.h> 

int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk); 

Le file.i pour le module rasade, auxchash.i :

%module auxchash 
%{ 
#define SWIG_FILE_WITH_INIT 
#include "auxchash.h" 
#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 
#include<openssl/bn.h> 
#include<openssl/sha.h> 
#include<openssl/rand.h> 
%} 

%include "typemaps.i" 
%include "cstring.i" 

%cstring_bounded_output(char *p, 1024); 
%cstring_bounded_output(char *q, 1024); 
%cstring_bounded_output(char *g, 1024); 
%cstring_bounded_output(char *hk, 1024); 
%cstring_bounded_output(char *tk, 1024); 
extern int keygen(int bits, char *p, char *q, char *g, char *hk, char *tk); 

Enfin un setup.py de fichier pour créer tous les fichiers nécessaires rasade, setup.py:

from distutils.core import setup, Extension 


auxchash_module = Extension('_auxchash', 
         sources=['auxchash_wrap.cxx', 'auxchash.cpp'], 
         ) 

setup (name = 'auxchash', 
    version = '0.1', 
    author  = "SWIG Docs", 
    description = """Simple swig example from docs""", 
    ext_modules = [auxchash_module], 
    py_modules = ["auxchash"], 
    ) 

Et tous sont compilés avec les commandes du terminal:

swig -c++ -python auxchash.i 
python setup.py build_ext --inplace 

Jusqu'à présent, si bon, il compilez sans erreurs. Mais quand je lance un python principal:

import auxchash 
res,p,q,g,hk,tk = auxchash.keygen(10) 

Il donne mon l'erreur suivante:

File: "[...]/auxchash.py" import auxchash 
File: "[...]/auxchash.py" auxchash=swig_import_helper() 
File: "[...]/auxchash.py" return=importlib.import_module('_auxchash') 
File: "[...]/__init.py__" __import__(name)` 
ImportError: [...]/auxchash.so: undefined symbol: BN_bn2hex 

Je ne sais pas comment le comprendre.

+0

Sur un lecture rapide, je pense que vous avez besoin de 'keygen int (bits int, char ** p, char ** q, char ** g, char ** hk, char ** tk)' de sorte que la fonction peut changer le pointeur dans l'appelant . Quelque chose comme '* p = BN_bn2hex (bn_p)'. – jww

+0

En ce qui concerne 'auxchash.so: symbole non défini: BN_bn2hex', que montre' ldd auxchash.so'? Y a-t-il une dépendance à 'libcrypto.so'? – jww

+0

Oui @jww vous avez raison, ce que vous avez écrit est tout à fait correct. Mais j'ai rencontré des problèmes même avec swig et char **. J'ai décidé d'adopter cette approche car je n'arrive pas à gérer un double pointeur vers un char * en swig. Voir ce [lien] (https://stackoverflow.com/questions/46776757/swig-char-as-a-pointer-to-a-char?noredirect=1#comment80538743_46776757). – lorsp000

Répondre

0

Vous devez relier votre module contre OpenSSL, egsomething comme:

auxchash_module = Extension('_auxchash', 
         sources=['auxchash_wrap.cxx', 'auxchash.cpp'], 
         libraries=['crypto', 'ssl'], 
         ) 

(Vous pourriez seulement besoin Crypto dans cette liste, je ne me souviens pas tout à fait/dire en ce moment)

+0

Merci beaucoup! Oui, en ajoutant le paramètre libraries, cela semble fonctionner. (: – lorsp000

+0

Cela fonctionne, mais maintenant je reçois un autre problème: en imprimant les variables de retour sur mon python principal, il imprime des caractères indéchiffrables, d'autre part, dans la fonction C++, j'imprime les mêmes valeurs et la valeur correcte. Quelque chose ne va pas dans la sortie du module swing, mais '% cstring_bounded_output' devrait renvoyer correctement un caractère * .C'est lié aux bibliothèques? – lorsp000

+0

J'ai essayé, pour mieux comprendre, d'écrire dans les variables de retour la simple chaîne "bonjour". Le python principal est incapable de les obtenir correctement (ie il imprime toujours des caractères indéchiffrables – lorsp000