bool OSSLRSA::verifyFinal(const ByteString& signature) { // Save necessary state before calling super class verifyFinal OSSLRSAPublicKey* pk = (OSSLRSAPublicKey*) currentPublicKey; AsymMech::Type mechanism = currentMechanism; if (!AsymmetricAlgorithm::verifyFinal(signature)) { return false; } ByteString firstHash, secondHash; bool bFirstResult = pCurrentHash->hashFinal(firstHash); bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true; delete pCurrentHash; pCurrentHash = NULL; if (pSecondHash != NULL) { delete pSecondHash; pSecondHash = NULL; } if (!bFirstResult || !bSecondResult) { return false; } ByteString digest = firstHash + secondHash; // Determine the signature NID type int type = 0; bool isPSS = false; const EVP_MD* hash = NULL; switch (mechanism) { case AsymMech::RSA_MD5_PKCS: type = NID_md5; break; case AsymMech::RSA_SHA1_PKCS: type = NID_sha1; break; case AsymMech::RSA_SHA224_PKCS: type = NID_sha224; break; case AsymMech::RSA_SHA256_PKCS: type = NID_sha256; break; case AsymMech::RSA_SHA384_PKCS: type = NID_sha384; break; case AsymMech::RSA_SHA512_PKCS: type = NID_sha512; break; case AsymMech::RSA_SHA1_PKCS_PSS: isPSS = true; hash = EVP_sha1(); break; case AsymMech::RSA_SHA224_PKCS_PSS: isPSS = true; hash = EVP_sha224(); break; case AsymMech::RSA_SHA256_PKCS_PSS: isPSS = true; hash = EVP_sha256(); break; case AsymMech::RSA_SHA384_PKCS_PSS: isPSS = true; hash = EVP_sha384(); break; case AsymMech::RSA_SHA512_PKCS_PSS: isPSS = true; hash = EVP_sha512(); break; case AsymMech::RSA_SSL: type = NID_md5_sha1; break; default: break; } // Perform the verify operation bool rv; if (isPSS) { ByteString plain; plain.resize(pk->getN().size()); int result = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &plain[0], pk->getOSSLKey(), RSA_NO_PADDING); if (result < 0) { rv = false; ERROR_MSG("RSA public decrypt failed (0x%08X)", ERR_get_error()); } else { plain.resize(result); result = RSA_verify_PKCS1_PSS(pk->getOSSLKey(), &digest[0], hash, &plain[0], sLen); if (result == 1) { rv = true; } else { rv = false; ERROR_MSG("RSA PSS verify failed (0x%08X)", ERR_get_error()); } } } else { rv = (RSA_verify(type, &digest[0], digest.size(), (unsigned char*) signature.const_byte_str(), signature.size(), pk->getOSSLKey()) == 1); if (!rv) ERROR_MSG("RSA verify failed (0x%08X)", ERR_get_error()); } return rv; }
// Signing functions bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { if (mechanism == AsymMech::RSA_PKCS) { // Separate implementation for RSA PKCS #1 signing without hash computation // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of PKCS #1 signing the length of the input data may not exceed 40% of the // modulus size OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; size_t allowedLen = osslKey->getN().size() - 11; if (dataToSign.size() > allowedLen) { ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a PKCS #1 signature"); return false; } signature.resize(sigLen); return true; } else if (mechanism == AsymMech::RSA) { // Separate implementation for raw RSA signing // Check if the private key is the right type if (!privateKey->isOfType(OSSLRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // In case of raw RSA, the length of the input data must match the length of the modulus OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey; if (dataToSign.size() != osslKey->getN().size()) { ERROR_MSG("Size of data to sign does not match the modulus size"); return false; } // Perform the signature operation signature.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); if (!RSA_blinding_on(rsa, NULL)) { ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key"); return false; } int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING); RSA_blinding_off(rsa); if (sigLen == -1) { ERROR_MSG("An error occurred while performing a raw RSA signature"); return false; } signature.resize(sigLen); return true; } else { // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen); } }
// Encryption functions bool OSSLRSA::encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding) { // Check if the public key is the right type if (!publicKey->isOfType(OSSLRSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // Retrieve the OpenSSL key object RSA* rsa = ((OSSLRSAPublicKey*) publicKey)->getOSSLKey(); // Check the data and padding algorithm int osslPadding = 0; if (padding == AsymMech::RSA_PKCS) { // The size of the input data cannot be more than the modulus // length of the key - 11 if (data.size() > (size_t) (RSA_size(rsa) - 11)) { ERROR_MSG("Too much data supplied for RSA PKCS #1 encryption"); return false; } osslPadding = RSA_PKCS1_PADDING; } else if (padding == AsymMech::RSA_PKCS_OAEP) { // The size of the input data cannot be more than the modulus // length of the key - 41 if (data.size() > (size_t) (RSA_size(rsa) - 41)) { ERROR_MSG("Too much data supplied for RSA OAEP encryption"); return false; } osslPadding = RSA_PKCS1_OAEP_PADDING; } else if (padding == AsymMech::RSA) { // The size of the input data should be exactly equal to the modulus length if (data.size() != (size_t) RSA_size(rsa)) { ERROR_MSG("Incorrect amount of input data supplied for raw RSA encryption"); return false; } osslPadding = RSA_NO_PADDING; } else { ERROR_MSG("Invalid padding mechanism supplied (%i)", padding); return false; } // Perform the RSA operation encryptedData.resize(RSA_size(rsa)); if (RSA_public_encrypt(data.size(), (unsigned char*) data.const_byte_str(), &encryptedData[0], rsa, osslPadding) == -1) { ERROR_MSG("RSA public key encryption failed (0x%08X)", ERR_get_error()); return false; } return true; }
// Verification functions bool OSSLRSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { if (mechanism == AsymMech::RSA_PKCS) { // Specific implementation for PKCS #1 only verification; originalData is assumed to contain // a digestInfo structure and verification is performed by comparing originalData to the data // recovered from the signature // Check if the public key is the right type if (!publicKey->isOfType(OSSLRSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // Perform the RSA public key operation OSSLRSAPublicKey* osslKey = (OSSLRSAPublicKey*) publicKey; ByteString recoveredData; recoveredData.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); int retLen = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &recoveredData[0], rsa, RSA_PKCS1_PADDING); if (retLen == -1) { ERROR_MSG("Public key operation failed"); return false; } recoveredData.resize(retLen); return (originalData == recoveredData); } else if (mechanism == AsymMech::RSA) { // Specific implementation for raw RSA verifiction; originalData is assumed to contain the // full input data used to compute the signature and verification is performed by comparing // originalData to the data recovered from the signature // Check if the public key is the right type if (!publicKey->isOfType(OSSLRSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } // Perform the RSA public key operation OSSLRSAPublicKey* osslKey = (OSSLRSAPublicKey*) publicKey; ByteString recoveredData; recoveredData.resize(osslKey->getN().size()); RSA* rsa = osslKey->getOSSLKey(); int retLen = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &recoveredData[0], rsa, RSA_NO_PADDING); if (retLen == -1) { ERROR_MSG("Public key operation failed"); return false; } recoveredData.resize(retLen); return (originalData == recoveredData); } else { // Call the generic function return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen); } }
// Signing functions bool BotanDSA::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("dsa")) { 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(BotanDSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanDSAPrivateKey* pk = (BotanDSAPrivateKey*) privateKey; Botan::DSA_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 Botan::SecureVector<Botan::byte> signResult; 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()); memcpy(&signature[0], signResult.begin(), signResult.size()); delete signer; signer = NULL; return true; }
// Verification functions bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* /* param = NULL */, const size_t /* paramLen = 0 */) { if (mechanism != AsymMech::ECDSA) { ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); return false; } // Check if the private key is the right type if (!publicKey->isOfType(OSSLECPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } OSSLECPublicKey* pk = (OSSLECPublicKey*) publicKey; EC_KEY* eckey = pk->getOSSLKey(); if (eckey == NULL) { ERROR_MSG("Could not get the OpenSSL public key"); return false; } // Use the OpenSSL implementation and not any engine ECDSA_set_method(eckey, ECDSA_OpenSSL()); // Perform the verify operation size_t len = pk->getOrderLength(); if (len == 0) { ERROR_MSG("Could not get the order length"); return false; } if (signature.size() != 2 * len) { ERROR_MSG("Invalid buffer length"); return false; } ECDSA_SIG* sig = ECDSA_SIG_new(); if (sig == NULL) { ERROR_MSG("Could not create an ECDSA_SIG object"); return false; } if (sig->r != NULL) BN_clear_free(sig->r); const unsigned char *s = signature.const_byte_str(); sig->r = BN_bin2bn(s, len, NULL); if (sig->s != NULL) BN_clear_free(sig->s); sig->s = BN_bin2bn(s + len, len, NULL); if (sig->r == NULL || sig->s == NULL) { ERROR_MSG("Could not add data to the ECDSA_SIG object"); ECDSA_SIG_free(sig); return false; } int ret = ECDSA_do_verify(originalData.const_byte_str(), originalData.size(), sig, eckey); if (ret != 1) { if (ret < 0) ERROR_MSG("ECDSA verify failed (0x%08X)", ERR_get_error()); ECDSA_SIG_free(sig); return false; } ECDSA_SIG_free(sig); return true; }
// Encryption functions bool BotanSymmetricAlgorithm::encryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode:CBC */, const ByteString& IV /* = ByteString()*/, bool padding /* = true */) { // Call the superclass initialiser if (!SymmetricAlgorithm::encryptInit(key, mode, IV, padding)) { return false; } // Check the IV if ((IV.size() > 0) && (IV.size() != getBlockSize())) { ERROR_MSG("Invalid IV size (%d bytes, expected %d bytes)", IV.size(), getBlockSize()); ByteString dummy; SymmetricAlgorithm::encryptFinal(dummy); return false; } ByteString iv; if (IV.size() > 0) { iv = IV; } else { iv.wipe(getBlockSize()); } // Determine the cipher std::string cipherName = getCipher(); if (cipherName == "") { ERROR_MSG("Invalid encryption cipher"); ByteString dummy; SymmetricAlgorithm::encryptFinal(dummy); return false; } // Allocate the context try { Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size()); if (mode == SymMode::ECB) { cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, Botan::ENCRYPTION)); } else { Botan::InitializationVector botanIV = Botan::InitializationVector(IV.const_byte_str(), IV.size()); cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, botanIV, Botan::ENCRYPTION)); } cryption->start_msg(); } catch (...) { ERROR_MSG("Failed to create the encryption token"); ByteString dummy; SymmetricAlgorithm::encryptFinal(dummy); delete cryption; cryption = NULL; return false; } return true; }
// Verification functions bool BotanDSA::verify(PublicKey* publicKey, const ByteString& originalData, const 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("dsa")) { emsa = "Raw"; } else { // Call the generic function return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism); } // Check if the public key is the right type if (!publicKey->isOfType(BotanDSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanDSAPublicKey* pk = (BotanDSAPublicKey*) publicKey; Botan::DSA_PublicKey* botanKey = pk->getBotanKey(); if (!botanKey) { ERROR_MSG("Could not get the Botan public key"); return false; } try { verifier = new Botan::PK_Verifier(*botanKey, emsa); } catch (...) { ERROR_MSG("Could not create the verifier token"); return false; } // Perform the verify operation bool verResult; try { verResult = verifier->verify_message(originalData.const_byte_str(), originalData.size(), signature.const_byte_str(), signature.size()); } catch (...) { ERROR_MSG("Could not check the signature"); delete verifier; verifier = NULL; return false; } delete verifier; verifier = NULL; return verResult; }
// Wrap/Unwrap keys bool BotanAES::wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out) { // Check key bit length; AES only supports 128, 192 or 256 bit keys if ((key->getBitLen() != 128) && (key->getBitLen() != 192) && (key->getBitLen() != 256)) { ERROR_MSG("Invalid AES key length (%d bits)", key->getBitLen()); return false; } // Determine the wrapping mode if (mode == SymWrap::AES_KEYWRAP) { // RFC 3394 AES key wrap if (in.size() < 16) { ERROR_MSG("key data to wrap too small"); return false; } if ((in.size() % 8) != 0) { ERROR_MSG("key data to wrap not aligned"); return false; } #if BOTAN_VERSION_MINOR == 11 Botan::secure_vector<Botan::byte> data(in.size()); memcpy(data.data(), in.const_byte_str(), in.size()); Botan::secure_vector<Botan::byte> wrapped; #else Botan::MemoryVector<Botan::byte> data(in.size()); memcpy(data.begin(), in.const_byte_str(), in.size()); Botan::SecureVector<Botan::byte> wrapped; #endif Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size()); Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); try { wrapped = Botan::rfc3394_keywrap(data, botanKey, af); } catch (...) { ERROR_MSG("AES key wrap failed"); return false; } out.resize(wrapped.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&out[0], wrapped.data(), out.size()); #else memcpy(&out[0], wrapped.begin(), out.size()); #endif return true; } #ifdef HAVE_AES_KEY_WRAP_PAD else if (mode == SymWrap::AES_KEYWRAP_PAD) { // RFC 5649 AES key wrap with pad #if BOTAN_VERSION_MINOR == 11 Botan::secure_vector<Botan::byte> data(in.size()); memcpy(data.data(), in.const_byte_str(), in.size()); Botan::secure_vector<Botan::byte> wrapped; #else Botan::MemoryVector<Botan::byte> data(in.size()); memcpy(data.begin(), in.const_byte_str(), in.size()); Botan::SecureVector<Botan::byte> wrapped; #endif Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size()); Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); try { wrapped = Botan::rfc5649_keywrap(data, botanKey, af); } catch (...) { ERROR_MSG("AES key wrap failed"); return false; } out.resize(wrapped.size()); #if BOTAN_VERSION_MINOR == 11 memcpy(&out[0], wrapped.data(), out.size()); #else memcpy(&out[0], wrapped.begin(), out.size()); #endif return true; } #endif else { ERROR_MSG("unknown AES key wrap mode %i", mode); return false; } }
// Decryption functions bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const std::string padding) { // Check if the private key is the right type if (!privateKey->isOfType(BotanRSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } std::string lowerPadding; lowerPadding.resize(padding.size()); std::transform(padding.begin(), padding.end(), lowerPadding.begin(), tolower); std::string eme; if (!lowerPadding.compare("rsa-pkcs")) { eme = "PKCS1v15"; } else if (!lowerPadding.compare("rsa-pkcs-oaep")) { eme = "EME1(SHA-160)"; } else if (!lowerPadding.compare("rsa-raw")) { eme = "Raw"; } else { ERROR_MSG("Invalid padding mechanism supplied (%s)", padding.c_str()); 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; } Botan::PK_Decryptor_EME* decryptor = NULL; try { decryptor = new Botan::PK_Decryptor_EME(*botanKey, eme); } catch (...) { ERROR_MSG("Could not create the decryptor token"); return false; } // Perform the decryption operation Botan::SecureVector<Botan::byte> decResult; try { decResult = decryptor->decrypt(encryptedData.const_byte_str(), encryptedData.size()); } catch (...) { ERROR_MSG("Could not decrypt the data"); delete decryptor; return false; } // Return the result if (!eme.compare("Raw")) { // We compensate that Botan removes leading zeros int modSize = pk->getN().size(); int decSize = decResult.size(); data.resize(modSize); memcpy(&data[0] + modSize - decSize, decResult.begin(), decSize); } else { data.resize(decResult.size()); memcpy(&data[0], decResult.begin(), decResult.size()); } delete decryptor; return true; }
// Encryption functions bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const std::string 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 lowerPadding; lowerPadding.resize(padding.size()); std::transform(padding.begin(), padding.end(), lowerPadding.begin(), tolower); std::string eme; if (!lowerPadding.compare("rsa-pkcs")) { eme = "PKCS1v15"; } else if (!lowerPadding.compare("rsa-pkcs-oaep")) { eme = "EME1(SHA-160)"; } else if (!lowerPadding.compare("rsa-raw")) { eme = "Raw"; } else { ERROR_MSG("Invalid padding mechanism supplied (%s)", padding.c_str()); 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 Botan::SecureVector<Botan::byte> encResult; 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()); memcpy(&encryptedData[0], encResult.begin(), encResult.size()); delete encryptor; return true; }
// Signing functions bool BotanDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { std::string emsa; if (mechanism == AsymMech::DSA) { emsa = "Raw"; } else { // Call default implementation return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen); } // Check if the private key is the right type if (!privateKey->isOfType(BotanDSAPrivateKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanDSAPrivateKey* pk = (BotanDSAPrivateKey*) privateKey; Botan::DSA_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; }
// Verification functions bool BotanDSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param /* = NULL */, const size_t paramLen /* = 0 */) { std::string emsa; if (mechanism == AsymMech::DSA) { emsa = "Raw"; } else { // Call the generic function return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen); } // Check if the public key is the right type if (!publicKey->isOfType(BotanDSAPublicKey::type)) { ERROR_MSG("Invalid key type supplied"); return false; } BotanDSAPublicKey* pk = (BotanDSAPublicKey*) publicKey; Botan::DSA_PublicKey* botanKey = pk->getBotanKey(); if (!botanKey) { ERROR_MSG("Could not get the Botan public key"); return false; } try { verifier = new Botan::PK_Verifier(*botanKey, emsa); } catch (...) { ERROR_MSG("Could not create the verifier token"); return false; } // Perform the verify operation bool verResult; try { verResult = verifier->verify_message(originalData.const_byte_str(), originalData.size(), signature.const_byte_str(), signature.size()); } catch (...) { ERROR_MSG("Could not check the signature"); delete verifier; verifier = NULL; return false; } delete verifier; verifier = NULL; return verResult; }