2010-04-01 7 views
4

J'utilise des objets BIO openssl pour convertir une chaîne binaire en chaîne base64. Le code est le suivant:openssl crypto library - conversion base64

void ToBase64(std::string & s_in) { 
    BIO * b_s = BIO_new(BIO_s_mem()); 
    BIO * b64_f = BIO_new(BIO_f_base64()); 

    b_s = BIO_push(b64_f , b_s); 

    std::cout << "IN::" << s_in.length(); 
    BIO_write(b_s, s_in.c_str(), s_in.length()); 


    char * pp; 
    int sz = BIO_get_mem_data(b_s, &pp); 

    std::cout << "OUT::" << sz << endl; 

    s_in.assign(pp,sz); 
    //std::cout << sz << " " << std::string(pp,sz) << std::endl; 

    BIO_free (b64_f); // TODO ret error potential 
    BIO_free (b_s); // 
    } 

La longueur est 64 ou 72. Cependant, la sortie est toujours 65, ce qui est incorrect, il devrait être beaucoup plus grande que cela. La documentation n'est pas la meilleure au monde, AFAIK l'objet bio_s_mem est censé croître dynamiquement. Qu'est-ce que je fais mal ?

Je ferais probablement mieux de trouver une classe C++ autonome qui n'offre pas de support de diffusion en continu, et qui supporte les conversions en base64. Le support de streaming n'est pas adapté à mon application. Cependant, je voulais juste coller à openSSL puisque je suis déjà en fonction de certaines routines crypto. De toute façon, je vais prendre une telle décision après le profilage.

Répondre

2

Vous avez deux problèmes:

  • Vous devez appeler BIO_get_mem_data() sur la mem bio - mais vous avez perdu la référence à (vous écrasez avec la valeur de retour de BIO_push, qui est égale à b64_f). Vous devez appeler BIO_flush() sur la base64 bio après avoir écrit toutes vos données.
+0

Merci, ces deux points ont un sens parfait (je soupçonne que la chasse d'eau fera l'affaire). En réponse au point d'écrasement: J'ai copié l'opération de poussée à partir de l'exemple montré ici: http://www.openssl.org/docs/crypto/BIO_f_base64.html# L'objet bio cible auquel la poussée est appliquée, est écrasé . –

+0

Oui, la chasse d'eau a effectivement fait l'affaire, des réflexions sur la fuite potentielle poignée? Je pense que le point 1 est discutable. –

+0

Eh bien dans cet exemple, peu importe qu'ils perdent la référence à la bio fp, car ils n'ont jamais besoin d'y accéder directement - sa sortie va dans le fichier. D'un autre côté, vous devez extraire explicitement la sortie de la mem bio. Je pense que ça pourrait fonctionner "par hasard", parce que "BIO_get_mem_data()" travaille sur le bio base64 (peut-être est-il construit sur un mem bio?) - et il peut cesser de fonctionner si vous y mettez beaucoup plus de données . – caf

0

Je pense que ce que vous voulez faire est de changer l'ordre des arguments à BIO_push.

b_s = BIO_push (b_s, b64_f)

+0

Merci pour la réponse. La poussée met un filtre plus tôt dans le tube, les exemples de la documentation openSSL le montrent: http://www.openssl.org/docs/crypto/BIO_f_base64.html#. Par conséquent, l'ordre dans ma fonction est correct. –

+0

Intéressant. Selon la page BIO_push http://www.openssl.org/docs/crypto/BIO_push.html l'appel BIO_push renvoie le premier argument avec le second ajouté. Cela aurait l'exemple de base64 écrasant (et perdant) le fp. Une des pages doit être fausse. – Fred