std::string GPGWrapper::encrypt(const std::string & recipientName, const std::string& message) { init(); ScopedGPGData clear_text, sign_text, encrypted_text; gpgme_error_t error = clear_text.init(message.c_str(), message.length()); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (clear_text)."); error = sign_text.init(); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (sign_text)."); error = gpgme_op_sign(context, clear_text.get(), sign_text.get(), GPGME_SIG_MODE_NORMAL); fail_if_err(error, L"Nie uda³o siê podpisaæ wiadomoœci."); error = gpgme_data_rewind(sign_text.get()); fail_if_err(error, L"Nie uda³o siê przewin¹æ na pocz¹tek podpisanego strumienia, aby go póŸniej zaszyfrowaæ."); error = encrypted_text.init(); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do zaszyfrowana (encrypted_text)."); gpgme_key_t recipient = getPublicKey(recipientName.c_str()); gpgme_key_t recipients[2] = { NULL, NULL }; recipients[0] = recipient; error = gpgme_op_encrypt(context, recipients, GPGME_ENCRYPT_ALWAYS_TRUST, sign_text.get(), encrypted_text.get()); fail_if_err(error, L"Nie uda³o siê zaszyfrowaæ podpisanej wiadomoœci."); gpgme_encrypt_result_t result = gpgme_op_encrypt_result(context); fail_if_err(result->invalid_recipients, L"Nie poprawny klucz szyfrowania odbiorcy."); return copyData(encrypted_text.get()); }
GPGWrapperDecryptedData GPGWrapper::decrypt(const std::string& message) { init(); ScopedGPGData clear_text, sign_text, encrypted_text; gpgme_error_t error = encrypted_text.init(message.c_str(), message.length()); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do odszyfrowania (encrypted_text)."); error = sign_text.init(); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do odszyfrowania (sign_text)."); error = gpgme_op_decrypt(context, encrypted_text.get(), sign_text.get()); fail_if_err(error, L"Nie uda³o siê odszyfrowaæ wiadomoœci."); error = gpgme_data_rewind(sign_text.get()); fail_if_err(error, L"Nie uda³o siê przewin¹æ na pocz¹tek podpisanego strumienia, aby go póŸniej zweryfikowaæ."); error = clear_text.init(); fail_if_err(error, L"Nie uda³o siê zainicjowaæ danych do odszyfrowania (clear_text)."); error = gpgme_op_verify(context, sign_text.get(), NULL, clear_text.get()); fail_if_err(error, L"Nie powiod³a siê próba potwierdzenia podpisu nadawcy."); GPGWrapperDecryptedData result; gpgme_verify_result_t verifyResult = gpgme_op_verify_result(context); if (verifyResult != NULL && verifyResult->signatures != NULL && verifyResult->signatures->summary & GPGME_SIGSUM_VALID) result.isSignValid = true; result.data = copyData(clear_text.get()); return result; }
gpgme_error_t cm_gpgme_data_rewind(gpgme_data_t dh) { #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 if (gpgme_data_seek(dh, (off_t)0, SEEK_SET) == -1) return gpg_error_from_errno(errno); else return 0; #else return gpgme_data_rewind(dh); #endif }
std::string GPGWrapper::copyData(gpgme_data_t data) { gpgme_error_t error = gpgme_data_rewind(data); fail_if_err(error, L"Nie uda³o siê przewin¹æ na pocz¹tek strumienia, aby go póŸniej odczytaæ."); const int bufferSize = 4096; char buffer[bufferSize + 1]; gpgme_ssize_t nbytes; std::string dataCopy; while ((nbytes = gpgme_data_read(data, buffer, bufferSize)) > 0) { size_t actualLength = dataCopy.length(); dataCopy.resize(dataCopy.length() + nbytes); memcpy(&dataCopy[actualLength], buffer, nbytes); } if (nbytes == -1) throw GPGWrapperError(L"B³¹d podczas kopiowania danyh ze strumienia."); return dataCopy; }