security: Split KeyChain into signing (KeyChain) and verification (Verifier) interfaces
This split removes the need for IdentityManager.
Also in this commit: Make verifySignature methods a set of static methods of Verifier.
Change-Id: Iea1c4353857a21417b2dcd1f91ba7013995d1459
diff --git a/src/security/identity/identity-manager.cpp b/src/security/identity/identity-manager.cpp
deleted file mode 100644
index 44f0d0b..0000000
--- a/src/security/identity/identity-manager.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#include <ndn-cpp/ndn-cpp-config.h>
-#if NDN_CPP_HAVE_TIME_H
-#include <time.h>
-#endif
-#if NDN_CPP_HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <ctime>
-#include <fstream>
-#include <math.h>
-#include <ndn-cpp/key-locator.hpp>
-
-#include "../../util/logging.hpp"
-#include "../../c/util/time.h"
-#include <ndn-cpp/security/identity/identity-manager.hpp>
-#include <ndn-cpp/security/certificate/identity-certificate.hpp>
-#include <ndn-cpp/security/signature/signature-sha256-with-rsa.hpp>
-
-INIT_LOGGER("ndn.security.IdentityManager")
-
-using namespace std;
-
-namespace ndn {
-
-IdentityManager::IdentityManager(const ptr_lib::shared_ptr<IdentityStorage> &identityStorage /* = DefaultIdentityStorage */,
- const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */)
- : identityStorage_(identityStorage)
- , privateKeyStorage_(privateKeyStorage)
-{
-}
-
-Name
-IdentityManager::createIdentity(const Name& identityName)
-{
- if (!info().doesIdentityExist(identityName)) {
- _LOG_DEBUG("Create Identity");
- info().addIdentity(identityName);
-
- _LOG_DEBUG("Create Default RSA key pair");
- Name keyName = generateRSAKeyPairAsDefault(identityName, true);
-
- _LOG_DEBUG("Create self-signed certificate");
- ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
-
- _LOG_DEBUG("Add self-signed certificate as default");
-
- addCertificateAsDefault(*selfCert);
-
- return keyName;
- }
- else
- throw Error("Identity has already been created!");
-}
-
-Name
-IdentityManager::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
-{
- _LOG_DEBUG("Get new key ID");
- Name keyName = info().getNewKeyName(identityName, isKsk);
-
- _LOG_DEBUG("Generate key pair in private storage");
- tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
-
- _LOG_DEBUG("Create a key record in public storage");
- ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
- info().addKey(keyName, keyType, *pubKey);
-
- return keyName;
-}
-
-Name
-IdentityManager::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
-{
- Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
- return keyName;
-}
-
-Name
-IdentityManager::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
-{
- defaultCertificate_.reset();
-
- Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
- info().setDefaultKeyNameForIdentity(keyName, identityName);
-
- return keyName;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
- const Name& signerCertificateName,
- const MillisecondsSince1970& notBefore,
- const MillisecondsSince1970& notAfter)
-{
- Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
-
- ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
- if (!pubKey)
- throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
-
- ptr_lib::shared_ptr<IdentityCertificate> certificate =
- createIdentityCertificate(certificatePrefix,
- *pubKey,
- signerCertificateName,
- notBefore, notAfter);
-
- info().addCertificate(*certificate);
-
- return certificate;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
- const PublicKey& publicKey,
- const Name& signerCertificateName,
- const MillisecondsSince1970& notBefore,
- const MillisecondsSince1970& notAfter)
-{
- ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
- Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
-
- Name certificateName = certificatePrefix;
- certificateName.append("ID-CERT").appendVersion();
-
- certificate->setName(certificateName);
- certificate->setNotBefore(notBefore);
- certificate->setNotAfter(notAfter);
- certificate->setPublicKeyInfo(publicKey);
- certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
- certificate->encode();
-
- signByCertificate(*certificate, signerCertificateName);
-
- return certificate;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::selfSign(const Name& keyName)
-{
- ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
-
- Name certificateName = keyName.getSubName(0, keyName.size() - 1);
- certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").appendVersion();
-
- ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
- if (!pubKey)
- throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
-
- certificate->setName(certificateName);
- certificate->setNotBefore(ndn_getNowMilliseconds());
- certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
- certificate->setPublicKeyInfo(*pubKey);
- certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
- certificate->encode();
-
- selfSign(*certificate);
- return certificate;
-}
-
-void
-IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
-{
- info().addCertificate(certificate);
-
- setDefaultCertificateForKey(certificate);
-}
-
-void
-IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
-{
- info().addCertificate(certificate);
-
- Name keyName = certificate.getPublicKeyName();
-
- setDefaultKeyForIdentity(keyName);
-
- setDefaultCertificateForKey(certificate);
-}
-
-void
-IdentityManager::setDefaultCertificateForKey(const IdentityCertificate& certificate)
-{
- defaultCertificate_.reset();
-
- Name keyName = certificate.getPublicKeyName();
-
- if(!info().doesKeyExist(keyName))
- throw Error("No corresponding Key record for certificate!");
-
- info().setDefaultCertificateNameForKey(keyName, certificate.getName());
-}
-
-void
-IdentityManager::sign(Data &data)
-{
- if (!defaultCertificate_)
- {
- defaultCertificate_ = info().getCertificate(
- info().getDefaultCertificateNameForIdentity(
- info().getDefaultIdentity()));
-
- if(!defaultCertificate_)
- throw Error("Default IdentityCertificate cannot be determined");
- }
-
- signByCertificate(data, *defaultCertificate_);
-}
-
-Signature
-IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
-{
- ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
- if (!cert)
- throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- signature.setValue
- (tpm().sign(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
- return signature;
-}
-
-void
-IdentityManager::signByCertificate(Data &data, const Name &certificateName)
-{
- ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
- if (!cert)
- throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
- data.setSignature(signature);
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- tpm().sign(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-void
-IdentityManager::signByCertificate(Data& data, const IdentityCertificate& certificate)
-{
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(certificate.getName().getPrefix(-1));
- data.setSignature(signature);
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- tpm().sign(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-void
-IdentityManager::selfSign (IdentityCertificate& cert)
-{
- SignatureSha256WithRsa signature;
- signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
- cert.setSignature(signature);
-
- // For temporary usage, we support RSA + SHA256 only, but will support more.
- tpm().sign(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-Name
-IdentityManager::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
-{
- Name result;
-
- string keyString("KEY");
- int i = 0;
- for(; i < certificatePrefix.size(); i++) {
- if (certificatePrefix.get(i).toEscapedString() == keyString)
- break;
- }
-
- if (i >= certificatePrefix.size())
- throw Error("Identity Certificate Prefix does not have a KEY component");
-
- result.append(certificatePrefix.getSubName(0, i));
- result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
-
- return result;
-}
-
-}
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index e61013f..8d3f412 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -7,10 +7,10 @@
*/
#include <ndn-cpp/security/key-chain.hpp>
-
-#include <ndn-cpp/security/policy/policy-manager.hpp>
-
#include <ndn-cpp/security/identity/basic-identity-storage.hpp>
+#include <ndn-cpp/security/signature/signature-sha256-with-rsa.hpp>
+#include "../util/logging.hpp"
+#include "../c/util/time.h"
using namespace std;
@@ -20,22 +20,17 @@
using namespace ndn::func_lib::placeholders;
#endif
+INIT_LOGGER("ndn.KeyChain");
+
namespace ndn {
const ptr_lib::shared_ptr<IdentityStorage> KeyChain::DefaultIdentityStorage = ptr_lib::shared_ptr<IdentityStorage>();
const ptr_lib::shared_ptr<PrivateKeyStorage> KeyChain::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
-const ptr_lib::shared_ptr<PolicyManager> KeyChain::DefaultPolicyManager = ptr_lib::shared_ptr<PolicyManager>();
-const ptr_lib::shared_ptr<EncryptionManager> KeyChain::DefaultEncryptionManager = ptr_lib::shared_ptr<EncryptionManager>();
KeyChain::KeyChain(const ptr_lib::shared_ptr<IdentityStorage> &publicInfoStorage /* = DefaultIdentityStorage */,
- const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */,
- const ptr_lib::shared_ptr<PolicyManager> &policyManager /* = DefaultPolicyManager */,
- const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager /* = DefaultEncryptionManager */)
+ const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */)
: publicInfoStorage_(publicInfoStorage)
, privateKeyStorage_(privateKeyStorage)
- , policyManager_(policyManager)
- , encryptionManager_(encryptionManager)
- // , maxSteps_(100)
{
if (publicInfoStorage_ == DefaultIdentityStorage)
{
@@ -50,124 +45,280 @@
// m_privateStorage = Ptr<SimpleKeyStore>::Create();
#endif
}
-
- identityManager_ = ptr_lib::make_shared<IdentityManager>(publicInfoStorage_, privateKeyStorage_);
-
- if (policyManager_ == DefaultPolicyManager)
- {
- // #ifdef USE_SIMPLE_POLICY_MANAGER
- // Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
- // Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
- // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
- // ">", "\\1\\2", "\\1", true));
- // Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
- // "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
- // "==", "\\1", "\\1\\2", true));
- // Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
- // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
- // ">", "\\1", "\\1", true));
- // policyManager->addVerificationPolicyRule(rule1);
- // policyManager->addVerificationPolicyRule(rule2);
- // policyManager->addVerificationPolicyRule(rule3);
-
- // policyManager->addSigningPolicyRule(rule3);
-
- // m_policyManager = policyManager;
- //
- // #else
- // policyManager_ = new NoVerifyPolicyManager();
- // #endif
- }
-
- if (encryptionManager_ == DefaultEncryptionManager)
- {
- }
-
-// #ifdef USE_BASIC_ENCRYPTION_MANAGER
-// encryptionManager_ = new BasicEncryptionManager(m_identityManager->getPrivateStorage(), "/tmp/encryption.db");
-// #endif
}
+Name
+KeyChain::createIdentity(const Name& identityName)
+{
+ if (!info().doesIdentityExist(identityName)) {
+ _LOG_DEBUG("Create Identity");
+ info().addIdentity(identityName);
+
+ _LOG_DEBUG("Create Default RSA key pair");
+ Name keyName = generateRSAKeyPairAsDefault(identityName, true);
+
+ _LOG_DEBUG("Create self-signed certificate");
+ ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName);
+
+ _LOG_DEBUG("Add self-signed certificate as default");
+ addCertificateAsDefault(*selfCert);
+
+ return keyName;
+ }
+ else
+ throw Error("Identity has already been created!");
+}
+
+Name
+KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
+{
+ _LOG_DEBUG("Get new key ID");
+ Name keyName = info().getNewKeyName(identityName, isKsk);
+
+ _LOG_DEBUG("Generate key pair in private storage");
+ tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
+
+ _LOG_DEBUG("Create a key record in public storage");
+ ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
+ info().addKey(keyName, keyType, *pubKey);
+
+ return keyName;
+}
+
+Name
+KeyChain::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
+{
+ Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+ return keyName;
+}
+
+Name
+KeyChain::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
+{
+ defaultCertificate_.reset();
+
+ Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+ info().setDefaultKeyNameForIdentity(keyName, identityName);
+
+ return keyName;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::createIdentityCertificate(const Name& certificatePrefix,
+ const Name& signerCertificateName,
+ const MillisecondsSince1970& notBefore,
+ const MillisecondsSince1970& notAfter)
+{
+ Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+
+ ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
+ if (!pubKey)
+ throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+
+ ptr_lib::shared_ptr<IdentityCertificate> certificate =
+ createIdentityCertificate(certificatePrefix,
+ *pubKey,
+ signerCertificateName,
+ notBefore, notAfter);
+
+ info().addCertificate(*certificate);
+
+ return certificate;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::createIdentityCertificate(const Name& certificatePrefix,
+ const PublicKey& publicKey,
+ const Name& signerCertificateName,
+ const MillisecondsSince1970& notBefore,
+ const MillisecondsSince1970& notAfter)
+{
+ ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
+ Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+
+ Name certificateName = certificatePrefix;
+ certificateName.append("ID-CERT").appendVersion();
+
+ certificate->setName(certificateName);
+ certificate->setNotBefore(notBefore);
+ certificate->setNotAfter(notAfter);
+ certificate->setPublicKeyInfo(publicKey);
+ certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+ certificate->encode();
+
+ sign(*certificate, signerCertificateName);
+
+ return certificate;
+}
+
+Name
+KeyChain::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
+{
+ Name result;
+
+ string keyString("KEY");
+ int i = 0;
+ for(; i < certificatePrefix.size(); i++) {
+ if (certificatePrefix.get(i).toEscapedString() == keyString)
+ break;
+ }
+
+ if (i >= certificatePrefix.size())
+ throw Error("Identity Certificate Prefix does not have a KEY component");
+
+ result.append(certificatePrefix.getSubName(0, i));
+ result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
+
+ return result;
+}
+
+void
+KeyChain::setDefaultCertificateForKey(const IdentityCertificate& certificate)
+{
+ defaultCertificate_.reset();
+
+ Name keyName = certificate.getPublicKeyName();
+
+ if(!info().doesKeyExist(keyName))
+ throw Error("No corresponding Key record for certificate!");
+
+ info().setDefaultCertificateNameForKey(keyName, certificate.getName());
+}
+
+void
+KeyChain::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
+{
+ info().addCertificate(certificate);
+
+ Name keyName = certificate.getPublicKeyName();
+
+ setDefaultKeyForIdentity(keyName);
+
+ setDefaultCertificateForKey(certificate);
+}
+
+void
+KeyChain::addCertificateAsDefault(const IdentityCertificate& certificate)
+{
+ info().addCertificate(certificate);
+
+ setDefaultCertificateForKey(certificate);
+}
+
+void
+KeyChain::sign(Data &data)
+{
+ if (!defaultCertificate_)
+ {
+ defaultCertificate_ = info().getCertificate(
+ info().getDefaultCertificateNameForIdentity(
+ info().getDefaultIdentity()));
+
+ if(!defaultCertificate_)
+ throw Error("Default IdentityCertificate cannot be determined");
+ }
+
+ sign(data, *defaultCertificate_);
+}
+
+void
+KeyChain::sign(Data &data, const Name &certificateName)
+{
+ ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+ if (!cert)
+ throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+ data.setSignature(signature);
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ tpm().sign(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+}
+
+void
+KeyChain::sign(Data& data, const IdentityCertificate& certificate)
+{
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificate.getName().getPrefix(-1));
+ data.setSignature(signature);
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ tpm().sign(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+}
+
+Signature
+KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+{
+ ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+ if (!cert)
+ throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ signature.setValue
+ (tpm().sign(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+ return signature;
+}
void
KeyChain::signByIdentity(Data& data, const Name& identityName)
{
- Name signingCertificateName;
-
- if (identityName.getComponentCount() == 0) {
- Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
- if (inferredIdentity.getComponentCount() == 0)
- signingCertificateName = identityManager_->getDefaultCertificateName();
- else
- signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);
- }
- else
- signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
+ Name signingCertificateName = info().getDefaultCertificateNameForIdentity(identityName);
if (signingCertificateName.getComponentCount() == 0)
throw Error("No qualified certificate name found!");
- if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
- throw Error("Signing Cert name does not comply with signing policy");
-
- identities().signByCertificate(data, signingCertificateName);
+ sign(data, signingCertificateName);
}
Signature
KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
{
- Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
+ Name signingCertificateName = info().getDefaultCertificateNameForIdentity(identityName);
if (signingCertificateName.size() == 0)
throw Error("No qualified certificate name found!");
- return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
+ return sign(buffer, bufferLength, signingCertificateName);
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::selfSign(const Name& keyName)
+{
+ ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
+
+ Name certificateName = keyName.getPrefix(-1);
+ certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+
+ ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
+ if (!pubKey)
+ throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+
+ certificate->setName(certificateName);
+ certificate->setNotBefore(ndn_getNowMilliseconds());
+ certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
+ certificate->setPublicKeyInfo(*pubKey);
+ certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+ certificate->encode();
+
+ selfSign(*certificate);
+ return certificate;
}
void
-KeyChain::verifyData
- (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
+KeyChain::selfSign (IdentityCertificate& cert)
{
- if (policies().requireVerify(*data)) {
- ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
- (data, stepCount, onVerified, onVerifyFailed);
- if (nextStep)
- {
- if (!face_)
- throw Error("Face should be set prior to verifyData method to call");
-
- face_->expressInterest
- (*nextStep->interest_,
- bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
- bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
- }
- }
- else if (policies().skipVerifyAndTrust(*data))
- onVerified(data);
- else
- onVerifyFailed(data);
-}
+ SignatureSha256WithRsa signature;
+ signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
+ cert.setSignature(signature);
-void
-KeyChain::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
-{
- // Try to verify the certificate (data) according to the parameters in nextStep.
- verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
-}
-
-void
-KeyChain::onCertificateInterestTimeout
- (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
- ptr_lib::shared_ptr<ValidationRequest> nextStep)
-{
- if (retry > 0)
- // Issue the same expressInterest as in verifyData except decrement retry.
- face_->expressInterest
- (*interest,
- bind(&KeyChain::onCertificateData, this, _1, _2, nextStep),
- bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
- else
- onVerifyFailed(data);
+ // For temporary usage, we support RSA + SHA256 only, but will support more.
+ tpm().sign(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
}
}
diff --git a/src/security/verifier.cpp b/src/security/verifier.cpp
new file mode 100644
index 0000000..67a1f33
--- /dev/null
+++ b/src/security/verifier.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreorder"
+#pragma clang diagnostic ignored "-Wtautological-compare"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunused-function"
+#elif __GNUC__
+#pragma GCC diagnostic ignored "-Wreorder"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#include <ndn-cpp/security/verifier.hpp>
+
+#include <ndn-cpp/security/policy/policy-manager.hpp>
+
+#include <cryptopp/rsa.h>
+
+#include "../util/logging.hpp"
+
+using namespace std;
+using namespace ndn::func_lib;
+#if NDN_CPP_HAVE_CXX11
+// In the std library, the placeholders are in a different namespace than boost.
+using namespace ndn::func_lib::placeholders;
+#endif
+
+INIT_LOGGER("ndn.Verifier");
+
+namespace ndn {
+const ptr_lib::shared_ptr<PolicyManager> Verifier::DefaultPolicyManager = ptr_lib::shared_ptr<PolicyManager>();
+
+Verifier::Verifier(const ptr_lib::shared_ptr<PolicyManager> &policyManager /* = DefaultPolicyManager */)
+ : policyManager_(policyManager)
+{
+ if (policyManager_ == DefaultPolicyManager)
+ {
+ // #ifdef USE_SIMPLE_POLICY_MANAGER
+ // Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
+ // Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
+ // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
+ // ">", "\\1\\2", "\\1", true));
+ // Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
+ // "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
+ // "==", "\\1", "\\1\\2", true));
+ // Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$",
+ // "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
+ // ">", "\\1", "\\1", true));
+ // policyManager->addVerificationPolicyRule(rule1);
+ // policyManager->addVerificationPolicyRule(rule2);
+ // policyManager->addVerificationPolicyRule(rule3);
+
+ // policyManager->addSigningPolicyRule(rule3);
+
+ // m_policyManager = policyManager;
+ //
+ // #else
+ // policyManager_ = new NoVerifyPolicyManager();
+ // #endif
+ }
+}
+
+void
+Verifier::verifyData
+ (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
+{
+ if (policies().requireVerify(*data)) {
+ ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
+ (data, stepCount, onVerified, onVerifyFailed);
+ if (static_cast<bool>(nextStep))
+ {
+ if (!face_)
+ throw Error("Face should be set prior to verifyData method to call");
+
+ face_->expressInterest
+ (*nextStep->interest_,
+ bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
+ bind(&Verifier::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
+ }
+ }
+ else if (policies().skipVerifyAndTrust(*data))
+ onVerified(data);
+ else
+ onVerifyFailed(data);
+}
+
+void
+Verifier::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
+{
+ // Try to verify the certificate (data) according to the parameters in nextStep.
+ verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
+}
+
+void
+Verifier::onCertificateInterestTimeout
+ (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data,
+ ptr_lib::shared_ptr<ValidationRequest> nextStep)
+{
+ if (retry > 0)
+ // Issue the same expressInterest as in verifyData except decrement retry.
+ face_->expressInterest
+ (*interest,
+ bind(&Verifier::onCertificateData, this, _1, _2, nextStep),
+ bind(&Verifier::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
+ else
+ onVerifyFailed(data);
+}
+
+bool
+Verifier::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
+{
+ using namespace CryptoPP;
+
+ bool result = false;
+
+ RSA::PublicKey publicKey;
+ ByteQueue queue;
+
+ queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
+ publicKey.Load(queue);
+
+ RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+ result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
+ sig.getValue().value(), sig.getValue().value_size());
+
+ _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
+
+ return result;
+}
+
+}