bool PolicyManager::verifySha256WithEcdsaSignature (const Blob& signature, const SignedBlob& signedBlob, const Blob& publicKeyDer) { // Set signedPortionDigest to the digest of the signed portion of the signedBlob. uint8_t signedPortionDigest[SHA256_DIGEST_LENGTH]; ndn_digestSha256 (signedBlob.signedBuf(), signedBlob.signedSize(), signedPortionDigest); // Verify the signedPortionDigest. // Use a temporary pointer since d2i updates it. const uint8_t *derPointer = publicKeyDer.buf(); EC_KEY *ecPublicKey = d2i_EC_PUBKEY(NULL, &derPointer, publicKeyDer.size()); if (!ecPublicKey) throw UnrecognizedKeyFormatException ("Error decoding public key in d2i_EC_PUBKEY"); int success = ECDSA_verify (NID_sha256, signedPortionDigest, sizeof(signedPortionDigest), (uint8_t *)signature.buf(),signature.size(), ecPublicKey); // Free the public key before checking for success. EC_KEY_free(ecPublicKey); // ECDSA_verify returns 1 for a valid signature. return (success == 1); }
Blob RsaAlgorithm::encrypt (const Blob& keyBits, const Blob& plainData, const EncryptParams& params) { RsaPublicKeyLite publicKey; if (publicKey.decode(keyBits) != NDN_ERROR_success) throw UnrecognizedKeyFormatException ("RsaAlgorithm: Error decoding public key"); // TODO: use RSA_size, etc. to get the proper size of the output buffer. ptr_lib::shared_ptr<vector<uint8_t> > encryptedData(new vector<uint8_t>(1000)); size_t encryptedDataLength; ndn_Error error; if ((error = publicKey.encrypt (plainData, params.getAlgorithmType(), &encryptedData->front(), encryptedDataLength))) { if (error == NDN_ERROR_Unsupported_algorithm_type) throw runtime_error("RsaAlgorithm: Unsupported padding scheme"); else throw SecurityException(string("RsaAlgorithm: ") + ndn_getErrorString(error)); } encryptedData->resize(encryptedDataLength); return Blob(encryptedData, false); }
/** * Verify the RSA signature on the SignedBlob using the given public key. * TODO: Move this general verification code to a more central location. * @param signature The Sha256WithRsaSignature. * @param signedBlob the SignedBlob with the signed portion to verify. * @param publicKeyDer The DER-encoded public key used to verify the signature. * @return true if the signature verifies, false if not. */ static bool verifySha256WithRsaSignature (const Sha256WithRsaSignature* signature, const SignedBlob& signedBlob, const Blob& publicKeyDer) { // Set signedPortionDigest to the digest of the signed portion of the wire encoding. uint8_t signedPortionDigest[SHA256_DIGEST_LENGTH]; // wireEncode returns the cached encoding if available. ndn_digestSha256 (signedBlob.signedBuf(), signedBlob.signedSize(), signedPortionDigest); // Verify the signedPortionDigest. // Use a temporary pointer since d2i updates it. const uint8_t *derPointer = publicKeyDer.buf(); RSA *rsaPublicKey = d2i_RSA_PUBKEY(NULL, &derPointer, publicKeyDer.size()); if (!rsaPublicKey) throw UnrecognizedKeyFormatException("Error decoding public key in d2i_RSAPublicKey"); int success = RSA_verify (NID_sha256, signedPortionDigest, sizeof(signedPortionDigest), (uint8_t *)signature->getSignature().buf(), signature->getSignature().size(), rsaPublicKey); // Free the public key before checking for success. RSA_free(rsaPublicKey); // RSA_verify returns 1 for a valid signature. return (success == 1); }
bool PolicyManager::verifySignature (const Signature* signature, const SignedBlob& signedBlob, const Blob& publicKeyDer) { ndn_Error error; bool verified; if (dynamic_cast<const DigestSha256Signature *>(signature)) return CryptoLite::verifyDigestSha256Signature (signature->getSignature(), signedBlob.getSignedPortionBlobLite()); #if NDN_CPP_HAVE_LIBCRYPTO else if (dynamic_cast<const Sha256WithRsaSignature *>(signature)) { if (publicKeyDer.isNull()) return false; if ((error = RsaPublicKeyLite::verifySha256WithRsaSignature (signature->getSignature(), signedBlob.getSignedPortionBlobLite(), publicKeyDer, verified)) != 0) { if (error == NDN_ERROR_Error_decoding_key) throw UnrecognizedKeyFormatException("Error decoding public key"); else throw SecurityException(ndn_getErrorString(error)); } return verified; } else if (dynamic_cast<const Sha256WithEcdsaSignature *>(signature)) { if (publicKeyDer.isNull()) return false; if ((error = EcPublicKeyLite::verifySha256WithEcdsaSignature (signature->getSignature(), signedBlob.getSignedPortionBlobLite(), publicKeyDer, verified)) != 0) { if (error == NDN_ERROR_Error_decoding_key) throw UnrecognizedKeyFormatException("Error decoding public key"); else throw SecurityException(ndn_getErrorString(error)); } return verified; } else #endif throw SecurityException("PolicyManager::verify: Signature type is unknown"); }
ptr_lib::shared_ptr<PublicKey> PublicKey::fromDer(const Blob& keyDer) { // Use a temporary pointer since d2i updates it. const uint8_t *derPointer = keyDer.buf(); RSA *publicKey = d2i_RSA_PUBKEY(NULL, &derPointer, keyDer.size()); if (!publicKey) throw UnrecognizedKeyFormatException("Error decoding public key DER"); RSA_free(publicKey); return ptr_lib::shared_ptr<PublicKey>(new PublicKey(OID(vector<int>(RSA_OID, RSA_OID + sizeof(RSA_OID))), keyDer)); }