security: Add check for success of TPM signing

Change-Id: I5c0fc958f4d359354391a30c62791e877052b97e
Refs: #4585, #5086
diff --git a/ndn-cxx/security/v2/key-chain.cpp b/ndn-cxx/security/v2/key-chain.cpp
index 255f310..75f1b68 100644
--- a/ndn-cxx/security/v2/key-chain.cpp
+++ b/ndn-cxx/security/v2/key-chain.cpp
@@ -703,7 +703,14 @@
   if (keyName == SigningInfo::getDigestSha256Identity())
     return Block(tlv::SignatureValue, util::Sha256::computeDigest(buf, size));
 
-  return Block(tlv::SignatureValue, m_tpm->sign(buf, size, keyName, digestAlgorithm));
+  auto signature = m_tpm->sign(buf, size, keyName, digestAlgorithm);
+  if (!signature) {
+    NDN_THROW(InvalidSigningInfoError("TPM signing failed for key `" + keyName.toUri() + "` "
+                                      "(e.g., PIB contains info about the key, but TPM is missing "
+                                      "the corresponding private key)"));
+  }
+
+  return Block(tlv::SignatureValue, std::move(signature));
 }
 
 tlv::SignatureTypeValue
diff --git a/tests/unit/security/v2/key-chain.t.cpp b/tests/unit/security/v2/key-chain.t.cpp
index ee19346..7f6abb0 100644
--- a/tests/unit/security/v2/key-chain.t.cpp
+++ b/tests/unit/security/v2/key-chain.t.cpp
@@ -210,6 +210,20 @@
   BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
 }
 
+BOOST_FIXTURE_TEST_CASE(SigningWithCorruptedPibTpm, IdentityManagementFixture)
+{
+  Identity id = m_keyChain.createIdentity("/test");
+
+  Data data("/foobar");
+  BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id)));
+
+  // now, "corrupting TPM"
+  const_cast<Tpm&>(m_keyChain.getTpm()).deleteKey(id.getDefaultKey().getName());
+
+  BOOST_CHECK_NO_THROW(id.getDefaultKey());
+  BOOST_CHECK_THROW(m_keyChain.sign(data, signingByIdentity(id)), KeyChain::InvalidSigningInfoError);
+}
+
 BOOST_FIXTURE_TEST_CASE(Management, IdentityManagementFixture)
 {
   Name identityName("/test/id");