EpadResult ExtractFromWad(RandomInStream &in, OutStream &out, std::string &key_file) { WadMetadata metadata; auto result = ExtractWadMetadata(in, in.GetCount(), metadata); in.Seek(metadata.payload_offset); if(result != EpadResult::Success) return result; Botan::SecureVector<byte> buffer; buffer.resize(metadata.payload_size != 0 ? metadata.payload_size : in.GetCount()); in.Read(buffer.data(), buffer.size()); out.Write(buffer.data(), buffer.size()); key_file.clear(); if(metadata.key_file_offset != kInvalid) { key_file.resize(metadata.key_file_size); in.Seek(metadata.key_file_offset); in.Read(reinterpret_cast<byte *>(&*key_file.begin()), metadata.key_file_size); } return EpadResult::Success; }
bool BotanRSA::signFinal(ByteString& signature) { if (!AsymmetricAlgorithm::signFinal(signature)) { return false; } // Perform the signature operation #if BOTAN_VERSION_MINOR == 11 std::vector<Botan::byte> signResult; #else Botan::SecureVector<Botan::byte> signResult; #endif try { BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); signResult = signer->signature(*rng->getRNG()); } catch (...) { ERROR_MSG("Could not sign the data"); delete signer; signer = NULL; return false; } // Return the result signature.resize(signResult.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&signature[0], signResult.data(), signResult.size()); #else memcpy(&signature[0], signResult.begin(), signResult.size()); #endif delete signer; signer = NULL; return true; }
// Encryption functions bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding) { // Check if the public key is the right type if (!publicKey->isOfType(BotanRSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } std::string eme; switch (padding) { case AsymMech::RSA_PKCS: eme = "PKCS1v15"; break; case AsymMech::RSA_PKCS_OAEP: eme = "EME1(SHA-160)"; break; case AsymMech::RSA: eme = "Raw"; break; default: ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); return false; } BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey; Botan::RSA_PublicKey* botanKey = pk->getBotanKey(); if (!botanKey) { ERROR_MSG("Could not get the Botan public key"); return false; } Botan::PK_Encryptor_EME* encryptor = NULL; try { encryptor = new Botan::PK_Encryptor_EME(*botanKey, eme); } catch (...) { ERROR_MSG("Could not create the encryptor token"); return false; } // Perform the encryption operation #if BOTAN_VERSION_MINOR == 11 std::vector<Botan::byte> encResult; #else Botan::SecureVector<Botan::byte> encResult; #endif try { BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); encResult = encryptor->encrypt(data.const_byte_str(), data.size(), *rng->getRNG()); } catch (...) { ERROR_MSG("Could not encrypt the data"); delete encryptor; return false; } // Return the result encryptedData.resize(encResult.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&encryptedData[0], encResult.data(), encResult.size()); #else memcpy(&encryptedData[0], encResult.begin(), encResult.size()); #endif delete encryptor; return true; }
// Signing functions bool BotanRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { std::string emsa = ""; switch (mechanism) { case AsymMech::RSA: emsa = "Raw"; break; case AsymMech::RSA_PKCS: emsa = "EMSA3(Raw)"; break; default: // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen); } // Check if the private key is the right type if (!privateKey->isOfType(BotanRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey; Botan::RSA_PrivateKey* botanKey = pk->getBotanKey(); if (!botanKey) { ERROR_MSG("Could not get the Botan private key"); return false; } try { signer = new Botan::PK_Signer(*botanKey, emsa); // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster. } catch (...) { ERROR_MSG("Could not create the signer token"); return false; } // Perform the signature operation #if BOTAN_VERSION_MINOR == 11 std::vector<Botan::byte> signResult; #else Botan::SecureVector<Botan::byte> signResult; #endif try { BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG()); } catch (std::exception& e) { ERROR_MSG("Could not sign the data: %s", e.what()); delete signer; signer = NULL; return false; } // Return the result signature.resize(signResult.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&signature[0], signResult.data(), signResult.size()); #else memcpy(&signature[0], signResult.begin(), signResult.size()); #endif delete signer; signer = NULL; return true; }
// Signing functions bool BotanRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const std::string mechanism) { std::string lowerMechanism; lowerMechanism.resize(mechanism.size()); std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower); std::string emsa = ""; if (!lowerMechanism.compare("rsa-pkcs")) { emsa = "EMSA3(Raw)"; } else if (!lowerMechanism.compare("rsa-raw")) { emsa = "Raw"; } else { // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism); } // Check if the private key is the right type if (!privateKey->isOfType(BotanRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey; Botan::RSA_PrivateKey* botanKey = pk->getBotanKey(); if (!botanKey) { ERROR_MSG("Could not get the Botan private key"); return false; } try { signer = new Botan::PK_Signer(*botanKey, emsa); // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster. } catch (...) { ERROR_MSG("Could not create the signer token"); return false; } // Perform the signature operation #if BOTAN_VERSION_MINOR == 11 std::vector<Botan::byte> signResult; #else Botan::SecureVector<Botan::byte> signResult; #endif try { BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG()); } catch (...) { ERROR_MSG("Could not sign the data"); delete signer; signer = NULL; return false; } // Return the result signature.resize(signResult.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&signature[0], signResult.data(), signResult.size()); #else memcpy(&signature[0], signResult.begin(), signResult.size()); #endif delete signer; signer = NULL; return true; }