This is a discussion on How to decrypt a file with GPGme within the Linux Security forums, part of the System Security and Security Related category; The main problem with GPGme is its (lack of) documentation. After looking aroung for a while, I found that there ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
The main problem with GPGme is its (lack of) documentation.
After looking aroung for a while, I found that there is an obscure (i.e., undocumented) way to generate a PDF manual. The examples contained there, however, are far from being tutorial material. What that manual needs badly are examples for the most used operations: decrypt and encrypt. I used Google to find the following code which seems to be what I am looking for (sample code to decrypt a file). Unfortunately the posting was in German and the code in C++, two languages that I don't know that well. Anyway, if somebody out there could translate the code below to C (_specially_ the callback that handles the passphrase) I for one, would be most grateful. TIA, -Ramon F Herrera --------------------------------------------------------------- #include <iostream> #include <iomanip> #include "gpgme.h" // Callback function to retrieve the passphrase const char *myPass(void *hook, const char *desc, void **r_hd) { char *sNull = "NULL"; const char *p; if( desc ) p = desc; else p = sNull; std::cout << "myPass(" << p << ")" << std::endl; static const char *passPhrase = "secret"; if( desc ) p = passPhrase; else p = NULL; return p; } int main(int argc, char *argv[]) { GpgmeCtx ctx; GpgmeData ciphertext, plaintext; GpgmeRecipients rset; gpgme_new (&ctx); gpgme_set_armor (ctx, 1); gpgme_set_passphrase_cb (ctx, myPass, NULL); char *plain = "Hallo Welt"; gpgme_data_new_from_mem (&plaintext, plain, strlen(plain), 1 ); std::cout << "gpgme_data_new_from_mem(plaintext) ok" << std::endl; GpgmeError err = gpgme_data_new ( &ciphertext ); if( err != GPGME_No_Error ) { std::cout << "gpgme_data_new error " << err << std::endl; exit(0); } std::cout << "gpgme_data_new(cipher) ok" << std::endl; err = gpgme_recipients_new (&rset); if( err != GPGME_No_Error ) { std::cout << "gpgme_recipients_new error " << err << std::endl; exit(0); } std::cout << "gpgme_recipients_new() ok" << std::endl; err = gpgme_recipients_add_name (rset, "neo42@gmx.de"); if( err != GPGME_No_Error ) { std::cout << "gpgme_recipients_add_name error " << err << std::endl; exit(0); } std::cout << "gpgme_recipients_add_name() ok" << std::endl; err = gpgme_op_encrypt (ctx, rset, plaintext, ciphertext ); if( err != GPGME_No_Error ) { std::cout << "gpgme_op_encrypt error " << err << std::endl; exit(0); } std::cout << "gpgme_op_encrypt() ok" << std::endl; char buf[4096]; size_t nread; err = gpgme_data_read( ciphertext, buf, sizeof(buf), &nread ); if( err != GPGME_No_Error ) { std::cout << "gpgme_data_read error " << err << std::endl; exit(0); } std::cout << "gpgme_data_read() ok " << nread << " bytes" << std::endl; buf[nread] = 0; std::cout << buf; // free all used resources gpgme_data_release (plaintext); gpgme_data_release (ciphertext); gpgme_recipients_release (rset); // // Decrypt // err = gpgme_data_new_from_mem (&ciphertext, buf, nread, 1 ); if( err != GPGME_No_Error ) { std::cout << "gpgme_data_new_from_mem(buf) error " << err << std::endl; exit(0); } std::cout << "gpgme_data_new_from_mem(ciphertext) ok" << std::endl; gpgme_data_new (&plaintext); err = gpgme_op_decrypt (ctx, ciphertext, plaintext); if( err != GPGME_No_Error ) { std::cout << "gpgme_op_decrypt error " << err << std::endl; exit(0); } std::cout << "gpgme_op_decrypt() ok" << std::endl; gpgme_data_release(ciphertext); err = gpgme_data_read( plaintext, buf, sizeof(buf), &nread ); if( err != GPGME_No_Error ) { std::cout << "gpgme_data_read error " << err << std::endl; exit(0); |
|
|||
|
I have a vague knowledge of c++. Hope this helps. 1. [std::]cout is the method of printing to standard output in c++. You need to replace it with printfs, or the like. Notice that it understands different data types intuitively, but printf doesn't: cout << "hello" << 2; printf("hello%d", 2); The std:: is just a way of referencing which cout is being used. In this case, the standard one. << is the operator which does the actual work, as well as separates parts, and std::endl is the endline, replaceable with "\n". 2. I personally have never used const in c, but I guess it compiles... It just makes variables immutable (i.e., you can't change them) in c++. 3. Other than that, myPass appears to be coded in normal C. 4. Looking at the variables, and the way they are initialized by calls to functions, I suspect that they are merely C structures, and not c++ objects. But don't take my word on this, go ahead and check the header files. (though, if you want to be technical about it, structs are classes in C++ with default to public access permissions...) Jon. -- * Does the walker choose the path, or does the path choose the walker? (fr. Sabriel) * -- |
|
|||
|
1) unpack the src and then do info -f doc/gpgme.info
2) unpack the src and look at the examples in tests/gpg, for example t-decrypt.c (looks pretty simple to me, completely c, including the t-support.h) Of course, I'm only glancing at it. Jon. -- * Does the walker choose the path, or does the path choose the walker? (fr. Sabriel) * -- |