security+tools: Allow user to explicitly specify the cert name prefix before 'KEY' component in ndnsec-certgen
Change-Id: I71e137e89b5ab0cd5db7001b39ff76c22a448bd2
Refs: #1659
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index fe85472..240bab6 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -35,6 +35,9 @@
namespace ndn {
+// Use a GUID as a magic number of KeyChain::DEFAULT_PREFIX identifier
+const Name KeyChain::DEFAULT_PREFIX("/723821fd-f534-44b3-80d9-44bf5f58bbbb");
+
KeyChain::KeyChain()
: m_pib(0)
, m_tpm(0)
@@ -120,7 +123,32 @@
const Name& signingIdentity,
const time::system_clock::TimePoint& notBefore,
const time::system_clock::TimePoint& notAfter,
- const std::vector<CertificateSubjectDescription>& subjectDescription)
+ const std::vector<CertificateSubjectDescription>& subjectDescription,
+ const Name& certPrefix)
+{
+ shared_ptr<PublicKey> publicKey;
+ try
+ {
+ publicKey = m_pib->getPublicKey(keyName);
+ }
+ catch (SecPublicInfo::Error& e)
+ {
+ return shared_ptr<IdentityCertificate>();
+ }
+
+ return prepareUnsignedIdentityCertificate(keyName, *publicKey, signingIdentity,
+ notBefore, notAfter,
+ subjectDescription, certPrefix);
+}
+
+shared_ptr<IdentityCertificate>
+KeyChain::prepareUnsignedIdentityCertificate(const Name& keyName,
+ const PublicKey& publicKey,
+ const Name& signingIdentity,
+ const time::system_clock::TimePoint& notBefore,
+ const time::system_clock::TimePoint& notAfter,
+ const std::vector<CertificateSubjectDescription>& subjectDescription,
+ const Name& certPrefix)
{
if (keyName.size() < 1)
return shared_ptr<IdentityCertificate>();
@@ -132,37 +160,40 @@
shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
Name certName;
- if (signingIdentity.isPrefixOf(keyName))
+ if (certPrefix == KeyChain::DEFAULT_PREFIX)
{
- certName.append(signingIdentity)
- .append("KEY")
- .append(keyName.getSubName(signingIdentity.size()))
- .append("ID-CERT")
- .appendVersion();
+ // No certificate prefix hint, infer the prefix
+ if (signingIdentity.isPrefixOf(keyName))
+ certName.append(signingIdentity)
+ .append("KEY")
+ .append(keyName.getSubName(signingIdentity.size()))
+ .append("ID-CERT")
+ .appendVersion();
+ else
+ certName.append(keyName.getPrefix(-1))
+ .append("KEY")
+ .append(keyName.get(-1))
+ .append("ID-CERT")
+ .appendVersion();
}
else
{
- certName.append(keyName.getPrefix(-1))
- .append("KEY")
- .append(keyName.get(-1))
- .append("ID-CERT")
- .appendVersion();
+ // cert prefix hint is supplied, determine the cert name.
+ if (certPrefix.isPrefixOf(keyName) && certPrefix != keyName)
+ certName.append(certPrefix)
+ .append("KEY")
+ .append(keyName.getSubName(certPrefix.size()))
+ .append("ID-CERT")
+ .appendVersion();
+ else
+ return shared_ptr<IdentityCertificate>();
}
+
certificate->setName(certName);
certificate->setNotBefore(notBefore);
certificate->setNotAfter(notAfter);
-
- shared_ptr<PublicKey> publicKey;
- try
- {
- publicKey = m_pib->getPublicKey(keyName);
- }
- catch (SecPublicInfo::Error& e)
- {
- return shared_ptr<IdentityCertificate>();
- }
- certificate->setPublicKeyInfo(*publicKey);
+ certificate->setPublicKeyInfo(publicKey);
if (subjectDescription.empty())
{
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 7c95e14..00a2e6b 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -57,6 +57,8 @@
}
};
+ static const Name DEFAULT_PREFIX;
+
KeyChain();
template<class KeyChainTraits>
@@ -116,6 +118,11 @@
* @param notBefore Refer to IdentityCertificate.
* @param notAfter Refer to IdentityCertificate.
* @param subjectDescription Refer to IdentityCertificate.
+ * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
+ * certificate name according to the relation between the signingIdentity and
+ * the subject identity. If signingIdentity is a prefix of the subject identity,
+ * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
+ * after subject identity (i.e., before `ksk-....`).
* @return IdentityCertificate.
*/
shared_ptr<IdentityCertificate>
@@ -123,7 +130,33 @@
const Name& signingIdentity,
const time::system_clock::TimePoint& notBefore,
const time::system_clock::TimePoint& notAfter,
- const std::vector<CertificateSubjectDescription>& subjectDescription);
+ const std::vector<CertificateSubjectDescription>& subjectDescription,
+ const Name& certPrefix = DEFAULT_PREFIX);
+
+ /**
+ * @brief prepare an unsigned identity certificate
+ *
+ * @param keyName Key name, e.g., `/<identity_name>/ksk-123456`.
+ * @param publicKey Public key to sign.
+ * @param signingIdentity The signing identity.
+ * @param notBefore Refer to IdentityCertificate.
+ * @param notAfter Refer to IdentityCertificate.
+ * @param subjectDescription Refer to IdentityCertificate.
+ * @param certPrefix Prefix before `KEY` component. By default, KeyChain will infer the
+ * certificate name according to the relation between the signingIdentity and
+ * the subject identity. If signingIdentity is a prefix of the subject identity,
+ * `KEY` will be inserted after the signingIdentity, otherwise `KEY` is inserted
+ * after subject identity (i.e., before `ksk-....`).
+ * @return IdentityCertificate.
+ */
+ shared_ptr<IdentityCertificate>
+ prepareUnsignedIdentityCertificate(const Name& keyName,
+ const PublicKey& publicKey,
+ const Name& signingIdentity,
+ const time::system_clock::TimePoint& notBefore,
+ const time::system_clock::TimePoint& notAfter,
+ const std::vector<CertificateSubjectDescription>& subjectDescription,
+ const Name& certPrefix = DEFAULT_PREFIX);
/**
* @brief Sign packet with default identity