/** * 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::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); }
bool PolicyManager::verifyDigestSha256Signature (const Blob& signature, const SignedBlob& signedBlob) { // 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); return signature.size() == sizeof(signedPortionDigest) && ndn_memcmp (signature.buf(), signedPortionDigest, sizeof(signedPortionDigest)) == 0; }
void IdentityManager::signWithSha256(Data &data, WireFormat& wireFormat) { data.setSignature(DigestSha256Signature()); // Encode once to get the signed portion. SignedBlob encoding = data.wireEncode(wireFormat); // Digest and set the signature. uint8_t signedPortionDigest[ndn_SHA256_DIGEST_SIZE]; ndn_digestSha256 (encoding.signedBuf(), encoding.signedSize(), signedPortionDigest); data.getSignature()->setSignature (Blob(signedPortionDigest, sizeof(signedPortionDigest))); // Encode again to include the signature. data.wireEncode(wireFormat); }
void IdentityManager::signByCertificate(Data &data, const Name &certificateName, WireFormat& wireFormat) { DigestAlgorithm digestAlgorithm; ptr_lib::shared_ptr<Signature> signature = makeSignatureByCertificate (certificateName, digestAlgorithm); data.setSignature(*signature); // Encode once to get the signed portion. SignedBlob encoding = data.wireEncode(wireFormat); data.getSignature()->setSignature (privateKeyStorage_->sign(encoding.signedBuf(), encoding.signedSize(), IdentityCertificate::certificateNameToPublicKeyName(certificateName), digestAlgorithm)); // Encode again to include the signature. data.wireEncode(wireFormat); }
void KeyChain::sign (Interest& interest, const Name& certificateName, WireFormat& wireFormat) { // TODO: Handle signature algorithms other than Sha256WithRsa. Sha256WithRsaSignature signature; signature.getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME); signature.getKeyLocator().setKeyName(certificateName.getPrefix(-1)); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(Name::Component()); // Encode once to get the signed portion, and sign. SignedBlob encoding = interest.wireEncode(wireFormat); ptr_lib::shared_ptr<Signature> signedSignature = sign (encoding.signedBuf(), encoding.signedSize(), certificateName); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1).append (wireFormat.encodeSignatureValue(*signedSignature))); }
void IdentityManager::signInterestWithSha256 (Interest& interest, WireFormat& wireFormat) { DigestSha256Signature signature; // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(Name::Component()); // Encode once to get the signed portion. SignedBlob encoding = interest.wireEncode(wireFormat); // Digest and set the signature. uint8_t signedPortionDigest[ndn_SHA256_DIGEST_SIZE]; ndn_digestSha256 (encoding.signedBuf(), encoding.signedSize(), signedPortionDigest); signature.setSignature(Blob(signedPortionDigest, sizeof(signedPortionDigest))); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1).append (wireFormat.encodeSignatureValue(signature))); }
void IdentityManager::signInterestByCertificate (Interest& interest, const Name& certificateName, WireFormat& wireFormat) { DigestAlgorithm digestAlgorithm; ptr_lib::shared_ptr<Signature> signature = makeSignatureByCertificate (certificateName, digestAlgorithm); // Append the encoded SignatureInfo. interest.getName().append(wireFormat.encodeSignatureInfo(*signature)); // Append an empty signature so that the "signedPortion" is correct. interest.getName().append(Name::Component()); // Encode once to get the signed portion, and sign. SignedBlob encoding = interest.wireEncode(wireFormat); signature->setSignature (privateKeyStorage_->sign(encoding.signedBuf(), encoding.signedSize(), IdentityCertificate::certificateNameToPublicKeyName(certificateName), digestAlgorithm)); // Remove the empty signature and append the real one. interest.setName(interest.getName().getPrefix(-1).append (wireFormat.encodeSignatureValue(*signature))); }